Files
SGF/scripts/accounting-menu-check.mjs
T
2026-10-29 22:42:37 +02:00

37 lines
3.8 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import React from 'react';
import {renderToStaticMarkup} from 'react-dom/server';
import {createServer} from 'vite';
const vite=await createServer({server:{middlewareMode:true},appType:'custom'});
try{
const {accountingSections,accountingFunctions,accountingReports,visibleAccountingSections,filterAccountingReports}=await vite.ssrLoadModule('/resources/js/accounting-menu.js');
const {default:Workspace}=await vite.ssrLoadModule('/resources/js/AccountingMenuWorkspace.jsx');
const {navigationGroups}=await vite.ssrLoadModule('/resources/js/WorkspaceNavigation.jsx');
const context={token:'synthetic',company:{id:1,name:'Empresa sintética A'},unit:{id:7,name:'Unidade A'}};
const companyCan=p=>p==='company.view';
assert.equal(accountingSections.length,6);assert.equal(accountingFunctions.length,11);assert.equal(accountingReports.length,24);
assert.deepEqual(visibleAccountingSections(()=>false),[]);assert.deepEqual(visibleAccountingSections(p=>p==='access.manage'),[]);
assert.equal(visibleAccountingSections(p=>p==='catalogue_accounting.view').length,6);
const group=navigationGroups(companyCan,7).find(g=>g.id==='accounting');assert.equal(group.items.length,6);assert(group.items.every(i=>i.informational));
assert(!group.items.some(i=>i.id==='catalogue_accounting'));
const accountantCan=p=>companyCan(p)||p==='catalogue_accounting.view';
assert(navigationGroups(accountantCan,7).find(g=>g.id==='accounting').items.some(i=>i.id==='catalogue_accounting'));
assert(filterAccountingReports('depreciacoes').some(r=>r.id==='assets'));
assert(filterAccountingReports('fornecedores','Tesouraria').some(r=>r.id==='suppliers'));
assert.deepEqual(filterAccountingReports('fornecedores','Pessoal'),[]);
for(const section of accountingSections){
const render=can=>renderToStaticMarkup(React.createElement(Workspace,{section:section.id,context,can,navigate:()=>{}}));
const html=render(companyCan);assert(html.includes('Submenus de contabilidade'));assert(html.includes('Empresa sintética A'));
assert(!html.includes('<form'));assert(!html.includes('type="submit"'));assert(!html.includes('0.00 MZN'));
assert(!html.includes('Abrir plano e classificação existentes'));assert(!html.includes('Abrir recebimentos e reconciliação de teste'));
if(section.id==='accounting_configuration')assert(render(accountantCan).includes('Abrir plano e classificação existentes'));
const differentUnit=(p,u=null)=>p==='company.view'||(p==='service_receivables.view'&&u===8);
assert(!render(differentUnit).includes('Abrir recebimentos e reconciliação de teste'));
const other=renderToStaticMarkup(React.createElement(Workspace,{section:section.id,context:{...context,company:{id:2,name:'Empresa sintética B'}},can:companyCan,navigate:()=>{}}));assert(!other.includes('Empresa sintética A'));
}
const denied=renderToStaticMarkup(React.createElement(Workspace,{section:'accounting_panel',context,can:()=>false,navigate:()=>{}}));assert(!denied.includes('Submenus de contabilidade'));
await fs.writeFile('docs/proofs/accounting-menu.json',JSON.stringify({checked_at:new Date().toISOString(),sections:6,function_definitions:11,report_definitions:24,existing_paths_preserved:true,links_permission_scoped:true,unit_scoped_links_checked:true,no_permissions_assigned_by_profile:true,no_fabricated_financial_balances:true,report_search_checked:true,business_commands:0,backend_calls:0,visual_review:false,publication:false},null,2)+'\n');
console.log('Accounting menu passed: six groups, eleven functions, 24 report definitions, permission/unit scoped links, report search and no fabricated balances or business commands.');
}finally{await vite.close();}