105 lines
3.0 KiB
TypeScript
105 lines
3.0 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest"
|
|
|
|
import { en } from "@/i18n/dictionaries/en"
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
revalidatePath: vi.fn(),
|
|
getI18n: vi.fn(),
|
|
getAuthenticatedUserId: vi.fn(),
|
|
returnAssignmentUseCase: vi.fn(),
|
|
}))
|
|
|
|
vi.mock("next/cache", () => ({
|
|
revalidatePath: mocks.revalidatePath,
|
|
}))
|
|
|
|
vi.mock("@/i18n/server", () => ({
|
|
getI18n: mocks.getI18n,
|
|
}))
|
|
|
|
vi.mock("@/services/auth.service", () => ({
|
|
getAuthenticatedUserId: mocks.getAuthenticatedUserId,
|
|
}))
|
|
|
|
vi.mock("@/use-cases/assignment.use-cases", () => ({
|
|
returnAssignmentUseCase: mocks.returnAssignmentUseCase,
|
|
}))
|
|
|
|
import { returnAssignment } from "@/actions/assignment.actions"
|
|
|
|
describe("returnAssignment action", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
mocks.getI18n.mockResolvedValue({ dictionary: en, locale: "en" })
|
|
mocks.getAuthenticatedUserId.mockResolvedValue("user-1")
|
|
})
|
|
|
|
it("returns validation errors for a missing assignment id", async () => {
|
|
const result = await returnAssignment({ id: "" })
|
|
|
|
expect(result).toEqual({
|
|
success: false,
|
|
errors: {
|
|
id: [en.inventory.assignments.schema.idRequired],
|
|
},
|
|
})
|
|
expect(mocks.returnAssignmentUseCase).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it("forwards returns to the use case and revalidates on success", async () => {
|
|
mocks.returnAssignmentUseCase.mockResolvedValue({ success: true })
|
|
|
|
const result = await returnAssignment({
|
|
id: "assignment-1",
|
|
returns: [
|
|
{ assignmentLineId: "line-1", quantity: 2, notes: "Slightly damaged" },
|
|
],
|
|
})
|
|
|
|
expect(result).toEqual({
|
|
success: true as const,
|
|
message: en.inventory.assignments.actions.returnSuccess,
|
|
})
|
|
expect(mocks.returnAssignmentUseCase).toHaveBeenCalledWith({
|
|
id: "assignment-1",
|
|
actorId: "user-1",
|
|
returns: [
|
|
{ assignmentLineId: "line-1", quantity: 2, notes: "Slightly damaged" },
|
|
],
|
|
})
|
|
expect(mocks.revalidatePath).toHaveBeenCalledWith("/assignments")
|
|
})
|
|
|
|
it("surfaces use-case errors and skips revalidation on failure", async () => {
|
|
mocks.returnAssignmentUseCase.mockResolvedValue({
|
|
success: false,
|
|
errors: { error: ["errorConcurrent"] },
|
|
})
|
|
|
|
const result = await returnAssignment({
|
|
id: "assignment-1",
|
|
returns: [{ assignmentLineId: "line-1", quantity: 2 }],
|
|
})
|
|
|
|
expect(result).toEqual({
|
|
success: false as const,
|
|
errors: { error: ["errorConcurrent"] },
|
|
message: en.inventory.assignments.actions.returnFailure,
|
|
})
|
|
expect(mocks.revalidatePath).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it("preserves the legacy full-return shortcut without returns", async () => {
|
|
mocks.returnAssignmentUseCase.mockResolvedValue({ success: true })
|
|
|
|
const result = await returnAssignment({ id: "assignment-1" })
|
|
|
|
expect(result.success).toBe(true)
|
|
expect(mocks.returnAssignmentUseCase).toHaveBeenCalledWith({
|
|
id: "assignment-1",
|
|
actorId: "user-1",
|
|
})
|
|
expect(mocks.revalidatePath).toHaveBeenCalledWith("/assignments")
|
|
})
|
|
})
|