import { describe, it, expect, vi, beforeEach } from "vitest"; vi.mock("~/models/season-participant", () => ({ findParticipantsBySportsSeasonId: vi.fn(), findParticipantByName: vi.fn(), createParticipant: vi.fn(), deleteParticipant: vi.fn(), updateParticipant: vi.fn(), })); vi.mock("~/models/sports-season", () => ({ findSportsSeasonById: vi.fn(), })); vi.mock("~/lib/logger", () => ({ logger: { error: vi.fn() }, })); import { findParticipantByName, updateParticipant, } from "~/models/season-participant"; import { action } from "~/routes/admin.sports-seasons.$id.participants"; const mockParams = { id: "season-1" }; function makeRequest(data: Record) { const formData = new FormData(); for (const [key, value] of Object.entries(data)) { if (value !== null) formData.set(key, value); } return new Request("http://localhost/admin/sports-seasons/season-1/participants", { method: "POST", body: formData, }); } describe("admin participants action — update-participant intent", () => { beforeEach(() => { vi.clearAllMocks(); }); it("updates both name and externalId when valid", async () => { (findParticipantByName as ReturnType).mockResolvedValue(null); (updateParticipant as ReturnType).mockResolvedValue({}); const result = await action({ request: makeRequest({ intent: "update-participant", participantId: "p-1", newName: "US Southeast", newExternalId: "US", }), params: mockParams, context: {}, } as Parameters[0]); expect(updateParticipant).toHaveBeenCalledWith("p-1", { name: "US Southeast", externalId: "US", }); expect(result).toMatchObject({ success: true, intent: "update-participant" }); }); it("saves null when newExternalId is blank", async () => { (findParticipantByName as ReturnType).mockResolvedValue(null); (updateParticipant as ReturnType).mockResolvedValue({}); await action({ request: makeRequest({ intent: "update-participant", participantId: "p-1", newName: "Some Team", newExternalId: " ", }), params: mockParams, context: {}, } as Parameters[0]); expect(updateParticipant).toHaveBeenCalledWith("p-1", { name: "Some Team", externalId: null, }); }); it("returns error when name is empty", async () => { const result = await action({ request: makeRequest({ intent: "update-participant", participantId: "p-1", newName: " ", newExternalId: "US", }), params: mockParams, context: {}, } as Parameters[0]); expect(updateParticipant).not.toHaveBeenCalled(); expect(result).toMatchObject({ error: "Name is required", intent: "update-participant" }); }); it("returns error when name conflicts with another participant", async () => { (findParticipantByName as ReturnType).mockResolvedValue({ id: "p-2", name: "US Midwest" }); const result = await action({ request: makeRequest({ intent: "update-participant", participantId: "p-1", newName: "US Midwest", newExternalId: "US", }), params: mockParams, context: {}, } as Parameters[0]); expect(updateParticipant).not.toHaveBeenCalled(); expect(result).toMatchObject({ error: expect.stringContaining("already exists"), intent: "update-participant" }); }); it("allows saving same name back to the same participant (no false conflict)", async () => { (findParticipantByName as ReturnType).mockResolvedValue({ id: "p-1", name: "US Midwest" }); (updateParticipant as ReturnType).mockResolvedValue({}); const result = await action({ request: makeRequest({ intent: "update-participant", participantId: "p-1", newName: "US Midwest", newExternalId: "US", }), params: mockParams, context: {}, } as Parameters[0]); expect(updateParticipant).toHaveBeenCalled(); expect(result).toMatchObject({ success: true }); }); });