import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import test from 'node:test'; // SMETA.js is imported elsewhere via an extensionless path ("../columnColors") // that only the project's bundler (Rsbuild) resolves, so plain `node --test` // cannot `import` this module directly (ERR_MODULE_NOT_FOUND). Per AURORA-1903 // and its precedent (AURORA-1901's form2SmetaConfig test), we instead match the // file's text for its `accessorKey: "data...."` leaves and assert their order. const sourcePath = fileURLToPath(new URL('./SMETA.js', import.meta.url)); const source = readFileSync(sourcePath, 'utf8'); // AURORA-1903: экран формы 1 должен показывать "Утверждено ИТОГО Год" (Z) и // "Факт ИТОГО Год" (AL) — раньше их теряли, хотя SQL (v_form_view) всегда их // отдавал и выгрузка Excel их писала. Порядок ниже — источник истины для // колонок листа "Смета" формы 1: он литерально совпадает с порядком ключей // SMETA_COLUMNS_BY_FORM["FORM_1"] в api/src/services/export_service/export_mappings.py. const EXPECTED_DATA_ACCESSOR_KEY_ORDER = [ 'data.section_code', 'data.name', 'data.plan.support.q1', 'data.plan.support.q2', 'data.plan.support.q3', 'data.plan.support.q4', 'data.plan.support.year', 'data.plan.development.q1', 'data.plan.development.q2', 'data.plan.development.q3', 'data.plan.development.q4', 'data.plan.development.year', 'data.plan.total_year', 'data.approved.support.q1', 'data.approved.support.q2', 'data.approved.support.q3', 'data.approved.support.q4', 'data.approved.support.year', 'data.approved.development.q1', 'data.approved.development.q2', 'data.approved.development.q3', 'data.approved.development.q4', 'data.approved.development.year', 'data.approved.total_year', 'data.fact.support.q1', 'data.fact.support.q2', 'data.fact.support.q3', 'data.fact.support.q4', 'data.fact.support.year', 'data.fact.development.q1', 'data.fact.development.q2', 'data.fact.development.q3', 'data.fact.development.q4', 'data.fact.development.year', 'data.fact.total_year', 'data.corrected.support.q2', 'data.corrected.support.q3', 'data.corrected.support.q4', 'data.corrected.development.q2', 'data.corrected.development.q3', 'data.corrected.development.q4', ]; function extractDataAccessorKeysInOrder(text) { const re = /accessorKey:\s*"(data\.[^"]+)"/g; const keys = []; let match; while ((match = re.exec(text)) !== null) { keys.push(match[1]); } return keys; } test('FORM_1 SMETA screen leaf accessorKeys are in the ticket-mandated order (AURORA-1903)', () => { const keys = extractDataAccessorKeysInOrder(source); assert.deepEqual(keys, EXPECTED_DATA_ACCESSOR_KEY_ORDER); }); test('FORM_1 SMETA screen has exactly one approved.total_year (Z) and one fact.total_year (AL) column', () => { const keys = extractDataAccessorKeysInOrder(source); assert.equal(keys.filter((key) => key === 'data.approved.total_year').length, 1); assert.equal(keys.filter((key) => key === 'data.fact.total_year').length, 1); assert.match(source, /accessorKey:\s*"data\.approved\.total_year"[\s\S]{0,80}columnLetter:\s*"Z"/); assert.match(source, /accessorKey:\s*"data\.fact\.total_year"[\s\S]{0,80}columnLetter:\s*"AL"/); });