From 60ecfff794c70ac30bd35a198e355e3b57e504e0 Mon Sep 17 00:00:00 2001 From: enlineawork Date: Sun, 6 Sep 2026 21:30:03 -0300 Subject: [PATCH] =?UTF-8?q?test:=20validar=20normalizaci=C3=B3n=20de=20pla?= =?UTF-8?q?nillas=20F2.2.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/f2-2-1-reference-excel-data.test.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 api-v3/test/f2-2-1-reference-excel-data.test.ts diff --git a/api-v3/test/f2-2-1-reference-excel-data.test.ts b/api-v3/test/f2-2-1-reference-excel-data.test.ts new file mode 100644 index 0000000..18db98d --- /dev/null +++ b/api-v3/test/f2-2-1-reference-excel-data.test.ts @@ -0,0 +1,49 @@ +import assert from 'node:assert/strict'; +import { test } from 'node:test'; +import { loadF221ExcelSource } from '../src/reference-data/f2-2-1-excel-source'; + +const source = loadF221ExcelSource(); + +test('F2.2.1 preserves every normalized territorial source row', () => { + assert.equal(source.territory.length, 230); + assert.equal(new Set(source.territory.map((row) => row.field)).size, 220); + assert.equal(new Set(source.territory.map((row) => `${row.field.toLowerCase()}|${row.area.toLowerCase()}`)).size, 230); +}); + +test('F2.2.1 does not collapse repeated field names across different operational contexts', () => { + const byName = new Map>(); + for (const row of source.territory) { + const key = row.field.toLowerCase(); + const contexts = byName.get(key) ?? new Set(); + contexts.add(`${row.area}|${row.operator}`); + byName.set(key, contexts); + } + assert.ok([...byName.values()].some((contexts) => contexts.size > 1)); +}); + +test('F2.2.1 keeps the APP matrix as configuration rather than physical inventory rows', () => { + assert.equal(source.types.length, 113); + assert.equal(source.parentPairs.length, 119); + assert.equal(source.attributes.length, 44); + assert.equal(source.idemRefs.length, 25); + assert.ok(source.types.some((entry) => entry.code === 'tanque')); + assert.ok(source.types.some((entry) => entry.code === 'bateria')); +}); + +test('F2.2.1 keeps IDEM as inheritance metadata, never as a catalog title', () => { + const directTitles = source.directFindings.flatMap((entry) => entry.titles); + assert.equal(directTitles.some((title) => /^idem\b/i.test(title.trim())), false); + assert.ok(source.idemRefs.some((entry) => entry.type === 'tanque')); +}); + +test('F2.2.1 imports the grouped Hallazgo catalog supplied in Hoja2', () => { + assert.equal(source.groups.length, 19); + assert.equal(source.groups.reduce((total, group) => total + group.items.length, 0), 171); + const tanks = source.groups.find((group) => group.name.trim().toUpperCase() === 'TANQUES'); + assert.ok(tanks); + assert.ok(tanks.items.some((item) => /ESTADO DEL TANQUE/i.test(item.title))); +}); + +test('F2.2.1 preserves rows explicitly reporting no operator without fabricating an organization in source data', () => { + assert.ok(source.territory.some((row) => row.operator.toLowerCase().includes('sin empresa operadora'))); +});