metis-desk/modules/assets/src/api/domain/workstation.test.ts
David b45925f3e2 feat(assets): implement asset picker dialog and selection components
- Added `useAssetPickerController` for managing asset selection logic.
- Created `AssetSelectProps` type for defining asset selection properties.
- Implemented `AssetPickerDialog` for displaying the asset selection interface.
- Developed `AssetPickerList` for rendering the list of selectable assets.
- Introduced `AssetSelect` component for integrating the asset picker into forms.
- Created `AssetList` component for shared asset listing functionality.
- Added tests for workstation creation logic to ensure proper validation.
- Implemented workstation asset fields and association fields for managing workstation assets.
- Developed workstation lifecycle dialog for managing work profile states.
- Added form progress component for visualizing multi-step forms.
2026-10-14 19:42:59 +02:00

158 lines
5.4 KiB
TypeScript

import assert from "node:assert/strict";
import { test } from "node:test";
import { UniqueID } from "@repo/rdx-ddd";
import { WorkstationValues } from "./value-objects/workstation-values.vo";
import { Workstation } from "./workstation.aggregate";
import type { WorkstationInput } from "./workstation-values";
const assetIds = [UniqueID.generateNewID().toPrimitive(), UniqueID.generateNewID().toPrimitive()];
function input(): WorkstationInput {
return {
name: " Puesto Ana ",
active: true,
siteId: null,
personId: null,
assetIds,
};
}
function values(data = input()) {
const result = WorkstationValues.create(data);
assert.ok(result.isSuccess);
return result.data;
}
test("Puestos: composición opcional, referencias válidas y límites sin duplicados", () => {
assert.ok(WorkstationValues.create({ ...input(), assetIds: [] }).isSuccess);
assert.equal(values().name.toPrimitive(), "Puesto Ana");
assert.ok(Object.isFrozen(values().assetIds));
assert.ok(!WorkstationValues.create({ ...input(), name: " " }).isSuccess);
assert.ok(!WorkstationValues.create({ ...input(), personId: "invalid" }).isSuccess);
const duplicate = WorkstationValues.create({
...input(),
assetIds: [assetIds[0] ?? "", assetIds[0] ?? ""],
});
assert.ok(!duplicate.isSuccess);
assert.equal(duplicate.error.code, "INVALID_MEMBERS");
assert.ok(
!WorkstationValues.create({
...input(),
assetIds: Array.from({ length: 201 }, () => UniqueID.generateNewID().toPrimitive()),
}).isSuccess
);
assert.ok(values().equals(values({ ...input(), assetIds: [...assetIds].reverse() })));
});
test("Puestos: UUID estable e historial de composición, persona y estado; guardado idéntico idempotente", () => {
const company = UniqueID.generateNewID();
const actor = UniqueID.generateNewID();
const created = Workstation.create(company, values(), actor, "2026-10-04T10:00:00.000Z");
assert.ok(created.isSuccess);
const item = created.data;
assert.equal(item.id.toPrimitive().charAt(14), "7");
assert.equal(item.history[0]?.id.toPrimitive().charAt(14), "7");
const same = item.update(
values({ ...input(), assetIds: [...assetIds].reverse() }),
actor,
"2026-10-04T11:00:00.000Z"
);
assert.ok(same.isSuccess);
assert.equal(same.data, item);
const changed = item.update(
values({ ...input(), personId: actor.toPrimitive(), active: false, assetIds: [] }),
actor,
"2026-10-04T11:00:00.000Z"
);
assert.ok(changed.isSuccess);
assert.ok(changed.data.id.equals(item.id));
assert.equal(changed.data.history.length, 2);
assert.equal(changed.data.history[0]?.values.toPrimitive().personId, null);
assert.deepEqual(changed.data.history[0]?.values.toPrimitive().assetIds, assetIds);
assert.ok(!changed.data.update(values(), actor, "2026-10-03T10:00:00.000Z").isSuccess);
assert.equal(
Workstation.rehydrate(
{ companyId: company, values: changed.data.values, history: changed.data.history },
changed.data.id
).id.toPrimitive(),
item.id.toPrimitive()
);
});
test("Puestos: ordenador principal exclusivo, único e independiente del responsable", () => {
const computerId = assetIds[0] ?? "";
const first = values({ ...input(), computerAssetId: computerId });
assert.equal(first.toPrimitive().computerAssetId, computerId);
assert.equal(first.toPrimitive().personId, null);
assert.ok(
!WorkstationValues.create({
...input(),
computerAssetId: UniqueID.generateNewID().toPrimitive(),
}).isSuccess
);
assert.ok(
!WorkstationValues.create({
...input(),
computerAssetId: computerId,
assetIds: [],
}).isSuccess
);
assert.ok(!first.equals(values({ ...input(), computerAssetId: assetIds[1] })));
assert.ok(
first.equals(
values({ ...input(), computerAssetId: computerId, assetIds: [...assetIds].reverse() })
)
);
});
test("baja del puesto: libera composición y responsable, conserva historial e identidad y es idempotente", () => {
const actor = UniqueID.generateNewID();
const created = Workstation.create(
UniqueID.generateNewID(),
values({
...input(),
computerAssetId: assetIds[0] ?? null,
personId: actor.toPrimitive(),
}),
actor,
"2026-10-13T10:00:00.000Z"
);
assert.ok(created.isSuccess);
const retired = created.data.decommission(actor, "2026-10-13T11:00:00.000Z");
assert.ok(retired.isSuccess);
assert.ok(retired.data.id.equals(created.data.id));
assert.equal(retired.data.history.length, 2);
assert.equal(retired.data.values.active, false);
assert.equal(retired.data.values.toPrimitive().personId, null);
assert.equal(retired.data.values.computerAssetId.getOrUndefined(), undefined);
assert.deepEqual(retired.data.values.toPrimitive().assetIds, []);
assert.deepEqual(retired.data.history[0]?.values.toPrimitive().assetIds, assetIds);
assert.ok(retired.data.history[1]?.actorId.equals(actor));
const repeated = retired.data.decommission(actor, "2026-10-13T12:00:00.000Z");
assert.ok(repeated.isSuccess);
assert.equal(repeated.data, retired.data);
const previouslyInactive = created.data.update(
values({ ...created.data.values.toPrimitive(), active: false }),
actor,
"2026-10-13T10:30:00.000Z"
);
assert.ok(previouslyInactive.isSuccess);
const cleared = previouslyInactive.data.decommission(actor, "2026-10-13T11:00:00.000Z");
assert.ok(cleared.isSuccess);
assert.deepEqual(cleared.data.values.assetIds, []);
});