test: add initial unit integration and e2e coverage
Adds the initial testing baseline for the project: Unit coverage: - Zod schemas for items, assignments, movements, categories, auth, recipients, users, and assets - password hashing and verification helpers - auth role helper functions Integration coverage with PostgreSQL Testcontainers: - item use-cases: create, duplicate names, delete constraints - assignment use-cases: create, insufficient stock, return, double return - asset use-cases: available/assigned creation and lifecycle transitions - user use-cases: create/update, uniqueness, admin safeguards, password reset - category use-cases: create/update/delete constraints - recipient use-cases: create/update and uniqueness constraints E2E smoke coverage with Playwright: - unauthenticated redirect to login - seeded admin login - dashboard load - admin users page - inventory items page - assignments page Also configures: - Vitest - Playwright - PostgreSQL Testcontainers helpers - deterministic E2E admin bootstrap - test artifact ignores Validation: - bun run test: 9 files / 37 tests passed - bun run test:e2e: 3 passed - bunx tsc --noEmit: passed - bunx prisma validate: passed
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
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)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user