import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest" import type { PrismaClient } from "@/generated/prisma/client" import { createTestRecipient } from "../helpers/factories" import { resetIntegrationTestDatabase, startIntegrationTestDatabase, stopIntegrationTestDatabase, } from "../helpers/test-db" let prisma: PrismaClient let createRecipientUseCase: typeof import("@/use-cases/recipient.use-cases").createRecipientUseCase let updateRecipientUseCase: typeof import("@/use-cases/recipient.use-cases").updateRecipientUseCase beforeAll(async () => { await startIntegrationTestDatabase() const prismaModule = await import("@/lib/prisma") const recipientUseCases = await import("@/use-cases/recipient.use-cases") prisma = prismaModule.prisma createRecipientUseCase = recipientUseCases.createRecipientUseCase updateRecipientUseCase = recipientUseCases.updateRecipientUseCase }) beforeEach(async () => { await resetIntegrationTestDatabase(prisma) }) afterAll(async () => { await prisma?.$disconnect() await stopIntegrationTestDatabase() }) describe("recipient use-cases", () => { it("creates a recipient and normalizes empty optional contact fields to null", async () => { await expect( createRecipientUseCase({ username: "recipient-one", firstName: "Recipient", lastName: "One", department: "IT", email: "", phone: "", }), ).resolves.toEqual({ success: true }) await expect( prisma.recipient.findUniqueOrThrow({ where: { username: "recipient-one" }, }), ).resolves.toMatchObject({ username: "recipient-one", firstName: "Recipient", lastName: "One", department: "IT", email: null, phone: null, }) }) it("rejects duplicate usernames and duplicate emails on create", async () => { await createTestRecipient(prisma, { username: "existing-recipient", email: "existing-recipient@example.test", }) await expect( createRecipientUseCase({ username: "existing-recipient", firstName: "Duplicate", lastName: "Username", department: "OTHER", email: "unique-recipient@example.test", phone: null, }), ).resolves.toEqual({ success: false, errors: { username: ["Username already exists"] }, }) await expect( createRecipientUseCase({ username: "unique-recipient", firstName: "Duplicate", lastName: "Email", department: "OTHER", email: "existing-recipient@example.test", phone: null, }), ).resolves.toEqual({ success: false, errors: { email: ["Email already exists"] }, }) await expect(prisma.recipient.count()).resolves.toBe(1) }) it("updates a recipient and rejects duplicate usernames or emails", async () => { const recipient = await createTestRecipient(prisma, { username: "editable-recipient", email: "editable-recipient@example.test", phone: "111111111", }) const other = await createTestRecipient(prisma, { username: "other-recipient", email: "other-recipient@example.test", }) await expect( updateRecipientUseCase({ id: recipient.id, username: "edited-recipient", firstName: "Edited", lastName: "Recipient", department: "ENGINEERING", email: "edited-recipient@example.test", phone: "222222222", }), ).resolves.toEqual({ success: true }) await expect( prisma.recipient.findUniqueOrThrow({ where: { id: recipient.id } }), ).resolves.toMatchObject({ username: "edited-recipient", firstName: "Edited", lastName: "Recipient", department: "ENGINEERING", email: "edited-recipient@example.test", phone: "222222222", }) await expect( updateRecipientUseCase({ id: recipient.id, username: other.username, firstName: "Edited", lastName: "Recipient", department: "ENGINEERING", email: "new-recipient@example.test", phone: "222222222", }), ).resolves.toEqual({ success: false, errors: { username: ["Username already exists"] }, }) await expect( updateRecipientUseCase({ id: recipient.id, username: "edited-recipient", firstName: "Edited", lastName: "Recipient", department: "ENGINEERING", email: other.email, phone: "222222222", }), ).resolves.toEqual({ success: false, errors: { email: ["Email already exists"] }, }) await expect( prisma.recipient.findUniqueOrThrow({ where: { id: recipient.id } }), ).resolves.toMatchObject({ username: "edited-recipient", email: "edited-recipient@example.test", }) await expect(prisma.recipient.count()).resolves.toBe(2) }) })