Files
SGF/scripts/sgf-module-dropdown-check.mjs
2026-11-11 09:00:17 +02:00

5 lines
3.3 KiB
JavaScript

import fs from'node:fs';import assert from'node:assert/strict';import{createRequire}from'node:module';import{pathToFileURL}from'node:url';import React from'react';import{renderToStaticMarkup}from'react-dom/server';import{transformWithOxc}from'vite';
const require=createRequire(import.meta.url),source=fs.readFileSync('resources/js/ModuleNavigation.jsx','utf8'),compiled=await transformWithOxc(source,'ModuleNavigation.jsx',{jsx:{runtime:'classic'}});const code=compiled.code.replace(/from ["']react["']/, 'from '+JSON.stringify(pathToFileURL(require.resolve('react')).href));const {default:Navigation,moduleFunctionAllowed}=await import('data:text/javascript;base64,'+Buffer.from(code).toString('base64'));
const modules=['commercial','purchasing','stock','workshop','finance','accounting'].map(id=>({id,label:id})),groups=[{id:'services',label:'Clientes',items:[{id:'clients',label:'Clientes'}]},{id:'purchasing',label:'Compras',items:[{id:'purchasing_home',label:'Percurso de Compras'}]},{id:'stock',label:'Stock',items:[{id:'stock_balances',label:'Existências'}]},{id:'workshop',label:'Oficinas',items:[{id:'workshop',label:'Ordens'}]},{id:'treasury',label:'Financeiro',items:[{id:'native_payables',label:'Obrigações'}]},{id:'accounting',label:'Contabilidade',items:[{id:'accounting_panel',label:'Diário'}]}];const context={module_id:'stock',modules,single_installation:true};const html=renderToStaticMarkup(React.createElement(Navigation,{groups,context,page:'stock_balances',user:{name:'QA'},navigate(){},openPage(){},logout(){},busy:false}));const checks=[],ok=(v,n)=>{assert(v,n);checks.push(n);};ok((html.match(/name="sgf-modules"/g)??[]).length===6,'six horizontal module dropdowns');ok(html.includes('Funções de stock')&&html.includes('Funções de accounting'),'each module owns its function panel');ok(html.includes('aria-current="page"'),'current function highlighted');ok(!html.includes('Módulo activo<select'),'duplicated module selector removed');ok(moduleFunctionAllowed(context,groups,'finance','native_payables'),'explicit Finance function accepted');ok(!moduleFunctionAllowed(context,groups,'commercial','native_payables'),'Finance function cannot be attributed to Commercial');ok(!moduleFunctionAllowed({...context,modules:modules.filter(m=>m.id!=='finance')},groups,'finance','native_payables'),'unavailable module refuses function even when listed elsewhere');ok(moduleFunctionAllowed(context,groups,'stock','clients'),'shared client choice remains explicitly in the selected module');ok(!moduleFunctionAllowed(context,groups,'stock','unknown'),'unknown page refused');
const limited=renderToStaticMarkup(React.createElement(Navigation,{groups,context:{...context,modules:[modules[2]]},page:'stock_balances',user:{name:'QA'},navigate(){},openPage(){},logout(){},busy:true}));ok((limited.match(/name="sgf-modules"/g)??[]).length===1,'limited identity sees one authorised module');ok(limited.includes('disabled=""'),'in-progress operation disables function actions');const run=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')),file=run.root+'/private/receipt-composition-cc50a276c10c/module-dropdown-render-20261110.json';fs.writeFileSync(file,JSON.stringify({passed:true,checks,browser_visual_review:false,business_commands:0,context_transition_guards_reused:true},null,2));console.log(JSON.stringify({passed:true,checks:checks.length,proof:file}));