Files
safetynet/tests/windows-package-plan.test.mjs

43 lines
3.0 KiB
JavaScript

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);
});