import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest" import type { PrismaClient } from "@/generated/prisma/client" import { createTestPerson, createTestTeam } from "../helpers/factories" import { resetIntegrationTestDatabase, startIntegrationTestDatabase, stopIntegrationTestDatabase, } from "../helpers/test-db" let prisma: PrismaClient let createTeamUseCase: typeof import("@/use-cases/team.use-cases").createTeamUseCase let updateTeamUseCase: typeof import("@/use-cases/team.use-cases").updateTeamUseCase let deleteTeamUseCase: typeof import("@/use-cases/team.use-cases").deleteTeamUseCase let listTeamsUseCase: typeof import("@/use-cases/team.use-cases").listTeamsUseCase let TeamService: typeof import("@/services/team.service").TeamService beforeAll(async () => { await startIntegrationTestDatabase() const prismaModule = await import("@/lib/prisma") const teamUseCases = await import("@/use-cases/team.use-cases") const teamService = await import("@/services/team.service") prisma = prismaModule.prisma createTeamUseCase = teamUseCases.createTeamUseCase updateTeamUseCase = teamUseCases.updateTeamUseCase deleteTeamUseCase = teamUseCases.deleteTeamUseCase listTeamsUseCase = teamUseCases.listTeamsUseCase TeamService = teamService.TeamService }) beforeEach(async () => { await resetIntegrationTestDatabase(prisma) }) afterAll(async () => { await prisma?.$disconnect() await stopIntegrationTestDatabase() }) describe("team use-cases", () => { it("creates a team and rejects duplicate names", async () => { expect(await createTeamUseCase({ name: "Engineering" })).toEqual({ success: true, }) expect( await prisma.team.findFirst({ where: { name: "Engineering" } }), ).toMatchObject({ name: "Engineering" }) expect(await createTeamUseCase({ name: "Engineering" })).toEqual({ success: false, errors: { name: ["Team already exists"] }, }) expect(await prisma.team.count()).toBe(1) }) it("rejects duplicate names case-insensitively and trims whitespace", async () => { await createTestTeam(prisma, { name: "Engineering" }) expect(await createTeamUseCase({ name: "engineering" })).toEqual({ success: false, errors: { name: ["Team already exists"] }, }) expect(await createTeamUseCase({ name: " ENGINEERING " })).toEqual({ success: false, errors: { name: ["Team already exists"] }, }) expect(await prisma.team.count()).toBe(1) }) it("trims the name before saving", async () => { await createTeamUseCase({ name: " Engineering " }) const team = await prisma.team.findFirst({ where: { name: "Engineering" }, }) expect(team).not.toBeNull() expect(team?.name).toBe("Engineering") }) it("updates a team and rejects unchanged or duplicate names", async () => { const team = await createTestTeam(prisma, { name: "Peripherals" }) const other = await createTestTeam(prisma, { name: "Networking" }) expect( await updateTeamUseCase({ id: team.id, name: "Accessories" }), ).toEqual({ success: true }) expect( await prisma.team.findUniqueOrThrow({ where: { id: team.id } }), ).toMatchObject({ name: "Accessories" }) expect( await updateTeamUseCase({ id: team.id, name: "Accessories" }), ).toEqual({ success: false, errors: { name: ["Team name is the same"] }, }) expect( await updateTeamUseCase({ id: team.id, name: other.name }), ).toEqual({ success: false, errors: { name: ["Team already exists"] }, }) expect( await prisma.team.findUniqueOrThrow({ where: { id: team.id } }), ).toMatchObject({ name: "Accessories" }) }) it("returns not found when updating a missing team", async () => { expect( await updateTeamUseCase({ id: "00000000-0000-0000-0000-000000000000", name: "Ghost", }), ).toEqual({ success: false, errors: { id: ["Team not found"] }, }) }) it("hard deletes a team", async () => { const team = await createTestTeam(prisma, { name: "Legacy" }) expect(await deleteTeamUseCase(team.id)).toEqual({ success: true }) expect(await prisma.team.findUnique({ where: { id: team.id } })).toBeNull() }) it("returns not found when deleting a missing team", async () => { expect( await deleteTeamUseCase("00000000-0000-0000-0000-000000000000"), ).toEqual({ success: false, errors: { id: ["Team not found"] }, }) }) it("nulls linked Person.teamId when a team is deleted", async () => { const team = await createTestTeam(prisma, { name: "Assigned" }) const person = await createTestPerson(prisma) await prisma.person.update({ where: { id: person.id }, data: { teamId: team.id }, }) expect(await deleteTeamUseCase(team.id)).toEqual({ success: true }) const updatedPerson = await prisma.person.findUnique({ where: { id: person.id }, }) expect(updatedPerson).not.toBeNull() expect(updatedPerson?.teamId).toBeNull() }) it("lists all teams ordered by name", async () => { await createTestTeam(prisma, { name: "Beta" }) await createTestTeam(prisma, { name: "Alpha" }) await createTestTeam(prisma, { name: "Gamma" }) const teams = await listTeamsUseCase() expect(teams).toHaveLength(3) expect(teams.map((team) => team.name)).toEqual(["Alpha", "Beta", "Gamma"]) }) })