Files
Investidor-V2/tests/frontend/iva-offer-preparations.test.mjs
T

161 lines
5.6 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import {
newOfferPreparation,
offerPreparationBook,
saveOfferPreparationBook,
recordOfferPreparations,
offerReusableData,
reuseOfferData,
offerPreparationReportRows,
} from '../../resources/js/lib/iva-offer-preparations.ts';
import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
const frozen = JSON.parse(
fs.readFileSync(
new URL('./fixtures/iva-g5c-inputs.json', import.meta.url),
'utf8',
),
);
const draft = () => structuredClone(frozen);
void test('incomplete P084/P085 drafts save without authorizations,zeroVAT or a benefit result;prior26books remain exact', () => {
const d = draft(),
before = JSON.parse(d.modelo_a_snapshot),
rows = ['P084', 'P085'].map((branch) =>
newOfferPreparation('gift-' + branch, branch, 'MZN'),
);
d.modelo_a_snapshot = saveOfferPreparationBook(d, { rows });
const next = JSON.parse(d.modelo_a_snapshot);
for (const key of Object.keys(before))
assert.deepEqual(next[key], before[key]);
assert.deepEqual(
offerPreparationBook(JSON.parse(JSON.stringify(d))).rows,
rows,
);
assert.equal(rows[1].operation, 'acquisition');
assert.equal(
'result' in next.offerPreparations[d.context_opportunity],
false,
);
for (const row of offerPreparationReportRows(d))
assert.match(row[2], /bénéfice|benefício não aplicado/);
assert.equal(
next.books['opportunity:329'].result.periods[0].fields['11'],
null,
);
});
void test('explicit reuse fills only empty fields,same opportunity;currency mismatch and P085 import rejected without mutation', () => {
const d = draft(),
sources = offerReusableData(d);
assert.equal(sources.length, 6);
const source = sources.find((x) => x.operation === 'import'),
original = structuredClone(source),
row = {
...newOfferPreparation('gift', 'P084', 'MZN'),
description: 'Edição deliberada',
beneficiary: 'Instituição QA',
};
const next = reuseOfferData(row, source);
assert.equal(next.description, row.description);
assert.equal(next.beneficiary, row.beneficiary);
assert.equal(next.documentRef, source.values.documentRef);
assert.equal(next.operation, 'import');
assert.equal(next.reusedFrom.key, source.key);
assert.deepEqual(source, original);
assert.equal(row.documentRef, '');
assert.throws(
() => reuseOfferData(newOfferPreparation('g', 'P085', 'MZN'), source),
/P085/,
);
assert.throws(
() => reuseOfferData({ ...row, currency: 'USD' }, source),
/Moeda/,
);
assert.equal(
offerReusableData({
...d,
context_opportunity: 'opportunity:does-not-exist',
}).length,
0,
);
});
void test('versions preserve deliberate edits and own branch conditions;report from saved/recovered draft does not extend benefit or field11', () => {
const d = draft();
let p84 = reuseOfferData(
newOfferPreparation('gift84', 'P084', 'MZN'),
offerReusableData(d).find((x) => x.operation === 'import'),
);
p84 = {
...p84,
beneficiary: 'SYNTHETIC QA instituição',
nationalInstitution: 'yes',
publicSocialInstitution: 'yes',
goodsSuitable: 'yes',
publicInterestUse: 'yes',
};
const p85 = {
...newOfferPreparation('gift85', 'P085', 'MZN'),
description: 'SYNTHETIC QA bens para cheias',
disaster: 'SYNTHETIC QA cheias',
disasterKind: 'Cheias',
mitigation: 'yes',
};
let book = recordOfferPreparations({ rows: [p84, p85] });
book = recordOfferPreparations({
...book,
rows: [{ ...p84, purpose: 'Edição posterior' }, p85],
});
assert.equal(book.history.length, 1);
assert.equal(book.history[0].rows[0].purpose, '');
d.modelo_a_snapshot = saveOfferPreparationBook(d, book);
assert.deepEqual(offerPreparationBook(JSON.parse(JSON.stringify(d))), book);
const report = JSON.stringify(
createProjectDossierReport(d, {
selectedSections: new Set(['finance']),
version: 'QA drafts',
}),
);
for (const token of [
'P084',
'P085',
'benefício não aplicado',
'SYNTHETIC QA cheias',
'Edição posterior',
'14(2)(a/b)',
'opportunity:334',
])
assert.ok(report.includes(token), token);
assert.equal(
offerPreparationBook({ ...d, context_opportunity: 'opportunity:333' })
.rows.length,
0,
);
if (process.env.IVA_OFFERS_CALCULATED)
fs.writeFileSync(process.env.IVA_OFFERS_CALCULATED, JSON.stringify(d));
});
void test('corrupt draft data cannot be replaced with empty book and P085 never accepts imported operation', () => {
for (const offerPreparations of [
[],
null,
{ 'opportunity:334': { rows: [{ id: 'broken' }] } },
]) {
const d = draft(),
s = JSON.parse(d.modelo_a_snapshot);
s.offerPreparations = offerPreparations;
d.modelo_a_snapshot = JSON.stringify(s);
assert.throws(() => saveOfferPreparationBook(d, { rows: [] }));
}
assert.throws(
() =>
saveOfferPreparationBook(draft(), {
rows: [
{
...newOfferPreparation('x', 'P085', 'MZN'),
operation: 'import',
},
],
}),
/operação/,
);
});