2026-05-14 16:45:02 -07:00
|
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
|
import type { RouterContextProvider } from "react-router";
|
2026-06-09 22:13:49 -07:00
|
|
|
import { auth } from "~/lib/auth.server";
|
|
|
|
|
import { isUserAdmin } from "~/models/user";
|
|
|
|
|
import { findParticipantById, updateParticipant } from "~/models/season-participant";
|
|
|
|
|
import { upsertRegularSeasonStandings } from "~/models/regular-season-standings";
|
|
|
|
|
import { deletePendingStandingsMapping } from "~/models/pending-standings-mappings";
|
|
|
|
|
import { action } from "../admin.sports-seasons.$id";
|
2026-05-14 16:45:02 -07:00
|
|
|
|
|
|
|
|
const ctx = {} as unknown as RouterContextProvider;
|
|
|
|
|
|
|
|
|
|
vi.mock("~/lib/auth.server", () => ({
|
|
|
|
|
auth: { api: { getSession: vi.fn() } },
|
|
|
|
|
}));
|
|
|
|
|
vi.mock("~/models/user", () => ({
|
|
|
|
|
isUserAdmin: vi.fn(),
|
|
|
|
|
}));
|
|
|
|
|
vi.mock("~/models/sports-season", () => ({
|
|
|
|
|
updateSportsSeason: vi.fn(),
|
|
|
|
|
findSportsSeasonById: vi.fn(),
|
|
|
|
|
deleteSportsSeason: vi.fn(),
|
|
|
|
|
}));
|
|
|
|
|
vi.mock("~/models/pending-standings-mappings", () => ({
|
|
|
|
|
getPendingStandingsMappings: vi.fn(),
|
|
|
|
|
deletePendingStandingsMapping: vi.fn(),
|
|
|
|
|
}));
|
|
|
|
|
vi.mock("~/models/season-participant", () => ({
|
|
|
|
|
findParticipantsBySportsSeasonId: vi.fn(),
|
|
|
|
|
findParticipantById: vi.fn(),
|
|
|
|
|
updateParticipant: vi.fn(),
|
|
|
|
|
}));
|
|
|
|
|
vi.mock("~/models/regular-season-standings", () => ({
|
|
|
|
|
getLastSyncedAt: vi.fn(),
|
|
|
|
|
upsertRegularSeasonStandings: vi.fn(),
|
|
|
|
|
}));
|
|
|
|
|
vi.mock("~/models/scoring-calculator", () => ({
|
|
|
|
|
processSeasonStandings: vi.fn(),
|
|
|
|
|
recalculateStandings: vi.fn(),
|
|
|
|
|
}));
|
|
|
|
|
vi.mock("~/models/standings", () => ({
|
|
|
|
|
createDailySnapshot: vi.fn(),
|
|
|
|
|
}));
|
|
|
|
|
vi.mock("~/database/context", () => ({
|
|
|
|
|
database: vi.fn(),
|
|
|
|
|
}));
|
|
|
|
|
vi.mock("~/services/standings-sync/index", () => ({
|
|
|
|
|
syncStandings: vi.fn(),
|
|
|
|
|
}));
|
|
|
|
|
vi.mock("~/services/simulations/registry", () => ({
|
|
|
|
|
getSimulatorInfo: vi.fn(),
|
|
|
|
|
SIMULATOR_TYPES: [],
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
function makeResolveRequest() {
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
formData.append("intent", "resolve-mapping");
|
|
|
|
|
formData.append("externalTeamId", "ext-42");
|
|
|
|
|
formData.append("participantId", "participant-7");
|
|
|
|
|
formData.append(
|
|
|
|
|
"standingData",
|
|
|
|
|
JSON.stringify({
|
|
|
|
|
teamName: "Golden State",
|
|
|
|
|
wins: 48,
|
|
|
|
|
losses: 20,
|
|
|
|
|
winPct: 0.706,
|
|
|
|
|
gamesPlayed: 68,
|
|
|
|
|
leagueRank: 3,
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return new Request("http://localhost/admin/sports-seasons/season-1", {
|
|
|
|
|
method: "POST",
|
|
|
|
|
body: formData,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
describe("admin.sports-seasons.$id action", () => {
|
2026-06-09 22:13:49 -07:00
|
|
|
beforeEach(() => {
|
2026-05-14 16:45:02 -07:00
|
|
|
vi.clearAllMocks();
|
|
|
|
|
vi.mocked(auth.api.getSession).mockResolvedValue({ user: { id: "admin-1" } } as any);
|
|
|
|
|
vi.mocked(isUserAdmin).mockResolvedValue(true);
|
|
|
|
|
vi.mocked(findParticipantById).mockResolvedValue({
|
|
|
|
|
id: "participant-7",
|
|
|
|
|
name: "Golden State Warriors",
|
|
|
|
|
sportsSeasonId: "season-1",
|
|
|
|
|
} as any);
|
|
|
|
|
vi.mocked(updateParticipant).mockResolvedValue({ id: "participant-7" } as any);
|
|
|
|
|
vi.mocked(upsertRegularSeasonStandings).mockResolvedValue(undefined as never);
|
|
|
|
|
vi.mocked(deletePendingStandingsMapping).mockResolvedValue(undefined as never);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("returns the resolved API team and participant name after a mapping is confirmed", async () => {
|
|
|
|
|
const result = await action({
|
|
|
|
|
request: makeResolveRequest(),
|
|
|
|
|
params: { id: "season-1" },
|
|
|
|
|
context: ctx,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(result).toMatchObject({
|
|
|
|
|
success: true,
|
|
|
|
|
intent: "resolve-mapping",
|
|
|
|
|
resolvedTeam: "Golden State",
|
|
|
|
|
resolvedParticipant: "Golden State Warriors",
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("rejects a participant from a different sports season", async () => {
|
|
|
|
|
vi.mocked(findParticipantById).mockResolvedValue({
|
|
|
|
|
id: "participant-7",
|
|
|
|
|
name: "Golden State Warriors",
|
|
|
|
|
sportsSeasonId: "other-season",
|
|
|
|
|
} as any);
|
|
|
|
|
|
|
|
|
|
const result = await action({
|
|
|
|
|
request: makeResolveRequest(),
|
|
|
|
|
params: { id: "season-1" },
|
|
|
|
|
context: ctx,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(result).toMatchObject({
|
|
|
|
|
error: "Selected participant does not belong to this sports season.",
|
|
|
|
|
});
|
|
|
|
|
expect(vi.mocked(updateParticipant)).not.toHaveBeenCalled();
|
|
|
|
|
});
|
|
|
|
|
});
|