172 lines
6.4 KiB
TypeScript
172 lines
6.4 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 { 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.vo";
|
|
|
|
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());
|
|
assert.equal(catalog.definitions.length, 26);
|
|
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);
|
|
});
|
|
|
|
test("licencias: ampliar un catálogo previo conserva identidades y disponibilidad", () => {
|
|
const seeded = seedResourceCatalog(ResourceCatalog.create());
|
|
const originalKeys = new Set([
|
|
"field:email",
|
|
"field:provider",
|
|
"field:context",
|
|
"field:unc",
|
|
"field:server",
|
|
"field:description",
|
|
"field:url",
|
|
"field:holder",
|
|
"field:issuer",
|
|
"field:expires",
|
|
"field:fingerprint",
|
|
"field:purpose",
|
|
"field:reference",
|
|
"template:mailbox",
|
|
"template:access",
|
|
"template:shared_folder",
|
|
"template:application",
|
|
"template:certificate",
|
|
]);
|
|
const previous = ResourceCatalog.rehydrate(
|
|
{
|
|
definitions: seeded.definitions.filter((item) =>
|
|
originalKeys.has(item.stockKey.getOrUndefined() ?? "")
|
|
),
|
|
availability: [],
|
|
},
|
|
seeded.id
|
|
);
|
|
const original = previous.definitions[0];
|
|
assert.ok(original);
|
|
const disabled = previous.setActive(Maybe.none(), original.id, false);
|
|
assert.ok(disabled.isSuccess);
|
|
const upgraded = seedResourceCatalog(disabled.data);
|
|
assert.equal(upgraded.definitions.length, 26);
|
|
for (const existing of disabled.data.definitions) {
|
|
assert.equal(
|
|
upgraded.definitions.find((item) => item.id.equals(existing.id)),
|
|
existing
|
|
);
|
|
}
|
|
const license = upgraded.definitions.find(
|
|
(item) => item.stockKey.getOrUndefined() === "template:software_license"
|
|
);
|
|
assert.ok(license && license.values.data.kind === "template");
|
|
assert.ok(license.values.data.fields.every((binding) => !binding.required));
|
|
const protectedTemplate = license.update(values({ ...license.values.data, name: "Otra" }));
|
|
assert.ok(!protectedTemplate.isSuccess);
|
|
assert.equal(protectedTemplate.error.code, "BUILTIN_PROTECTED");
|
|
const company = UniqueID.generateNewID();
|
|
const locallyDisabled = upgraded.setActive(Maybe.some(company), license.id, false);
|
|
assert.ok(locallyDisabled.isSuccess);
|
|
assert.equal(locallyDisabled.data.active(license, Maybe.some(company)), false);
|
|
assert.equal(locallyDisabled.data.active(license, Maybe.none()), true);
|
|
assert.equal(seedResourceCatalog(locallyDisabled.data), locallyDisabled.data);
|
|
});
|