mirror of
https://github.com/Since-3/Kuma.git
synced 2026-10-12 20:51:18 +00:00
109 lines
3.5 KiB
TypeScript
109 lines
3.5 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
|
|
vi.mock("@/src/lib/prisma", () => ({
|
|
prisma: {
|
|
notification: {
|
|
findMany: vi.fn(),
|
|
count: vi.fn(),
|
|
updateMany: vi.fn(),
|
|
},
|
|
},
|
|
}));
|
|
|
|
vi.mock("@/src/lib/auth/getUser", () => ({
|
|
requireAuthWithData: vi.fn(),
|
|
isManager: (u: { role: string }) => u?.role === "manager",
|
|
isEmployee: (u: { role: string }) => u?.role === "employee",
|
|
}));
|
|
|
|
import { prisma } from "@/src/lib/prisma";
|
|
import { requireAuthWithData } from "@/src/lib/auth/getUser";
|
|
import {
|
|
getNotifications,
|
|
markNotificationRead,
|
|
markAllNotificationsRead,
|
|
} from "@/src/modules/notifications/actions/notification-actions";
|
|
|
|
const findMany = vi.mocked(prisma.notification.findMany);
|
|
const count = vi.mocked(prisma.notification.count);
|
|
const updateMany = vi.mocked(prisma.notification.updateMany);
|
|
const requireAuth = vi.mocked(requireAuthWithData);
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe("getNotifications", () => {
|
|
it("liefert leeres Ergebnis für die User-Rolle", async () => {
|
|
requireAuth.mockResolvedValueOnce({ id: "u1", role: "user" } as never);
|
|
const result = await getNotifications();
|
|
expect(result).toEqual({ items: [], unreadCount: 0 });
|
|
expect(findMany).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("liefert leeres Ergebnis wenn keine Session besteht", async () => {
|
|
requireAuth.mockRejectedValueOnce(new Error("redirect"));
|
|
const result = await getNotifications();
|
|
expect(result).toEqual({ items: [], unreadCount: 0 });
|
|
});
|
|
|
|
it("scoped die Abfrage auf die eigene recipientId und mappt Datumsfelder", async () => {
|
|
requireAuth.mockResolvedValueOnce({ id: "mgr-1", role: "manager" } as never);
|
|
const now = new Date("2026-08-28T10:00:00Z");
|
|
findMany.mockResolvedValueOnce([
|
|
{
|
|
id: "n1",
|
|
type: "booking.created",
|
|
title: "T",
|
|
body: "B",
|
|
linkUrl: "/x",
|
|
readAt: null,
|
|
createdAt: now,
|
|
},
|
|
] as never);
|
|
count.mockResolvedValueOnce(1);
|
|
|
|
const result = await getNotifications();
|
|
|
|
expect(findMany.mock.calls[0][0]?.where).toEqual({ recipientId: "mgr-1" });
|
|
expect(count.mock.calls[0][0]?.where).toEqual({ recipientId: "mgr-1", readAt: null });
|
|
expect(result.unreadCount).toBe(1);
|
|
expect(result.items[0].createdAt).toBe(now.toISOString());
|
|
expect(result.items[0].readAt).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("markNotificationRead", () => {
|
|
it("nimmt die recipientId in die WHERE-Bedingung auf (Ownership)", async () => {
|
|
requireAuth.mockResolvedValueOnce({ id: "mgr-1", role: "manager" } as never);
|
|
updateMany.mockResolvedValueOnce({ count: 1 } as never);
|
|
|
|
await markNotificationRead("n1");
|
|
|
|
expect(updateMany).toHaveBeenCalledWith({
|
|
where: { id: "n1", recipientId: "mgr-1", readAt: null },
|
|
data: { readAt: expect.any(Date) },
|
|
});
|
|
});
|
|
|
|
it("verweigert die User-Rolle", async () => {
|
|
requireAuth.mockResolvedValueOnce({ id: "u1", role: "user" } as never);
|
|
const result = await markNotificationRead("n1");
|
|
expect(result).toEqual({ success: false });
|
|
expect(updateMany).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("markAllNotificationsRead", () => {
|
|
it("markiert nur ungelesene der eigenen recipientId", async () => {
|
|
requireAuth.mockResolvedValueOnce({ id: "emp-9", role: "employee" } as never);
|
|
updateMany.mockResolvedValueOnce({ count: 3 } as never);
|
|
|
|
await markAllNotificationsRead();
|
|
|
|
expect(updateMany).toHaveBeenCalledWith({
|
|
where: { recipientId: "emp-9", readAt: null },
|
|
data: { readAt: expect.any(Date) },
|
|
});
|
|
});
|
|
});
|