import { describe, it, expect, vi, beforeEach } from "vitest"; import type { RouterContextProvider } from "react-router"; import { action } from "~/routes/api/draft.start"; const ctx = {} as unknown as RouterContextProvider; vi.mock("~/database/context"); vi.mock("~/server/socket", () => ({ getSocketIO: vi.fn(), scheduleDraftRoomClosure: vi.fn(), })); vi.mock("~/lib/auth.server", () => ({ auth: { api: { getSession: vi.fn() } }, })); vi.mock("~/models/commissioner", () => ({ isCommissioner: vi.fn(), })); vi.mock("~/models/user", () => ({ findUserById: vi.fn().mockResolvedValue(null), getUserDisplayName: vi.fn().mockReturnValue(null), })); vi.mock("~/services/draft-autostart", () => ({ startDraft: vi.fn().mockResolvedValue({ success: true }), })); // ── Fixtures ───────────────────────────────────────────────────────────────── const SEASON_ID = "season-1"; const COMMISSIONER_ID = "commissioner-user-1"; function makeSeason(overrides: Record = {}) { return { id: SEASON_ID, leagueId: "league-1", status: "pre_draft", draftInitialTime: 120, draftIncrementTime: 30, draftTimerMode: "chess_clock", ...overrides, }; } function makeRequest() { const formData = new FormData(); formData.append("seasonId", SEASON_ID); return new Request("http://localhost/api/draft/start", { method: "POST", body: formData, }); } // ── Tests ───────────────────────────────────────────────────────────────────── describe("draft.start action", () => { let mockDb: any; let mockSocketIO: any; beforeEach(async () => { vi.clearAllMocks(); const { auth } = await import("~/lib/auth.server"); vi.mocked(auth.api.getSession).mockResolvedValue({ user: { id: COMMISSIONER_ID } } as any); const { isCommissioner } = await import("~/models/commissioner"); vi.mocked(isCommissioner).mockResolvedValue(true); mockSocketIO = { to: vi.fn().mockReturnThis(), emit: vi.fn() }; const socketModule = await import("~/server/socket"); vi.mocked(socketModule.getSocketIO).mockReturnValue(mockSocketIO); mockDb = { query: { seasons: { findFirst: vi.fn() }, }, }; const { database } = await import("~/database/context"); vi.mocked(database).mockReturnValue(mockDb); const { startDraft } = await import("~/services/draft-autostart"); vi.mocked(startDraft).mockResolvedValue({ success: true }); }); it("returns 401 when not authenticated", async () => { const { auth } = await import("~/lib/auth.server"); vi.mocked(auth.api.getSession).mockResolvedValue(null); const res = await action({ request: makeRequest(), params: {}, context: ctx }); expect(res.status).toBe(401); }); it("returns 404 when season not found", async () => { mockDb.query.seasons.findFirst.mockResolvedValue(null); const res = await action({ request: makeRequest(), params: {}, context: ctx }); expect(res.status).toBe(404); }); it("returns 403 when user is not a commissioner", async () => { mockDb.query.seasons.findFirst.mockResolvedValue(makeSeason()); const { isCommissioner } = await import("~/models/commissioner"); vi.mocked(isCommissioner).mockResolvedValue(false); const res = await action({ request: makeRequest(), params: {}, context: ctx }); expect(res.status).toBe(403); }); it("calls startDraft and returns 200 on success", async () => { mockDb.query.seasons.findFirst.mockResolvedValue(makeSeason()); const res = await action({ request: makeRequest(), params: {}, context: ctx }); const { startDraft } = await import("~/services/draft-autostart"); expect(vi.mocked(startDraft)).toHaveBeenCalledWith( expect.objectContaining({ seasonId: SEASON_ID }) ); expect(res.status).toBe(200); }); it("returns 400 when startDraft reports draft already started", async () => { mockDb.query.seasons.findFirst.mockResolvedValue(makeSeason()); const { startDraft } = await import("~/services/draft-autostart"); vi.mocked(startDraft).mockResolvedValue({ success: false, error: "Draft already started or completed" }); const res = await action({ request: makeRequest(), params: {}, context: ctx }); expect(res.status).toBe(400); }); it("returns 400 when startDraft reports no draft slots", async () => { mockDb.query.seasons.findFirst.mockResolvedValue(makeSeason()); const { startDraft } = await import("~/services/draft-autostart"); vi.mocked(startDraft).mockResolvedValue({ success: false, error: "No draft slots found for this season" }); const res = await action({ request: makeRequest(), params: {}, context: ctx }); expect(res.status).toBe(400); }); });