191 lines
5.0 KiB
TypeScript
191 lines
5.0 KiB
TypeScript
import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest"
|
|
import type { PrismaClient } from "@/generated/prisma/client"
|
|
import { createTestPerson, createTestUser } from "../helpers/factories"
|
|
import {
|
|
resetIntegrationTestDatabase,
|
|
startIntegrationTestDatabase,
|
|
stopIntegrationTestDatabase,
|
|
} from "../helpers/test-db"
|
|
|
|
let prisma: PrismaClient
|
|
let createPersonUseCase: typeof import("@/use-cases/person.use-cases").createPersonUseCase
|
|
let updatePersonUseCase: typeof import("@/use-cases/person.use-cases").updatePersonUseCase
|
|
|
|
beforeAll(async () => {
|
|
await startIntegrationTestDatabase()
|
|
|
|
const prismaModule = await import("@/lib/prisma")
|
|
const personUseCases = await import("@/use-cases/person.use-cases")
|
|
|
|
prisma = prismaModule.prisma
|
|
createPersonUseCase = personUseCases.createPersonUseCase
|
|
updatePersonUseCase = personUseCases.updatePersonUseCase
|
|
})
|
|
|
|
beforeEach(async () => {
|
|
await resetIntegrationTestDatabase(prisma)
|
|
})
|
|
|
|
afterAll(async () => {
|
|
await prisma?.$disconnect()
|
|
await stopIntegrationTestDatabase()
|
|
})
|
|
|
|
describe("person use-cases", () => {
|
|
it("creates a person and normalizes empty optional contact fields to null", async () => {
|
|
await expect(
|
|
createPersonUseCase({
|
|
firstName: "Person",
|
|
lastName: "One",
|
|
department: "IT",
|
|
email: "",
|
|
phone: "",
|
|
}),
|
|
).resolves.toEqual({ success: true })
|
|
|
|
await expect(
|
|
prisma.person.findFirstOrThrow({
|
|
where: { firstName: "Person", lastName: "One" },
|
|
}),
|
|
).resolves.toMatchObject({
|
|
firstName: "Person",
|
|
lastName: "One",
|
|
department: "IT",
|
|
email: null,
|
|
phone: null,
|
|
userId: null,
|
|
})
|
|
})
|
|
|
|
it("creates a person with linked userId", async () => {
|
|
const user = await createTestUser(prisma)
|
|
|
|
await expect(
|
|
createPersonUseCase({
|
|
firstName: "Linked",
|
|
lastName: "Person",
|
|
department: "ENGINEERING",
|
|
email: "linked@example.test",
|
|
phone: null,
|
|
userId: user.id,
|
|
}),
|
|
).resolves.toEqual({ success: true })
|
|
|
|
await expect(
|
|
prisma.person.findFirstOrThrow({
|
|
where: { firstName: "Linked" },
|
|
}),
|
|
).resolves.toMatchObject({
|
|
firstName: "Linked",
|
|
lastName: "Person",
|
|
department: "ENGINEERING",
|
|
email: "linked@example.test",
|
|
userId: user.id,
|
|
})
|
|
})
|
|
|
|
it("rejects duplicate emails on create", async () => {
|
|
await createTestPerson(prisma, {
|
|
email: "existing@example.test",
|
|
})
|
|
|
|
await expect(
|
|
createPersonUseCase({
|
|
firstName: "Duplicate",
|
|
lastName: "Email",
|
|
department: "OTHER",
|
|
email: "existing@example.test",
|
|
phone: null,
|
|
}),
|
|
).resolves.toEqual({
|
|
success: false,
|
|
errors: { email: ["Email already exists"] },
|
|
})
|
|
|
|
await expect(prisma.person.count()).resolves.toBe(1)
|
|
})
|
|
|
|
it("updates a person and rejects duplicate emails", async () => {
|
|
const person = await createTestPerson(prisma, {
|
|
email: "person@example.test",
|
|
phone: "111111111",
|
|
})
|
|
const other = await createTestPerson(prisma, {
|
|
email: "other@example.test",
|
|
})
|
|
|
|
await expect(
|
|
updatePersonUseCase({
|
|
id: person.id,
|
|
firstName: "Edited",
|
|
lastName: "Person",
|
|
department: "ENGINEERING",
|
|
email: "edited@example.test",
|
|
phone: "222222222",
|
|
}),
|
|
).resolves.toEqual({ success: true })
|
|
|
|
await expect(
|
|
prisma.person.findUniqueOrThrow({ where: { id: person.id } }),
|
|
).resolves.toMatchObject({
|
|
firstName: "Edited",
|
|
lastName: "Person",
|
|
department: "ENGINEERING",
|
|
email: "edited@example.test",
|
|
phone: "222222222",
|
|
})
|
|
|
|
await expect(
|
|
updatePersonUseCase({
|
|
id: person.id,
|
|
firstName: "Edited",
|
|
lastName: "Person",
|
|
department: "ENGINEERING",
|
|
email: other.email,
|
|
phone: "222222222",
|
|
}),
|
|
).resolves.toEqual({
|
|
success: false,
|
|
errors: { email: ["Email already exists"] },
|
|
})
|
|
|
|
await expect(
|
|
prisma.person.findUniqueOrThrow({ where: { id: person.id } }),
|
|
).resolves.toMatchObject({
|
|
email: "edited@example.test",
|
|
})
|
|
await expect(prisma.person.count()).resolves.toBe(2)
|
|
})
|
|
|
|
it("searches by email and name in paginated results", async () => {
|
|
await createTestPerson(prisma, {
|
|
firstName: "Alice",
|
|
lastName: "Smith",
|
|
email: "alice@company.com",
|
|
})
|
|
await createTestPerson(prisma, {
|
|
firstName: "Bob",
|
|
lastName: "Jones",
|
|
email: "bob@other.com",
|
|
})
|
|
|
|
const { PersonService } = await import("@/services/person.service")
|
|
|
|
const emailResults = await PersonService.findAllPaginated({
|
|
search: "company",
|
|
page: 1,
|
|
pageSize: 10,
|
|
})
|
|
expect(emailResults.data).toHaveLength(1)
|
|
expect(emailResults.data[0].firstName).toBe("Alice")
|
|
|
|
const nameResults = await PersonService.findAllPaginated({
|
|
search: "Bob",
|
|
page: 1,
|
|
pageSize: 10,
|
|
})
|
|
expect(nameResults.data).toHaveLength(1)
|
|
expect(nameResults.data[0].firstName).toBe("Bob")
|
|
})
|
|
})
|