18 lines
8.7 KiB
JavaScript
18 lines
8.7 KiB
JavaScript
import test from 'node:test';import assert from 'node:assert/strict';import fs from 'node:fs';
|
|
import {newIspcEligibilityInput,ispcEligibilityBook,saveIspcEligibilityBook,recordIspcEligibility,ispcEligibilityCurrent,ispcEligibilityReportRows,ispcReuseValues,ispcReuseDiff} from '../../resources/js/lib/ispc-eligibility.ts';
|
|
const seed=JSON.parse(fs.readFileSync(new URL('./fixtures/iva-l3e-preserved.json',import.meta.url),'utf8'));
|
|
function fixture(patch={}){const d={...structuredClone(seed),context_opportunity:'opportunity:375',fiscal_component:'ispc',person_type:'collective',fiscal_activity:'SYNTHETIC QA comércio',fiscal_establishments:'1',project_title:'SYNTHETIC QA — L4-A ISPC'},input={...newIspcEligibilityInput(d),activities:['commerce'],territory:'yes',basis:'previous_year',referenceYear:'2025',annualReference:'4000000',annualReferenceRef:'SYNTHETIC QA referência2025',organizedRequired:'no',sharesInIspc:'no',sharesAnonymous:'no',otherActivities:'no',generalRegimeChosen:'no',...patch};return{d,b:{version:1,input}};}
|
|
const evaluate=patch=>{const{d,b}=fixture(patch);return recordIspcEligibility(d,b).result;};
|
|
test('reuses only valid person/activity/establishments;does not invent activity category,prior annual volume or option',()=>{const d={person_type:'sole_trader',fiscal_activity:'Actividade conhecida',fiscal_establishments:2,currency:'MZN',annual_sales:'3000000',fiscal_turnover:'3000000'};const i=newIspcEligibilityInput(d);assert.equal(i.personType,'singular');assert.equal(i.establishments,'2');assert.equal(i.activityDescription,'Actividade conhecida');assert.deepEqual(i.activities,[]);assert.equal(i.annualReference,'');assert.equal(i.option,'preparation');assert.equal(newIspcEligibilityInput({...d,person_type:'consortium'}).personType,'');});
|
|
test('2025reference4000000inclusive is compatible;optative choice remains preparation;foreign investor does not imply foreign operation',()=>{const{d,b}=fixture();d.nationality='estrangeira';const r=recordIspcEligibility(d,b).result;assert.equal(r.status,'compatible',r.reason);assert.equal(r.annualReference.numerator,'4000000');assert.equal(r.optionStatus,'preparation');assert.match(r.optionReason,/não é adesão/);assert.equal(evaluate({annualReference:'4000000.000001'}).status,'incompatible');assert.equal(evaluate({annualReference:''}).status,'indeterminate');assert.equal(evaluate({annualReference:'0'}).status,'compatible');});
|
|
test('known statutory exclusions are specific and do not require filling irrelevant remaining inputs',()=>{for(const patch of [{organizedRequired:'yes'},{sharesInIspc:'yes'},{sharesAnonymous:'yes'},{otherActivities:'yes'},{activities:['other']},{establishments:'2'},{territory:'no'}])assert.equal(evaluate({...patch,annualReference:''}).status,'incompatible',JSON.stringify(patch));for(const field of ['organizedRequired','sharesInIspc','sharesAnonymous','otherActivities','generalRegimeChosen'])assert.equal(evaluate({[field]:''}).status,'indeterminate',field);});
|
|
test('liberal183days versus184;8b services do not inherit the8c duration rule;inapplicable retained facts do not become exclusions',()=>{const p={activities:['liberal15'],unlistedServices:'no',liberalDaysSameEntity:'183',liberalClientRef:'SYNTHETIC QA maior duração do ano'};assert.equal(evaluate(p).status,'compatible');assert.equal(evaluate({...p,liberalDaysSameEntity:'184'}).status,'incompatible');assert.equal(evaluate({...p,liberalDaysSameEntity:''}).status,'indeterminate');assert.equal(evaluate({...p,liberalDaysSameEntity:'367'}).status,'indeterminate');assert.equal(evaluate({...p,activities:['services12'],liberalDaysSameEntity:'184'}).status,'compatible');assert.equal(evaluate({...p,activities:['commerce'],unlistedServices:'yes',liberalDaysSameEntity:'184'}).status,'compatible');assert.equal(evaluate({...p,activities:['commerce','liberal15'],liberalDaysSameEntity:'184'}).status,'incompatible');});
|
|
test('startup forecast has its own2026basis and AT confirmation;projected assumption and effective reference stay distinct',()=>{const p={basis:'start_forecast',referenceYear:'2026',annualReference:'1000000'};assert.equal(evaluate(p).status,'indeterminate');assert.equal(evaluate({...p,forecastConfirmed:'yes'}).status,'compatible');assert.equal(evaluate({...p,origin:'effective',forecastConfirmed:'yes'}).status,'indeterminate');assert.equal(evaluate({...p,origin:'effective',forecastConfirmed:'yes',forecastConfirmationRef:'SYNTHETIC QA confirmaçãoAT'}).status,'compatible');assert.equal(evaluate({...p,referenceYear:'2025',forecastConfirmed:'yes',annualReference:'5000000'}).status,'indeterminate');assert.equal(evaluate({basis:'',referenceYear:'',annualReference:'5000000'}).status,'indeterminate');});
|
|
test('three-year general-regime commitment is explicit;no new approver or assumption from an empty field',()=>{const p={generalRegimeChosen:'yes',generalThreeYearsCompleted:'no'};assert.equal(evaluate(p).status,'incompatible');assert.equal(evaluate({...p,generalThreeYearsCompleted:'yes'}).status,'indeterminate');assert.equal(evaluate({...p,generalThreeYearsCompleted:'yes',generalRegimeRef:'SYNTHETIC QA opção e período cumprido'}).status,'compatible');assert.equal(evaluate({generalRegimeChosen:'no',generalThreeYearsCompleted:'no'}).status,'compatible');});
|
|
test('documented option is separate from eligibility and cannot be inferred from selectingISPC',()=>{const p={option:'opted'};let r=evaluate(p);assert.equal(r.status,'compatible');assert.equal(r.optionStatus,'indeterminate');r=evaluate({...p,optionReference:'SYNTHETIC QA opção',optionDate:'2025-12-31'});assert.equal(r.optionStatus,'recorded');assert.equal(evaluate({...p,optionReference:'x',optionDate:'2026-02-01'}).optionStatus,'indeterminate');assert.equal(evaluate({option:'not_opted'}).optionStatus,'not_opted');});
|
|
test('wrong currency/year and occasional scope remain indeterminate rather than zero or invented ineligibility',()=>{for(const patch of [{currency:'USD'},{currency:''},{assessmentDate:'2025-12-31'},{assessmentDate:'2026-02-30'},{assessmentDate:'2027-01-01'},{mode:'occasional'},{personType:''},{referenceYear:'2026'},{establishments:''}])assert.equal(evaluate(patch).status,'indeterminate',JSON.stringify(patch));});
|
|
test('save/recovery preserves all prior fiscal maps;deliberate edits keep frozen report and append history only on calculation',()=>{const{d,b}=fixture(),before=JSON.parse(d.modelo_a_snapshot);let book=recordIspcEligibility(d,b,'2026-10-25T14:00:00Z');d.modelo_a_snapshot=saveIspcEligibilityBook(d,book);for(const[k,v]of Object.entries(before))assert.deepEqual(JSON.parse(d.modelo_a_snapshot)[k],v,k);assert.ok(ispcEligibilityCurrent(d,book));const first=structuredClone(book.result);book.input.activityDescription='Deliberate future edit';d.modelo_a_snapshot=saveIspcEligibilityBook(d,book);assert.equal(ispcEligibilityCurrent(d,book),false);assert.doesNotMatch(ispcEligibilityReportRows(d).flat().join(' '),/Deliberate future edit/);book=recordIspcEligibility(d,book);assert.deepEqual(book.history.at(-1),first);d.modelo_a_snapshot=saveIspcEligibilityBook(d,book);assert.deepEqual(ispcEligibilityBook(JSON.parse(JSON.stringify(d))),book);});
|
|
test('reuse differences are reviewable;new profile values do not overwrite annual amounts,option or deliberate edits',()=>{const{d,b}=fixture();b.input.activityDescription='Deliberate activity';b.input.option='not_opted';const diff=ispcReuseDiff({...d,fiscal_establishments:'2',fiscal_activity:'New profile activity'},b);assert.equal(b.input.establishments,'1');assert.equal(b.input.activityDescription,'Deliberate activity');assert.ok(diff.some(v=>v.field==='establishments'&&v.after==='2'));assert.ok(diff.some(v=>v.field==='activityDescription'));assert.ok(!('annualReference'in ispcReuseValues({...d,annual_sales:'9000000'})));assert.equal(b.input.option,'not_opted');});
|
|
test('malformed books and ambiguous opportunity are preserved errors,not silently empty preparations',()=>{const{d,b}=fixture();b.input.activities=['commerce','commerce'];assert.throws(()=>saveIspcEligibilityBook(d,b),/não recuperáveis/);assert.throws(()=>ispcEligibilityBook({...d,modelo_a_snapshot:JSON.stringify({version:1,books:{},ispcEligibility:[]})}),/não recuperável/);assert.throws(()=>ispcEligibilityBook({...d,context_opportunity:'',context_applicability_snapshot:JSON.stringify({opportunity_choices:['a','b']})}),/Escolha/);});
|
|
test('export synthetic eligibility book for isolated private persistence and actual component proof',()=>{const{d,b}=fixture({annualReference:'2500000'});let book=recordIspcEligibility(d,b,'2026-10-25T14:00:00Z');book=recordIspcEligibility(d,book,'2026-10-25T14:01:00Z');d.modelo_a_snapshot=saveIspcEligibilityBook(d,book);assert.equal(book.result.status,'compatible');assert.equal(book.result.optionStatus,'preparation');if(process.env.L4A_ISPC_OUTPUT)fs.writeFileSync(process.env.L4A_ISPC_OUTPUT,JSON.stringify(d));});
|