ledgerone_backend/test/notifications.service.spec.ts

104 lines
3.3 KiB
TypeScript

/// <reference types="jest" />
import { NotificationsService } from "../src/notifications/notifications.service";
import { createPrismaMock } from "./utils/mock-prisma";
describe("NotificationsService", () => {
const userId = "user-1";
let prisma: ReturnType<typeof createPrismaMock>;
let emailService: { sendNotificationEmail: jest.Mock };
let service: NotificationsService;
beforeEach(() => {
prisma = createPrismaMock();
emailService = { sendNotificationEmail: jest.fn().mockResolvedValue(undefined) };
service = new NotificationsService(prisma as never, emailService as never);
prisma.notification.create.mockResolvedValue({
id: "notification-1",
userId,
type: "test",
severity: "info",
title: "Test",
body: "Body",
channels: ["in_app"],
});
prisma.notification.update.mockImplementation(({ data }) => Promise.resolve({ id: "notification-1", ...data }));
prisma.notificationPreference.findUnique.mockResolvedValue({
userId,
emailEnabled: true,
pushEnabled: false,
minSeverity: "info",
});
prisma.user.findUnique.mockResolvedValue({ email: "user@example.com" });
});
it("creates an in-app notification and sends SMTP email when enabled", async () => {
const result = await service.notifyUser(userId, {
type: "test",
title: "Test",
body: "Body",
});
expect(prisma.notification.create).toHaveBeenCalledWith(expect.objectContaining({
data: expect.objectContaining({ userId, channels: ["in_app"] }),
}));
expect(emailService.sendNotificationEmail).toHaveBeenCalledWith(
"user@example.com",
"Test",
"Body",
expect.stringContaining("/notifications"),
"info",
);
expect(result.channels).toEqual(["in_app", "email"]);
});
it("does not send email below the configured severity threshold", async () => {
prisma.notificationPreference.findUnique.mockResolvedValue({
userId,
emailEnabled: true,
pushEnabled: false,
minSeverity: "critical",
});
await service.notifyUser(userId, {
type: "test",
severity: "warning",
title: "Warning",
body: "Body",
});
expect(emailService.sendNotificationEmail).not.toHaveBeenCalled();
expect(prisma.notification.update).toHaveBeenCalledWith(expect.objectContaining({
data: { channels: ["in_app"] },
}));
});
it("stores a push subscription and enables push preferences", async () => {
prisma.pushSubscription.upsert.mockResolvedValue({ id: "push-1", userId });
prisma.notificationPreference.upsert.mockResolvedValue({
userId,
emailEnabled: true,
pushEnabled: true,
minSeverity: "info",
});
await service.savePushSubscription(
userId,
{
endpoint: "https://push.example.test/sub",
keys: { p256dh: "p256dh", auth: "auth" },
},
"jest",
);
expect(prisma.pushSubscription.upsert).toHaveBeenCalledWith(expect.objectContaining({
create: expect.objectContaining({ userId, userAgent: "jest" }),
update: expect.objectContaining({ userId, revokedAt: null }),
}));
expect(prisma.notificationPreference.upsert).toHaveBeenCalledWith(expect.objectContaining({
update: { pushEnabled: true },
}));
});
});