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(), 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); });