feat(assets): add asset metadata views and enforce assignment transitions

This commit is contained in:
2026-06-19 17:14:22 +02:00
parent c1763ed007
commit f32d55a7b0
17 changed files with 1573 additions and 70 deletions
+113
View File
@@ -0,0 +1,113 @@
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(),
createAssetUseCase: vi.fn(),
updateAssetUseCase: 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/asset.use-cases", () => ({
createAssetUseCase: mocks.createAssetUseCase,
updateAssetUseCase: mocks.updateAssetUseCase,
}))
import { createAssetAction, updateAssetAction } from "@/actions/asset.actions"
describe("asset actions", () => {
beforeEach(() => {
vi.clearAllMocks()
mocks.getI18n.mockResolvedValue({ dictionary: en, locale: "en" })
mocks.getAuthenticatedUserId.mockResolvedValue("user-1")
})
it("accepts operational asset fields on create and forwards them to the use case", async () => {
mocks.createAssetUseCase.mockResolvedValue({
success: true,
assetId: "asset-1",
})
const result = await createAssetAction({
itemId: "item-1",
serialNumber: "SERIAL-1",
status: "AVAILABLE",
assetTag: "IT-000900",
manufacturer: "Lenovo",
model: "ThinkPad P1",
purchaseDate: "2026-01-15",
purchasePrice: "1400.25",
warrantyEndsAt: "2028-01-15",
})
expect(result).toEqual({
success: true,
message: en.inventory.assets.actions.createSuccess,
})
expect(mocks.createAssetUseCase).toHaveBeenCalledWith({
actorId: "user-1",
itemId: "item-1",
serialNumber: "SERIAL-1",
status: "AVAILABLE",
assetTag: "IT-000900",
manufacturer: "Lenovo",
model: "ThinkPad P1",
purchaseDate: new Date("2026-01-15T00:00:00.000Z"),
purchasePrice: 1400.25,
warrantyEndsAt: new Date("2028-01-15T00:00:00.000Z"),
})
expect(mocks.revalidatePath).toHaveBeenCalledWith("/inventory/assets")
expect(mocks.revalidatePath).toHaveBeenCalledWith("/inventory/items")
})
it("accepts operational asset fields on update and forwards them to the use case", async () => {
mocks.updateAssetUseCase.mockResolvedValue({ success: true })
const result = await updateAssetAction({
id: "asset-1",
itemId: "item-1",
serialNumber: "SERIAL-1",
status: "BROKEN",
assetTag: "IT-000901",
manufacturer: "Dell",
model: "Latitude 7420",
purchaseDate: "2026-02-01",
purchasePrice: "1499.5",
warrantyEndsAt: "2027-02-01",
})
expect(result).toEqual({
success: true,
message: en.inventory.assets.actions.updateSuccess,
})
expect(mocks.updateAssetUseCase).toHaveBeenCalledWith({
actorId: "user-1",
id: "asset-1",
itemId: "item-1",
serialNumber: "SERIAL-1",
status: "BROKEN",
assetTag: "IT-000901",
manufacturer: "Dell",
model: "Latitude 7420",
purchaseDate: new Date("2026-02-01T00:00:00.000Z"),
purchasePrice: 1499.5,
warrantyEndsAt: new Date("2027-02-01T00:00:00.000Z"),
})
expect(mocks.revalidatePath).toHaveBeenCalledWith("/inventory/assets")
expect(mocks.revalidatePath).toHaveBeenCalledWith("/inventory/items")
})
})