Kuma/tests/marketing/consent.test.ts
2026-10-02 17:31:08 +02:00

86 lines
2.8 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
vi.mock("next/cache", () => ({ revalidateTag: vi.fn() }));
vi.mock("@/src/lib/prisma", () => {
const prisma = {
marketingConsent: { findUnique: vi.fn(), upsert: vi.fn() },
marketingAuditLog: { createMany: vi.fn() },
$transaction: vi.fn(),
};
prisma.$transaction.mockImplementation((fn: (tx: unknown) => unknown) => fn(prisma));
return { prisma };
});
import { prisma } from "@/src/lib/prisma";
import { setMarketingConsent } from "@/src/modules/marketing/lib/consent";
import { CONSENT_TEXT_VERSION } from "@/src/modules/marketing/lib/consent-text";
beforeEach(() => {
vi.clearAllMocks();
});
describe("setMarketingConsent", () => {
it("speichert die Einwilligung mit Wortlaut-Version und protokolliert sie", async () => {
vi.mocked(prisma.marketingConsent.findUnique).mockResolvedValue(null);
const changed = await setMarketingConsent({
userId: "user-1",
businessId: "biz-1",
granted: true,
source: "course_booking",
});
expect(changed).toBe(true);
const upsert = vi.mocked(prisma.marketingConsent.upsert).mock.calls[0][0];
expect(upsert.create).toMatchObject({
granted: true,
textVersion: CONSENT_TEXT_VERSION,
source: "course_booking",
});
expect(upsert.create?.grantedAt).toBeInstanceOf(Date);
const [entry] = vi.mocked(prisma.marketingAuditLog.createMany).mock.calls[0][0]!.data as {
action: string;
actorType: string;
userId: string;
}[];
expect(entry).toMatchObject({
action: "consent.granted",
actorType: "customer",
userId: "user-1",
});
});
it("protokolliert den Widerruf", async () => {
vi.mocked(prisma.marketingConsent.findUnique).mockResolvedValue({ granted: true } as never);
await setMarketingConsent({
userId: "user-1",
businessId: "biz-1",
granted: false,
source: "unsubscribe_link",
});
const upsert = vi.mocked(prisma.marketingConsent.upsert).mock.calls[0][0];
expect(upsert.update).toMatchObject({ granted: false });
expect(upsert.update?.revokedAt).toBeInstanceOf(Date);
const [entry] = vi.mocked(prisma.marketingAuditLog.createMany).mock.calls[0][0]!.data as {
action: string;
}[];
expect(entry.action).toBe("consent.revoked");
});
it("ändert nichts, wenn der Stand schon stimmt", async () => {
vi.mocked(prisma.marketingConsent.findUnique).mockResolvedValue({ granted: true } as never);
const changed = await setMarketingConsent({
userId: "user-1",
businessId: "biz-1",
granted: true,
source: "profile",
});
expect(changed).toBe(false);
expect(prisma.marketingConsent.upsert).not.toHaveBeenCalled();
expect(prisma.marketingAuditLog.createMany).not.toHaveBeenCalled();
});
});