import test from 'node:test'; import assert from 'node:assert/strict'; import path from 'node:path'; import {createWindowsPackagePlan} from '../scripts/windows-package-plan.mjs'; const root=path.resolve('.'),options={workspace:root,outputDirectory:path.join(root,'dist'),electronDirectory:path.join(root,'node_modules/electron/dist'),platform:'win32'}; const expected={sourceSha256:'a'.repeat(64),runtimeSha256:'b'.repeat(64),packageSha256:'c'.repeat(64)}; const receipt={identity:expected,fuses:true,resources:true,broker:true,runtimeAcl:true}; test('unpacked and verified NSIS stages use distinct official CLI commands',async()=>{ const plan=createWindowsPackagePlan(options); assert.ok(plan.unpacked.args.includes('--dir')); assert.deepEqual(plan.verification.required,['fuses','resources','broker','runtimeAcl']); const installer=await plan.installer({expectedIdentity:expected,readIdentity:async()=>expected,verify:async()=>receipt}); assert.deepEqual(installer.args.slice(0,4),['--win','nsis','--prepackaged',plan.unpacked.directory]); assert.equal(installer.args.includes('--dir'),false); assert.deepEqual(installer.args.slice(-2),['--publish','never']); assert.equal(Object.isFrozen(installer.args),true); }); test('every security verification gate is mandatory before installer planning',async()=>{ const plan=createWindowsPackagePlan(options); for(const key of ['fuses','resources','broker','runtimeAcl'])await assert.rejects(plan.installer({expectedIdentity:expected,readIdentity:async()=>expected,verify:async()=>({...receipt,[key]:false})}),{code:'package_verification_incomplete'}); }); test('missing verification callbacks cannot authorize an installer',async()=>{ await assert.rejects(createWindowsPackagePlan(options).installer({expectedIdentity:expected}),{code:'package_verifier_required'}); }); test('source runtime and package identity changes each prevent reuse',async()=>{ const plan=createWindowsPackagePlan(options); for(const key of Object.keys(expected)){ let reads=0; await assert.rejects(plan.installer({expectedIdentity:expected,readIdentity:async()=>++reads===1?expected:{...expected,[key]:'d'.repeat(64)},verify:async()=>receipt}),{code:'package_identity_changed'}); await assert.rejects(plan.installer({expectedIdentity:expected,readIdentity:async()=>expected,verify:async()=>({...receipt,identity:{...expected,[key]:'d'.repeat(64)}})}),{code:'package_verification_incomplete'}); } }); test('outside output malformed branding and unsupported platform are rejected',()=>{ for(const override of [{outputDirectory:path.dirname(root)},{outputDirectory:root},{productName:'bad\nname'},{appId:'bad'},{platform:'linux'}]){ assert.throws(()=>createWindowsPackagePlan({...options,...override})); } }); test('failed verifier remains a failure rather than a distributable result',async()=>{ const failure=new Error('synthetic verifier failure'); await assert.rejects(createWindowsPackagePlan(options).installer({expectedIdentity:expected,readIdentity:async()=>expected,verify:async()=>{throw failure;}}),error=>error===failure); });