← back to Newmor Onboard

scripts/test-asset-transition.mjs

25 lines

import assert from 'node:assert/strict';
import fs from 'node:fs';
import {hash,transition} from './asset-transition.mjs';
const root='/Users/macstudio3/Projects/newmor-onboard';
const plan=JSON.parse(fs.readFileSync(root+'/data/live-2026-09-09/theme-change-plan.json'));
const checks=[];
for(const p of plan.changes){
 const before=fs.readFileSync(root+'/data/live-2026-09-09/theme/'+p.key,'utf8');
 const after=fs.readFileSync(root+'/theme-work/'+p.key,'utf8');
 let storage=before,writes=0;
 const config=()=>({current:storage,wanted:after,sourceHash:p.before_sha256,targetHash:p.after_sha256,apply:true,write:async s=>{storage=s;writes++},readback:async()=>storage});
 assert.equal(await transition({...config(),apply:false}),'dry-run');assert.equal(writes,0);
 await assert.rejects(transition({...config(),wanted:after+'drift'}),/target bytes/);assert.equal(writes,0);
 await assert.rejects(transition({...config(),current:before+'drift'}),/Concurrent/);assert.equal(writes,0);
 assert.equal(await transition(config()),'verified');assert.equal(storage,after);
 assert.equal(await transition(config()),'already-correct');assert.equal(writes,1);
 await assert.rejects(transition({...config(),current:before,write:async()=>{throw Error('simulated second-asset failure')}}),/simulated/);
 // Following a partial batch failure, reverse the already applied asset with the actual transition function.
 assert.equal(await transition({...config(),wanted:before,sourceHash:p.after_sha256,targetHash:p.before_sha256}),'verified');
 assert.equal(storage,before);assert.equal(writes,2);
 checks.push({key:p.key,result:'PASS',checks:['dry-run','target drift','source drift','apply','idempotent retry','partial batch failure','rollback persisted bytes']});
}
fs.writeFileSync(root+'/verification/asset-rollback-rehearsal.json',JSON.stringify({timestamp:new Date().toISOString(),checks},null,2)+'\n');
console.log(`PASS: actual transition apply/rollback + drift/idempotency/failure checks for all ${checks.length} assets`);