/// import { NotificationsService } from "../src/notifications/notifications.service"; import { createPrismaMock } from "./utils/mock-prisma"; describe("NotificationsService", () => { const userId = "user-1"; let prisma: ReturnType; 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 }, })); }); });