import assert from "node:assert/strict"; import test from "node:test"; import { fiscalQaRows } from "../../resources/js/lib/fiscal-qa-preview.ts"; import { exportCompletedArithmeticCsv, readArithmeticSnapshot } from "../../resources/js/lib/simulation-form.ts"; import { createProjectDossierReport } from "../../resources/js/lib/project-dossier-report.ts"; function fixture() { const snapshot = { contract_version: 1, scenario_kind: "fiscal_rule_qa_preview", base: "0.03", currency: "MZN", indicative_total: "0.0048", legal_interpretation: false, formula_version: "investmoz.tax.v1", context: { reference_date: "2026-10-21", currency: "MZN", currency_fraction_digits: 2, scenario_id: "61000100-0000-4000-8000-000000000099", scenario_version: 1, engine_version: "fiscal-draft-preview-v1", ruleset_version: "IVA-GERAL-BASE-LIQUIDA:1", }, result: { status: "calculated", value: "0.0048", unit: "MZN", explanation: "Cálculo exacto QA; enquadramento declarado; não é saldo a pagar.", missing_inputs: [], source_ids: ["source-fixture"], }, intermediate: { result: "48/10000" }, fiscal_provenance: { rule: { rule_code: "IVA-GERAL-BASE-LIQUIDA", rule_version: 1, valid_from: "2023-01-01", valid_until: null, source_sha256: "a".repeat(64), source: { diploma: "Lei 22/2022", article: "Artigo 17(1)" }, }, }, }; return { id: "61000100-0000-4000-8000-000000000088", status: "completed", version_no: 2, result_snapshot: snapshot, reports: [ { id: "61000100-0000-4000-8000-000000000077", version_no: 1, status: "ready", report_snapshot: structuredClone(snapshot), report_sha256: "b".repeat(64), }, ], }; } test("screen rows preserve sub-cent IVA as a string and distinguish calculation from payment", () => { const simulation = fixture(); const before = JSON.stringify(simulation); const rows = fiscalQaRows(simulation.result_snapshot); assert.equal( rows.find(([label]) => label.startsWith("IVA calculado"))[1], "0.0048", ); assert.match( rows.find(([label]) => label === "Arredondamento")[1], /Não aplicado/, ); assert.match( rows.find(([label]) => label === "Enquadramento")[1], /não validado juridicamente/, ); assert.equal(JSON.stringify(simulation), before); }); test("CSV preserves the exact amount and refuses a mismatched immutable report", () => { const simulation = fixture(); const csv = exportCompletedArithmeticCsv( simulation, "2026-10-21T09:00:00Z", ); assert.match(csv, /0\.0048/); assert.doesNotMatch(csv, /Resultado fiscal final,Indeterminado/); simulation.reports[0].report_snapshot.result.value = "0.00"; assert.throws( () => exportCompletedArithmeticCsv(simulation), /relatório preservado/, ); }); test("dossier report uses the same exact snapshot and preserves genuine indetermination", () => { const simulation = fixture(); function report() { return createProjectDossierReport( { project_title: "QA fiscal", currency: "MZN" }, { selectedSections: new Set(["finance"]), currentCalculation: { status: "completed", version: 2, snapshot: simulation.result_snapshot, }, }, ); } const rows = report().sections.find( (section) => section.id === "finance", ).rows; assert.equal( rows.find((row) => row.field.startsWith("IVA calculado")).value, "0.0048", ); assert.equal( rows.find((row) => row.field === "Fonte da taxa").value, "Lei 22/2022 — Artigo 17(1)", ); simulation.result_snapshot.result.status = "indeterminate"; simulation.result_snapshot.result.value = null; simulation.result_snapshot.indicative_total = null; simulation.result_snapshot.result.missing_inputs = ["eligible_parameter"]; assert.equal( report() .sections.find((section) => section.id === "finance") .rows.find((row) => row.field.startsWith("IVA calculado")).value, "Indeterminado", ); }); test("published consumer routes the frozen snapshot through screen CSV and dossier without QA labels", () => { const simulation = fixture(); const snapshot = simulation.result_snapshot; snapshot.scenario_kind = "fiscal_rule_published"; snapshot.context.engine_version = "fiscal-published-v1"; snapshot.presentation = { value: snapshot.result.value, rounding_applied: false }; snapshot.result.explanation = "IVA pela versão publicada; enquadramento declarado."; snapshot.fiscal_provenance.rule.status = "published"; snapshot.fiscal_provenance.scope_status = "user_declared"; snapshot.fiscal_provenance.mode = "published_version"; simulation.reports[0].report_snapshot = structuredClone(snapshot); const before = JSON.stringify(simulation); const rows = fiscalQaRows(snapshot); assert.equal(readArithmeticSnapshot(snapshot).integrity, "versioned"); assert.match(rows[0][1], /publicada/); assert.doesNotMatch(JSON.stringify(rows), /rascunho|não publicada|QA/); const csv = exportCompletedArithmeticCsv(simulation, "2026-10-21T12:00:00Z"); for (const [label, value] of rows) { assert.ok(csv.includes(label)); assert.ok(csv.includes(value.replaceAll('"', '""'))); } const report = createProjectDossierReport({ project_title: "Published IVA QA", currency: "MZN" }, { selectedSections: new Set(["finance"]), currentCalculation: { status: "completed", version: 2, snapshot }, }); const finance = report.sections.find((section) => section.id === "finance"); for (const [field, value] of rows) assert.ok(finance.rows.some((row) => row.field === field && row.value === value)); assert.doesNotMatch(JSON.stringify(finance), /rascunho|proveniência QA/); assert.equal(JSON.stringify(simulation), before); }); test("published consumer indeterminate snapshot is valid and a mismatched presentation is refused", () => { const snapshot = fixture().result_snapshot; snapshot.scenario_kind = "fiscal_rule_published"; snapshot.result.status = "indeterminate"; snapshot.result.value = null; snapshot.result.missing_inputs = ["operation_scope"]; snapshot.indicative_total = null; snapshot.presentation = { value: null, rounding_applied: false }; assert.equal(readArithmeticSnapshot(snapshot).integrity, "versioned"); snapshot.presentation.value = "0"; assert.equal(readArithmeticSnapshot(snapshot).integrity, "invalid"); });