test: cover notification delivery identity

This commit is contained in:
Marc-André Bombeck committed 2026-08-06 03:49:49 +02:00
1 parent 3bb9349171
commit 913a41b37d
1 file changed
+117
@@ -0,0 +1,117 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("@/lib/db", () => ({
prisma: {
notificationChannel: {
findMany: vi.fn(),
update: vi.fn(),
upsert: vi.fn(),
},
user: { findUnique: vi.fn() },
auditLog: { create: vi.fn() },
},
}));
vi.mock("@/lib/auth/audit", () => ({
auditLog: vi.fn(async () => undefined),
}));
vi.mock("@/lib/crypto", () => ({
decrypt: (value: string) => value,
encrypt: (value: string) => value,
}));
vi.mock("@/lib/logging/context", () => ({
getEvent: () => ({
addWarning: vi.fn(),
addMeta: vi.fn(),
}),
}));
const sendViaWebPushMock = vi.fn();
vi.mock("@/lib/notifications/senders/apns", () => ({
sendViaApns: vi.fn(),
}));
vi.mock("@/lib/notifications/senders/email", () => ({
sendViaEmail: vi.fn(),
}));
vi.mock("@/lib/notifications/senders/ntfy", () => ({
sendViaNtfy: vi.fn(),
}));
vi.mock("@/lib/notifications/senders/telegram", () => ({
sendViaTelegram: vi.fn(),
}));
vi.mock("@/lib/notifications/senders/web-push", () => ({
sendViaWebPush: (...args: unknown[]) => sendViaWebPushMock(...args),
}));
vi.mock("@/lib/notifications/senders/webhook", () => ({
sendViaWebhook: vi.fn(),
}));
vi.mock("@/lib/notifications/senders/push-attempt-record", () => ({
recordPushAttempt: vi.fn(),
}));
import { prisma } from "@/lib/db";
import { dispatchNotification } from "@/lib/notifications/dispatcher";
const recordUserId = "managed-record";
const recipientUserId = "guardian-recipient";
beforeEach(() => {
vi.resetAllMocks();
vi.mocked(prisma.user.findUnique).mockImplementation(async (args) => {
const id = (args as { where: { id: string } }).where.id;
return id === recordUserId
? ({ managedProfileAt: new Date() } as never)
: (null as never);
});
vi.mocked(prisma.notificationChannel.findMany).mockResolvedValue([
{
id: "recipient-channel",
userId: recipientUserId,
type: "WEB_PUSH",
config: "{}",
nextRetryAt: null,
preferences: [],
},
] as never);
vi.mocked(prisma.notificationChannel.update).mockResolvedValue({
consecutiveFailures: 0,
} as never);
sendViaWebPushMock.mockResolvedValue({ ok: true });
});
describe("notification delivery identity", () => {
it("principal resolution uses the recipient channel for a managed record", async () => {
const outcome = await dispatchNotification({
eventType: "MEDICATION_REMINDER",
userId: recordUserId,
recordUserId,
recipientUserId,
title: "Record content",
message: "Record schedule",
});
expect(outcome).toEqual({
dispatched: true,
channelsAttempted: 1,
channelsSucceeded: 1,
});
expect(prisma.notificationChannel.findMany).toHaveBeenCalledWith(
expect.objectContaining({
where: { userId: recipientUserId, enabled: true },
}),
);
expect(sendViaWebPushMock).toHaveBeenCalledWith(
recipientUserId,
expect.objectContaining({
userId: recordUserId,
recordUserId,
recipientUserId,
title: "Record content",
message: "Record schedule",
}),
);
});
});