mirror of
https://github.com/Since-3/Kuma.git
synced 2026-10-12 20:51:18 +00:00
133 lines
4.6 KiB
TypeScript
133 lines
4.6 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||
|
||
vi.mock("@/src/lib/prisma", () => ({
|
||
prisma: {
|
||
room: { findUnique: vi.fn(), update: vi.fn() },
|
||
courseBooking: { findMany: vi.fn() },
|
||
course: { findMany: vi.fn(), updateMany: vi.fn() },
|
||
},
|
||
}));
|
||
|
||
vi.mock("@/src/lib/auth/getUser", () => ({
|
||
getUserData: vi.fn(),
|
||
isManager: (u: { role: string }) => u?.role === "manager",
|
||
isEmployee: (u: { role: string }) => u?.role === "employee",
|
||
getEffectiveManagerId: (u: { role: string; id: string }) => u.id,
|
||
}));
|
||
|
||
vi.mock("next/cache", () => ({ revalidatePath: vi.fn() }));
|
||
vi.mock("@/src/modules/courses/lib/public-courses-cache", () => ({
|
||
refreshPublicCourses: vi.fn(),
|
||
}));
|
||
|
||
import { prisma } from "@/src/lib/prisma";
|
||
import { getUserData } from "@/src/lib/auth/getUser";
|
||
import { updateRoom } from "@/src/modules/rooms/actions/room-actions";
|
||
import { refreshPublicCourses } from "@/src/modules/courses/lib/public-courses-cache";
|
||
import type { FloorPlan, FloorPlanItem } from "@/src/modules/rooms/lib/floor-plan";
|
||
|
||
const reformer = (id: string, label: string, x: number): FloorPlanItem => ({
|
||
id,
|
||
type: "reformer",
|
||
x,
|
||
y: 1.5,
|
||
rotation: 0,
|
||
label,
|
||
});
|
||
|
||
const plan = (items: FloorPlanItem[]): FloorPlan => ({ width: 8, depth: 6, items });
|
||
|
||
const threeReformers = plan([
|
||
reformer("r1", "1", 1),
|
||
reformer("r2", "2", 2),
|
||
reformer("r3", "3", 3),
|
||
]);
|
||
|
||
beforeEach(() => {
|
||
vi.clearAllMocks();
|
||
vi.mocked(getUserData).mockResolvedValue({ id: "mgr-1", role: "manager" } as never);
|
||
vi.mocked(prisma.room.findUnique).mockResolvedValue({
|
||
id: "room-1",
|
||
createdBy: "mgr-1",
|
||
floorPlan: threeReformers,
|
||
} as never);
|
||
vi.mocked(prisma.courseBooking.findMany).mockResolvedValue([]);
|
||
vi.mocked(prisma.course.findMany).mockResolvedValue([]);
|
||
});
|
||
|
||
describe("updateRoom – gebuchte Plätze", () => {
|
||
it("verhindert das Entfernen eines Geräts mit kommender Buchung", async () => {
|
||
vi.mocked(prisma.courseBooking.findMany).mockResolvedValue([{ spotIds: ["r3"] }] as never);
|
||
|
||
const result = await updateRoom("room-1", {
|
||
name: "Reformer-Raum",
|
||
floorPlan: plan([reformer("r1", "1", 1), reformer("r2", "2", 2)]),
|
||
});
|
||
|
||
expect(result).toMatchObject({ success: false });
|
||
expect(result.error).toContain("Reformer 3");
|
||
expect(prisma.room.update).not.toHaveBeenCalled();
|
||
});
|
||
|
||
it("verhindert das Umnummerieren eines gebuchten Geräts", async () => {
|
||
vi.mocked(prisma.courseBooking.findMany).mockResolvedValue([{ spotIds: ["r1"] }] as never);
|
||
|
||
const result = await updateRoom("room-1", {
|
||
name: "Reformer-Raum",
|
||
floorPlan: plan([reformer("r1", "9", 1), reformer("r2", "2", 2), reformer("r3", "3", 3)]),
|
||
});
|
||
|
||
expect(result.success).toBe(false);
|
||
expect(prisma.room.update).not.toHaveBeenCalled();
|
||
});
|
||
|
||
it("erlaubt das Verschieben gebuchter Geräte, ohne Buchungen zu prüfen", async () => {
|
||
const moved = plan([reformer("r1", "1", 5), reformer("r2", "2", 6), reformer("r3", "3", 7)]);
|
||
|
||
const result = await updateRoom("room-1", { name: "Reformer-Raum", floorPlan: moved });
|
||
|
||
expect(result.success).toBe(true);
|
||
expect(prisma.courseBooking.findMany).not.toHaveBeenCalled();
|
||
expect(vi.mocked(prisma.room.update).mock.calls[0][0].data.floorPlan).toEqual(moved);
|
||
});
|
||
});
|
||
|
||
describe("updateRoom – Teilnehmerzahl", () => {
|
||
it("senkt die Teilnehmerzahl kommender Platzwahl-Kurse auf die neue Platzanzahl", async () => {
|
||
vi.mocked(prisma.course.findMany).mockResolvedValue([
|
||
{ id: "c1", businessId: "biz-1", isStandingOrder: false },
|
||
{ id: "c2", businessId: "biz-1", isStandingOrder: false },
|
||
] as never);
|
||
|
||
const result = await updateRoom("room-1", {
|
||
name: "Reformer-Raum",
|
||
floorPlan: plan([reformer("r1", "1", 1), reformer("r2", "2", 2)]),
|
||
});
|
||
|
||
expect(result.success).toBe(true);
|
||
expect(result.message).toContain("2 kommende Kurse");
|
||
expect(vi.mocked(prisma.course.findMany).mock.calls[0][0]!.where).toMatchObject({
|
||
room: "room-1",
|
||
spotBooking: true,
|
||
maxParticipants: { gt: 2 },
|
||
});
|
||
expect(prisma.course.updateMany).toHaveBeenCalledWith({
|
||
where: { id: { in: ["c1", "c2"] } },
|
||
data: { maxParticipants: 2 },
|
||
});
|
||
expect(refreshPublicCourses).toHaveBeenCalledWith("biz-1", "biz-1");
|
||
});
|
||
|
||
it("lässt die Teilnehmerzahl in Ruhe, wenn der Grundriss ganz entfernt wird", async () => {
|
||
vi.mocked(prisma.room.findUnique).mockResolvedValue({
|
||
id: "room-1",
|
||
createdBy: "mgr-1",
|
||
floorPlan: null,
|
||
} as never);
|
||
|
||
const result = await updateRoom("room-1", { name: "Matten-Raum", floorPlan: null });
|
||
|
||
expect(result.success).toBe(true);
|
||
expect(prisma.course.findMany).not.toHaveBeenCalled();
|
||
});
|
||
});
|