Regista aceitacao funcional do primeiro incremento PGC-NIRF e preserva as dependencias documentais e tecnicas existentes. A validacao do calculo fiscal continua separada e pendente. Sem credenciais, bases operacionais ou publicacao.
39 lines
4.9 KiB
JavaScript
39 lines
4.9 KiB
JavaScript
import fs from 'node:fs/promises';
|
|
import assert from 'node:assert/strict';
|
|
import { randomUUID } from 'node:crypto';
|
|
|
|
const fixture = JSON.parse(await fs.readFile('C:/laragon/data/sgf-tempo/secrets/browser-fixture.json','utf8'));
|
|
const base = 'http://127.0.0.1:8001';
|
|
function client() {
|
|
const cookies = new Map(); let csrf = '', context = '';
|
|
return {
|
|
async request(path, method = 'GET', body, token = context) {
|
|
const response = await fetch(base + path, { method, headers: { Accept:'application/json','Content-Type':'application/json',Cookie:[...cookies].map(([k,v]) => `${k}=${v}`).join('; '),'X-CSRF-TOKEN':csrf,'X-SGF-Context':token,'Idempotency-Key':randomUUID() },...(body === undefined ? {} : {body:JSON.stringify(body)}) });
|
|
for (const cookie of response.headers.getSetCookie()) { const pair=cookie.split(';',1)[0], split=pair.indexOf('='); cookies.set(pair.slice(0,split),pair.slice(split+1)); }
|
|
const data=await response.json().catch(() => ({})); if(data.csrf)csrf=data.csrf;if(data.context?.token)context=data.context.token;
|
|
return {status:response.status,data,cache:response.headers.get('cache-control')};
|
|
},
|
|
async login(email) {await this.request('/api/session');assert.equal((await this.request('/api/login','POST',{email,password:fixture.password})).status,200);return this.select();},
|
|
async select(unit=fixture.unit) {const response=await this.request('/api/context','POST',{tenant_id:fixture.tenant,company_id:fixture.company,unit_id:unit});assert.equal(response.status,200);return response.data.context.token;}
|
|
};
|
|
}
|
|
const manager=client(),reader=client();await manager.login('gestor@example.test');await reader.login('consulta@example.test');
|
|
const path=`/api/document-preview/draft/${fixture.document_draft_id}`;
|
|
const first=await manager.request(path);assert.equal(first.status,200);assert.ok(first.cache.includes('no-store'));assert.equal(first.data.notice,'RASCUNHO — SEM VALIDADE FISCAL');assert.equal(first.data.base_amount,'0.0000000125');assert.equal(first.data.data.currency,null);assert.ok(first.data.pending.tax_rule_pending);
|
|
const model={version:0,show_logo:false,show_contacts:true,show_observations:true,show_payment_instructions:false,contact_text:'Contactos sintéticos da empresa',observations:'Observações iniciais da demonstração'};
|
|
assert.equal((await manager.request('/api/document-preview/model','PATCH',model)).status,200);
|
|
const revision=await manager.request(path+'/revision');assert.equal(revision.status,200);assert.notEqual(revision.data.revision,first.data.revision);assert.equal(Object.keys(revision.data).join(','),'revision');
|
|
const refreshed=await manager.request(path);assert.equal(refreshed.data.observations,model.observations);assert.equal(refreshed.data.payments.length,0);assert.equal(refreshed.data.notice,first.data.notice);assert.ok(refreshed.data.pending.tax_rule_pending);
|
|
assert.equal((await reader.request(path)).status,200);assert.equal((await reader.request('/api/document-preview/model','PATCH',{...model,version:1})).status,403);
|
|
assert.equal((await manager.request('/api/document-preview/model','PATCH',{...model,version:1,show_notice:false})).status,422);
|
|
assert.equal((await manager.request('/api/document-preview/model','PATCH',model)).status,409);
|
|
const oldContext=await manager.select();await manager.select(null);assert.equal((await manager.request('/api/document-preview/model','PATCH',{...model,version:1},oldContext)).status,409);await manager.select();
|
|
const list=await manager.request('/api/a/billing_drafts');const confirmed=list.data.records.find(record=>record.internal_confirmation);
|
|
assert.ok(confirmed);const historyPath=`/api/document-preview/history/${confirmed.id}`;
|
|
const history=await manager.request(historyPath);assert.equal(history.status,200);assert.equal(history.data.contacts,null);assert.equal(history.data.issuer.name,null);
|
|
assert.equal((await manager.request('/api/document-preview/model','PATCH',{...model,version:1,observations:'Observações para a prova no navegador'})).status,200);
|
|
const historyAfter=await manager.request(historyPath);assert.equal(historyAfter.data.revision,history.data.revision);assert.equal(historyAfter.data.contacts,null);
|
|
await manager.request('/api/logout','POST');await reader.request('/api/logout','POST');
|
|
await fs.writeFile('docs/proofs/preview-http-results.json',JSON.stringify({database:'sgf_tempo_test',real_synthetic_login:true,results:['Read-only composition reuses exact values and unknown currency; no-store headers.', 'Revision changes after configuration; explicit new read loads new values.', 'Reader consults but cannot configure (403); hidden mandatory content rejected (422).', 'Old configuration version and context rejected (409).', 'Historical consultation is independent of current configuration and does not reconstruct missing issuer name.'],instruction_values:'omitted'},null,2));
|
|
console.log('Isolated preview HTTP proof passed; instruction values omitted.');
|