144 lines
5.0 KiB
TypeScript
144 lines
5.0 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
|
|
import { UniqueID } from "@repo/rdx-ddd";
|
|
import { Maybe } from "@repo/rdx-utils";
|
|
|
|
import { AssetCatalog } from "./asset-catalog.aggregate";
|
|
import { seedAssetCatalog } from "./asset-catalog-seed";
|
|
import { AssetRelationship } from "./asset-relationship.aggregate";
|
|
import { AssetDefinitionValues } from "./value-objects/asset-definition-values.vo";
|
|
import type { RelationshipValuesData } from "./value-objects/asset-relationship-values.vo";
|
|
import { AssetRelationshipValues } from "./value-objects/asset-relationship-values.vo";
|
|
|
|
const sourceId = UniqueID.generateNewID().toPrimitive();
|
|
const targetId = UniqueID.generateNewID().toPrimitive();
|
|
const typeId = UniqueID.generateNewID().toPrimitive();
|
|
|
|
function input(symmetric = false): RelationshipValuesData {
|
|
return {
|
|
sourceId,
|
|
targetId,
|
|
typeId,
|
|
name: " Alojado en ",
|
|
inverseName: " Aloja ",
|
|
symmetric,
|
|
notes: " rack 1 ",
|
|
};
|
|
}
|
|
|
|
function values(data = input()) {
|
|
const result = AssetRelationshipValues.create(data);
|
|
|
|
assert.ok(result.isSuccess);
|
|
|
|
return result.data;
|
|
}
|
|
|
|
test("Las relaciones validan sus extremos, normalizan nombres y distinguen dirección", () => {
|
|
const first = values();
|
|
|
|
assert.equal(first.toPrimitive().name, "Alojado en");
|
|
assert.equal(first.notes, "rack 1");
|
|
assert.notEqual(
|
|
first.key(),
|
|
values({ ...input(), sourceId: targetId, targetId: sourceId }).key()
|
|
);
|
|
const symmetric = values(input(true));
|
|
|
|
assert.equal(
|
|
symmetric.key(),
|
|
values({ ...input(true), sourceId: targetId, targetId: sourceId }).key()
|
|
);
|
|
assert.equal(symmetric.toPrimitive().inverseName, "Alojado en");
|
|
const self = AssetRelationshipValues.create({ ...input(), targetId: sourceId });
|
|
|
|
assert.ok(!self.isSuccess);
|
|
assert.equal(self.error.code, "SELF_RELATIONSHIP");
|
|
assert.ok(!AssetRelationshipValues.create({ ...input(), targetId: "bad" }).isSuccess);
|
|
assert.ok(!AssetRelationshipValues.create({ ...input(), inverseName: " " }).isSuccess);
|
|
assert.ok(!AssetRelationshipValues.create({ ...input(), notes: "x".repeat(10001) }).isSuccess);
|
|
assert.ok(Object.isFrozen(first));
|
|
});
|
|
test("Retirar conserva UUID, extremos y auditoría; repetir la retirada no modifica el historial", () => {
|
|
const company = UniqueID.generateNewID();
|
|
const actor = UniqueID.generateNewID();
|
|
const otherActor = UniqueID.generateNewID();
|
|
const created = AssetRelationship.create(company, values(), actor, "2026-10-04T10:00:00.000Z");
|
|
|
|
assert.ok(created.isSuccess);
|
|
const link = created.data;
|
|
|
|
assert.equal(link.id.toPrimitive().charAt(14), "7");
|
|
assert.ok(link.active);
|
|
assert.ok(!link.end(otherActor, "2026-10-03T10:00:00.000Z").isSuccess);
|
|
const ended = link.end(otherActor, "2026-10-04T11:00:00.000Z");
|
|
|
|
assert.ok(ended.isSuccess);
|
|
assert.equal(ended.data.active, false);
|
|
assert.ok(ended.data.id.equals(link.id));
|
|
assert.equal(ended.data.values, link.values);
|
|
assert.ok(ended.data.createdBy.equals(actor));
|
|
assert.ok(ended.data.endedBy.getOrUndefined()?.equals(otherActor));
|
|
const retry = ended.data.end(actor, "2026-10-04T12:00:00.000Z");
|
|
|
|
assert.ok(retry.isSuccess);
|
|
assert.equal(retry.data, ended.data);
|
|
assert.ok(link.active);
|
|
});
|
|
test("Tipos de relación de serie protegidos, ámbito de compañía y dirección fija", () => {
|
|
const scope = Maybe.some(UniqueID.generateNewID());
|
|
const other = Maybe.some(UniqueID.generateNewID());
|
|
let catalog = seedAssetCatalog(AssetCatalog.create());
|
|
const stock = catalog.definitions.find((item) => item.values.data.kind === "relation");
|
|
|
|
assert.ok(stock);
|
|
const spec = {
|
|
kind: "relation",
|
|
name: "Conectado a",
|
|
inverseName: "Conectado a",
|
|
description: "",
|
|
symmetric: true,
|
|
} as const;
|
|
const custom = AssetDefinitionValues.create({
|
|
...spec,
|
|
name: "Replica a",
|
|
inverseName: "Replicado desde",
|
|
symmetric: false,
|
|
});
|
|
|
|
assert.ok(custom.isSuccess);
|
|
const protectedChange = catalog.save(Maybe.none(), Maybe.some(stock.id), custom.data);
|
|
|
|
assert.ok(!protectedChange.isSuccess);
|
|
assert.equal(protectedChange.error.code, "BUILTIN_PROTECTED");
|
|
const status = catalog.setActive(scope, stock.id, false);
|
|
|
|
assert.ok(status.isSuccess);
|
|
catalog = status.data;
|
|
assert.equal(catalog.active(stock, scope), false);
|
|
assert.equal(catalog.active(stock, other), true);
|
|
const added = catalog.save(scope, Maybe.none(), custom.data);
|
|
|
|
assert.ok(added.isSuccess);
|
|
catalog = added.data;
|
|
const item = catalog.definitions.at(-1);
|
|
|
|
assert.ok(item);
|
|
assert.equal(
|
|
catalog.visible(other).some((entry) => entry.id.equals(item.id)),
|
|
false
|
|
);
|
|
const converted = AssetDefinitionValues.create({ ...spec, name: "Replica a" });
|
|
|
|
assert.ok(converted.isSuccess);
|
|
const rejected = catalog.save(scope, Maybe.some(item.id), converted.data);
|
|
|
|
assert.ok(!rejected.isSuccess);
|
|
assert.equal(rejected.error.code, "RELATION_DIRECTION_FIXED");
|
|
const unchanged = catalog.save(scope, Maybe.some(item.id), custom.data);
|
|
|
|
assert.ok(unchanged.isSuccess);
|
|
assert.equal(unchanged.data, catalog);
|
|
});
|