mirror of
https://github.com/Since-3/Kuma.git
synced 2026-10-12 20:41:16 +00:00
125 lines
4.1 KiB
TypeScript
125 lines
4.1 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
|
|
vi.mock("@/src/lib/prisma", () => ({
|
|
prisma: {
|
|
business: { findUnique: vi.fn() },
|
|
notification: { create: vi.fn() },
|
|
},
|
|
}));
|
|
|
|
import { prisma } from "@/src/lib/prisma";
|
|
import {
|
|
createNotification,
|
|
isNotificationEnabled,
|
|
notifyBusinessManager,
|
|
} from "@/src/modules/notifications/lib/create-notification";
|
|
|
|
const businessFindUnique = vi.mocked(prisma.business.findUnique);
|
|
const notificationCreate = vi.mocked(prisma.notification.create);
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe("createNotification", () => {
|
|
it("schreibt einen Datensatz und gibt true zurück", async () => {
|
|
notificationCreate.mockResolvedValueOnce({} as never);
|
|
const ok = await createNotification({
|
|
recipientId: "mgr-1",
|
|
type: "booking.created",
|
|
title: "Neue Buchung",
|
|
body: "…",
|
|
linkUrl: "/courses/edit/c1",
|
|
});
|
|
expect(ok).toBe(true);
|
|
expect(notificationCreate).toHaveBeenCalledWith({
|
|
data: {
|
|
recipientId: "mgr-1",
|
|
type: "booking.created",
|
|
title: "Neue Buchung",
|
|
body: "…",
|
|
linkUrl: "/courses/edit/c1",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("wirft nie, sondern gibt bei DB-Fehler false zurück", async () => {
|
|
notificationCreate.mockRejectedValueOnce(new Error("db down"));
|
|
const ok = await createNotification({
|
|
recipientId: "mgr-1",
|
|
type: "booking.created",
|
|
title: "x",
|
|
body: "y",
|
|
});
|
|
expect(ok).toBe(false);
|
|
});
|
|
|
|
it("setzt linkUrl auf null wenn nicht angegeben", async () => {
|
|
notificationCreate.mockResolvedValueOnce({} as never);
|
|
await createNotification({ recipientId: "m", type: "course.full", title: "a", body: "b" });
|
|
expect(notificationCreate.mock.calls[0][0].data.linkUrl).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("isNotificationEnabled", () => {
|
|
it("gibt den Registry-Default zurück wenn kein Business gefunden wird", async () => {
|
|
businessFindUnique.mockResolvedValueOnce(null);
|
|
expect(await isNotificationEnabled("nope", "booking.created")).toBe(true);
|
|
});
|
|
|
|
it("respektiert ein gespeichertes Opt-out", async () => {
|
|
businessFindUnique.mockResolvedValueOnce({
|
|
notificationSettings: { "booking.created": false },
|
|
} as never);
|
|
expect(await isNotificationEnabled("b1", "booking.created")).toBe(false);
|
|
});
|
|
|
|
it("fällt bei DB-Fehler auf den Default zurück (Zustellung im Zweifel)", async () => {
|
|
businessFindUnique.mockRejectedValueOnce(new Error("boom"));
|
|
expect(await isNotificationEnabled("b1", "waitlist.spot")).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("notifyBusinessManager", () => {
|
|
it("no-op bei fehlender businessId", async () => {
|
|
await notifyBusinessManager(null, { type: "booking.created", title: "a", body: "b" });
|
|
await notifyBusinessManager(undefined, { type: "booking.created", title: "a", body: "b" });
|
|
expect(businessFindUnique).not.toHaveBeenCalled();
|
|
expect(notificationCreate).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("erstellt eine Notification für den Manager des Business", async () => {
|
|
businessFindUnique.mockResolvedValueOnce({
|
|
managerId: "mgr-42",
|
|
notificationSettings: null,
|
|
} as never);
|
|
notificationCreate.mockResolvedValueOnce({} as never);
|
|
|
|
await notifyBusinessManager("b1", {
|
|
type: "booking.created",
|
|
title: "Neue Buchung",
|
|
body: "…",
|
|
linkUrl: "/x",
|
|
});
|
|
|
|
expect(notificationCreate).toHaveBeenCalledTimes(1);
|
|
expect(notificationCreate.mock.calls[0][0].data.recipientId).toBe("mgr-42");
|
|
});
|
|
|
|
it("stellt nichts zu, wenn der Typ für das Business abgeschaltet ist", async () => {
|
|
businessFindUnique.mockResolvedValueOnce({
|
|
managerId: "mgr-42",
|
|
notificationSettings: { "booking.created": false },
|
|
} as never);
|
|
|
|
await notifyBusinessManager("b1", { type: "booking.created", title: "a", body: "b" });
|
|
expect(notificationCreate).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("wirft nie, auch wenn der Business-Lookup fehlschlägt", async () => {
|
|
businessFindUnique.mockRejectedValueOnce(new Error("boom"));
|
|
await expect(
|
|
notifyBusinessManager("b1", { type: "course.full", title: "a", body: "b" })
|
|
).resolves.toBeUndefined();
|
|
});
|
|
});
|