import assert from "node:assert/strict"; import { test } from "node:test"; import { UniqueID } from "@repo/rdx-ddd"; import { Asset } from "./asset.aggregate"; import type { AssetInput } from "./asset-values"; import { AssetSpecification, AssetValues } from "./value-objects/asset-values"; const company = UniqueID.generateNewID(); const actor = UniqueID.generateNewID(); const templateId = UniqueID.generateNewID().toPrimitive(); const ids = Array.from({ length: 5 }, () => UniqueID.generateNewID().toPrimitive()); function specification(required = false) { const types = ["text", "number", "date", "boolean", "choice"] as const; const result = AssetSpecification.create({ templateId, templateName: "Portátil", fields: ids.map((fieldId, index) => ({ fieldId, name: types[index] ?? "text", type: types[index] ?? "text", unit: "", choices: index === 4 ? ["A", "B"] : [], required: required && index === 3, })), }); assert.ok(result.isSuccess); return result.data; } function input(characteristics: AssetInput["characteristics"] = {}): AssetInput { return { name: " Equipo ", templateId, siteId: null, personId: null, status: "available", notes: "", characteristics, }; } test("Características opcionales, tipos y límites; cero y falso son valores presentes", () => { const spec = specification(); assert.ok(AssetValues.create(input(), spec).isSuccess); const typed = Object.fromEntries( ids.map((id, index) => [id, ["texto", 0, "2026-02-28", false, "A"][index] ?? ""]) ); const valid = AssetValues.create(input(typed), spec); assert.ok(valid.isSuccess); assert.equal(valid.data.toPrimitive().name, "Equipo"); for (const [index, value] of [ [1, "12"], [2, "2026-02-30"], [3, "false"], [4, "C"], ] as const) { const id = ids[index]; assert.ok(id); const failed = AssetValues.create(input({ [id]: value }), spec); assert.equal(failed.isSuccess, false); } assert.equal( AssetValues.create(input({ [UniqueID.generateNewID().toPrimitive()]: "extra" }), spec) .isSuccess, false ); const required = specification(true); assert.equal(AssetValues.create(input(), required).isSuccess, false); const boolean = ids[3]; assert.ok(boolean); assert.ok(AssetValues.create(input({ [boolean]: false }), required).isSuccess); assert.equal( AssetValues.create(input({ [boolean]: false, [ids[0] ?? ""]: "x".repeat(10001) }), spec) .isSuccess, false ); }); test("Activo conserva UUID y revisiones; los cambios iguales son idempotentes y retirado no admite asignación", () => { const spec = specification(); const first = AssetValues.create(input(), spec); assert.ok(first.isSuccess); const created = Asset.create(company, spec, first.data, actor, "2026-10-04T12:00:00.000Z"); assert.ok(created.isSuccess); const asset = created.data; assert.equal(asset.id.toPrimitive().charAt(14), "7"); assert.equal(asset.history[0]?.id.toPrimitive().charAt(14), "7"); const same = asset.update(first.data, actor, "2026-10-04T13:00:00.000Z"); assert.ok(same.isSuccess); assert.equal(same.data, asset); const next = AssetValues.create( { ...input(), personId: UniqueID.generateNewID().toPrimitive(), status: "in_use" }, spec ); assert.ok(next.isSuccess); const changed = asset.update(next.data, actor, "2026-10-04T13:00:00.000Z"); assert.ok(changed.isSuccess); assert.ok(changed.data.id.equals(asset.id)); assert.equal(changed.data.history.length, 2); assert.equal(changed.data.history[0]?.values.toPrimitive().personId, null); assert.equal( AssetValues.create({ ...next.data.toPrimitive(), status: "retired" }, spec).isSuccess, false ); assert.ok(Object.isFrozen(next.data.toPrimitive().characteristics)); });