Files
no-whatever/src/app/api/room/[id]/join/route.test.ts
T

106 lines
3.1 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
import { createRequest, createRouteContext, parseJsonResponse } from "@/__tests__/helpers/api-test-utils";
import { TEST_ROOM_DATA } from "@/__tests__/helpers/fixtures";
vi.mock("@/lib/prisma", () => ({ prisma: {} }));
vi.mock("@/lib/roomRepository", () => ({
atomicUpdateRoom: vi.fn(),
}));
vi.mock("@/lib/roomEvents", () => ({
notify: vi.fn(),
}));
import { POST } from "./route";
import { atomicUpdateRoom } from "@/lib/roomRepository";
const mockAtomicUpdate = vi.mocked(atomicUpdateRoom);
beforeEach(() => {
vi.clearAllMocks();
});
describe("POST /api/room/[id]/join", () => {
it("joins a room successfully", async () => {
mockAtomicUpdate.mockImplementation(async (_id, updater) => {
const data = { ...TEST_ROOM_DATA, users: ["user-1"] };
return updater(data);
});
const req = createRequest("/api/room/ROOM01/join", {
method: "POST",
body: { userId: "user-2" },
});
const ctx = createRouteContext({ id: "ROOM01" });
const res = await POST(req, ctx);
const { status, data } = await parseJsonResponse(res);
expect(status).toBe(200);
expect(data.roomId).toBe("ROOM01");
expect(data.userCount).toBe(2);
});
it("returns 403 when kicked", async () => {
mockAtomicUpdate.mockImplementation(async (_id, updater) => {
const data = { ...TEST_ROOM_DATA, kickedUsers: ["user-2"] };
return updater(data);
});
const req = createRequest("/api/room/ROOM01/join", {
method: "POST",
body: { userId: "user-2" },
});
const ctx = createRouteContext({ id: "ROOM01" });
const res = await POST(req, ctx);
expect(res.status).toBe(403);
});
it("returns 403 when room is locked", async () => {
mockAtomicUpdate.mockImplementation(async (_id, updater) => {
const data = { ...TEST_ROOM_DATA, locked: true, users: ["user-1"] };
return updater(data);
});
const req = createRequest("/api/room/ROOM01/join", {
method: "POST",
body: { userId: "user-2" },
});
const ctx = createRouteContext({ id: "ROOM01" });
const res = await POST(req, ctx);
expect(res.status).toBe(403);
});
it("returns 404 when room not found", async () => {
mockAtomicUpdate.mockResolvedValue(null);
const req = createRequest("/api/room/ABC123/join", {
method: "POST",
body: { userId: "user-1" },
});
const ctx = createRouteContext({ id: "ABC123" });
const res = await POST(req, ctx);
expect(res.status).toBe(404);
});
it("returns 401 when no userId", async () => {
const req = createRequest("/api/room/ROOM01/join", {
method: "POST",
body: {},
});
const ctx = createRouteContext({ id: "ROOM01" });
const res = await POST(req, ctx);
expect(res.status).toBe(401);
});
it("returns 400 when room id format is invalid", async () => {
const req = createRequest("/api/room/1234/join", {
method: "POST",
body: { userId: "user-1" },
});
const ctx = createRouteContext({ id: "1234" });
const res = await POST(req, ctx);
expect(res.status).toBe(400);
});
});