2026-10-05 11:13:51 +00:00
|
|
|
import assert from "node:assert/strict";
|
|
|
|
|
import { test } from "node:test";
|
|
|
|
|
|
|
|
|
|
import { UniqueID } from "@repo/rdx-ddd";
|
|
|
|
|
import { Maybe } from "@repo/rdx-utils";
|
|
|
|
|
|
|
|
|
|
import { ResourceCatalog } from "./resource-catalog.aggregate";
|
|
|
|
|
import { seedResourceCatalog } from "./resource-catalog-seed";
|
|
|
|
|
import type { ResourceDefinitionSpec } from "./resource-definition";
|
|
|
|
|
import { ResourceDefinitionValues } from "./value-objects/resource-definition-values";
|
|
|
|
|
|
|
|
|
|
function values(input: ResourceDefinitionSpec) {
|
|
|
|
|
const result = ResourceDefinitionValues.create(input);
|
|
|
|
|
assert.ok(result.isSuccess);
|
|
|
|
|
return result.data;
|
|
|
|
|
}
|
|
|
|
|
const field = {
|
|
|
|
|
kind: "field",
|
|
|
|
|
name: "Marca",
|
|
|
|
|
description: "",
|
|
|
|
|
type: "text",
|
|
|
|
|
unit: "",
|
|
|
|
|
choices: [],
|
|
|
|
|
} as const;
|
|
|
|
|
test("catálogo de recursos: serie idempotente, UUID v7, características opcionales y protección", () => {
|
|
|
|
|
const catalog = seedResourceCatalog(ResourceCatalog.create());
|
2026-10-05 15:01:32 +00:00
|
|
|
assert.equal(catalog.definitions.length, 18);
|
2026-10-05 11:13:51 +00:00
|
|
|
assert.equal(seedResourceCatalog(catalog), catalog);
|
|
|
|
|
assert.ok(catalog.definitions.every((item) => item.id.toPrimitive()[14] === "7"));
|
|
|
|
|
const template = catalog.definitions.find((item) => item.values.data.kind === "template");
|
|
|
|
|
assert.ok(template && template.values.data.kind === "template");
|
|
|
|
|
assert.ok(template.values.data.fields.every((binding) => !binding.required));
|
|
|
|
|
assert.ok(template.bindings.every((binding) => binding.id.toPrimitive()[14] === "7"));
|
|
|
|
|
const changed = catalog.save(
|
|
|
|
|
Maybe.none(),
|
|
|
|
|
Maybe.some(template.id),
|
|
|
|
|
values({ ...template.values.data, name: "Cambio" })
|
|
|
|
|
);
|
|
|
|
|
assert.ok(!changed.isSuccess);
|
|
|
|
|
assert.equal(changed.error.code, "BUILTIN_PROTECTED");
|
|
|
|
|
const disabled = catalog.setActive(Maybe.none(), template.id, false);
|
|
|
|
|
assert.ok(disabled.isSuccess);
|
|
|
|
|
assert.equal(
|
|
|
|
|
seedResourceCatalog(disabled.data).definitions.find((item) => item.id.equals(template.id))
|
|
|
|
|
?.active,
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
test("ámbitos, tipos, listas, campos externos y disponibilidad por compañía", () => {
|
|
|
|
|
const company = UniqueID.generateNewID();
|
|
|
|
|
const other = UniqueID.generateNewID();
|
|
|
|
|
const saved = ResourceCatalog.create().save(
|
|
|
|
|
Maybe.some(company),
|
|
|
|
|
Maybe.none(),
|
|
|
|
|
values({ ...field, choices: [] })
|
|
|
|
|
);
|
|
|
|
|
assert.ok(saved.isSuccess);
|
|
|
|
|
const local = saved.data.definitions[0];
|
|
|
|
|
assert.ok(local);
|
|
|
|
|
assert.equal(saved.data.visible(Maybe.some(other)).length, 0);
|
|
|
|
|
const template = (fieldId: string): ResourceDefinitionSpec => ({
|
|
|
|
|
kind: "template",
|
|
|
|
|
name: "Propia",
|
|
|
|
|
description: "",
|
|
|
|
|
fields: [{ fieldId, required: false }],
|
|
|
|
|
});
|
|
|
|
|
for (const [scope, id] of [
|
|
|
|
|
[Maybe.none<UniqueID>(), local.id],
|
|
|
|
|
[Maybe.some(other), local.id],
|
|
|
|
|
[Maybe.some(company), UniqueID.generateNewID()],
|
|
|
|
|
] as const) {
|
|
|
|
|
const result = saved.data.save(scope, Maybe.none(), values(template(id.toPrimitive())));
|
|
|
|
|
assert.ok(!result.isSuccess);
|
|
|
|
|
assert.equal(result.error.code, "FIELD_UNAVAILABLE");
|
|
|
|
|
}
|
|
|
|
|
const duplicate = saved.data.save(
|
|
|
|
|
Maybe.some(company),
|
|
|
|
|
Maybe.none(),
|
|
|
|
|
values({ ...field, choices: [], name: " marca " })
|
|
|
|
|
);
|
|
|
|
|
assert.ok(!duplicate.isSuccess);
|
|
|
|
|
assert.equal(duplicate.error.code, "NAME_EXISTS");
|
|
|
|
|
const changeType = local.update(values({ ...field, choices: [], type: "number" }));
|
|
|
|
|
assert.ok(!changeType.isSuccess);
|
|
|
|
|
assert.equal(changeType.error.code, "FIELD_TYPE_FIXED");
|
|
|
|
|
assert.equal(
|
|
|
|
|
ResourceDefinitionValues.create({ ...field, type: "choice", choices: ["A", " a "] }).isSuccess,
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
const choices = saved.data.save(
|
|
|
|
|
Maybe.none(),
|
|
|
|
|
Maybe.none(),
|
|
|
|
|
values({ ...field, name: "Lista", type: "choice", choices: ["A", "B"] })
|
|
|
|
|
);
|
|
|
|
|
assert.ok(choices.isSuccess);
|
|
|
|
|
const list = choices.data.definitions.find((item) => item.values.data.name === "Lista");
|
|
|
|
|
assert.ok(list);
|
|
|
|
|
assert.equal(
|
|
|
|
|
list.update(values({ ...field, name: "Lista", type: "choice", choices: ["A"] })).isSuccess,
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
const seeded = seedResourceCatalog(ResourceCatalog.create());
|
|
|
|
|
const stock = seeded.definitions[0];
|
|
|
|
|
assert.ok(stock);
|
|
|
|
|
const override = seeded.setActive(Maybe.some(company), stock.id, false);
|
|
|
|
|
assert.ok(override.isSuccess);
|
|
|
|
|
assert.equal(override.data.active(stock, Maybe.some(company)), false);
|
|
|
|
|
assert.equal(override.data.active(stock, Maybe.some(other)), true);
|
|
|
|
|
const reset = override.data.setActive(Maybe.some(company), stock.id, null);
|
|
|
|
|
assert.ok(reset.isSuccess);
|
|
|
|
|
assert.equal(reset.data.active(stock, Maybe.some(company)), true);
|
|
|
|
|
});
|