mirror of
https://github.com/Since-3/Kuma.git
synced 2026-10-12 20:41:16 +00:00
118 lines
4 KiB
TypeScript
118 lines
4 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/generated/prisma/client";
|
|
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();
|
|
});
|
|
|
|
it("versucht es einmal neu, wenn eine parallele Anfrage die Zeile zuerst anlegt", async () => {
|
|
// Beide Anfragen lesen "keine Zeile"; unsere scheitert beim Anlegen am Unique-Key.
|
|
// Im zweiten Durchlauf ist die Zeile der anderen Anfrage da.
|
|
vi.mocked(prisma.marketingConsent.findUnique)
|
|
.mockResolvedValueOnce(null)
|
|
.mockResolvedValueOnce({ granted: true } as never);
|
|
vi.mocked(prisma.marketingConsent.upsert).mockRejectedValueOnce(
|
|
new Prisma.PrismaClientKnownRequestError("Unique constraint failed", {
|
|
code: "P2002",
|
|
clientVersion: "test",
|
|
})
|
|
);
|
|
|
|
const changed = await setMarketingConsent({
|
|
userId: "user-1",
|
|
businessId: "biz-1",
|
|
granted: true,
|
|
source: "profile",
|
|
});
|
|
|
|
expect(changed).toBe(false);
|
|
expect(prisma.marketingConsent.findUnique).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it("gibt andere Fehler weiter", async () => {
|
|
vi.mocked(prisma.marketingConsent.findUnique).mockRejectedValue(new Error("DB weg"));
|
|
await expect(
|
|
setMarketingConsent({ userId: "u", businessId: "b", granted: true, source: "profile" })
|
|
).rejects.toThrow("DB weg");
|
|
});
|
|
});
|