40 lines
3.2 KiB
JavaScript
40 lines
3.2 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import vm from 'node:vm';
|
|
import {readFileSync} from 'node:fs';
|
|
import {createRequire} from 'node:module';
|
|
const require=createRequire(import.meta.url);
|
|
const source=readFileSync(new URL('../apps/browser/main.cjs',import.meta.url),'utf8');
|
|
const hook=source.slice(source.indexOf(" browserSession.webRequest.onBeforeSendHeaders("),source.indexOf(' // Session request, header and permission gates'));
|
|
function fixture({auditFails=false}={}){
|
|
let listener,completeScan;
|
|
const timers=[],callbacks=[],events=[];
|
|
const policy={expiresAt:new Date(Date.now()+60000).toISOString(),dlp:{maxBytes:65536,semantic:{enabled:false}},security:{yara:{enabled:false}}};
|
|
const context=vm.createContext({require:specifier=>require('../apps/browser/'+specifier.slice(2)),credentialBroker:undefined,credentialRequestCorrelations:new Map(),currentTabContext:()=>true,URL,Date,ready:true,policy,localInspector:null,
|
|
browserSession:{webRequest:{onBeforeSendHeaders(_filter,fn){listener=fn;}}},
|
|
developerAssetRequestAllowed:()=>false,tabs:{all:()=>[]},core:{destinationAllowed:()=>true,inspect:()=>({decision:'allow'})},
|
|
diagnosticSpan:(_name,_attrs,fn)=>fn(),audit:async(...args)=>{events.push(args);if(auditFails)throw Error('fixture persistence failure');},
|
|
scanEnterprise:()=>new Promise(resolve=>{completeScan=resolve;}),setTimeout:fn=>{timers.push(fn);return timers.length;},clearTimeout(){},
|
|
});
|
|
vm.runInContext(source.slice(source.indexOf('function agentRequestOwnerAllowed(source)'),source.indexOf('function actorDestinationAllowed')),context);
|
|
vm.runInContext(source.slice(source.indexOf('function requestDiagnostic('),source.indexOf('function credentialContext(')),context);
|
|
vm.runInContext(hook,context);
|
|
listener({url:'https://example.test/path',requestHeaders:{X:'public'},webContentsId:0,resourceType:'xhr'},response=>callbacks.push(response));
|
|
return {timers,callbacks,events,context,finish:()=>completeScan({decision:'allow',coverage:{complete:true}})};
|
|
}
|
|
const settle=async()=>{for(let n=0;n<8;n++)await Promise.resolve();};
|
|
test('native header deadline cancels once, records static audit reason and refuses late scanner approval',async()=>{
|
|
const f=fixture();await settle();assert.equal(f.callbacks.length,0);
|
|
f.timers[0]();await settle();assert.equal(f.callbacks.length,1);assert.equal(f.callbacks[0].cancel,true);
|
|
assert.deepEqual(f.events,[['dlp.block','headers-inspection-timeout','example.test']]);
|
|
f.timers[0]();f.finish();await settle();assert.equal(f.callbacks.length,1);assert.equal(f.events.length,1);
|
|
});
|
|
test('audit failure cannot release a timed-out request or create unhandled rejection',async()=>{
|
|
const f=fixture({auditFails:true});await settle();f.timers[0]();await settle();f.finish();await settle();
|
|
assert.equal(f.callbacks.length,1);assert.equal(f.callbacks[0].cancel,true);assert.equal(f.events.length,1);
|
|
});
|
|
test('completed header approval is not later relabelled as a timeout',async()=>{
|
|
const f=fixture();await settle();f.finish();await settle();assert.equal(f.callbacks.length,1);assert.equal(f.callbacks[0].cancel,false);
|
|
f.timers[0]();await settle();assert.equal(f.callbacks.length,1);assert.equal(f.events.length,0);
|
|
});
|