| 1234567891011121314151617181920212223242526272829303132333435 |
- import fs from 'node:fs';
- import path from 'node:path';
- import crypto from 'node:crypto';
- import assert from 'node:assert/strict';
- import { publishFiles } from '../work/board-deploy-20261106-r1/package/scripts/publish-board.mjs';
- const base=path.resolve('work/board-deploy-20261106-r1');
- const pkg=path.join(base,'package'),sourceDir=path.join(pkg,'payload'),manifestPath=path.join(pkg,'deploy/board-files.json');
- const manifest=JSON.parse(fs.readFileSync(manifestPath));
- const targetDir=fs.mkdtempSync(path.join(base,'static-publish-test-'));
- for(const f of manifest.files){const p=path.join(targetDir,f.path);fs.mkdirSync(path.dirname(p),{recursive:true});fs.copyFileSync(path.join(sourceDir,f.path),p);}
- fs.copyFileSync(path.join(base,'production-index.html'),path.join(targetDir,'index.html'));
- const nav=path.join(targetDir,'src/layout/kf-nav.js');
- fs.copyFileSync(path.join(base,'production-before/src/layout/kf-nav.js'),nav);
- fs.unlinkSync(path.join(targetDir,'src/core/library.js'));
- const snapshot=()=>Object.fromEntries(['index.html',...manifest.files.map(f=>f.path)].map(p=>{const f=path.join(targetDir,p);return[p,fs.existsSync(f)?crypto.createHash('sha256').update(fs.readFileSync(f)).digest('hex'):null];}));
- const options={sourceDir,manifestPath,targetDir},before=snapshot();
- const plan=publishFiles(options);
- assert.equal(plan.readOnly,true);assert.equal(plan.filesChecked,71);assert.equal(plan.changes.length,2);assert.deepEqual(snapshot(),before);
- let thrown;
- try{publishFiles({...options,apply:true},{beforeWrite:p=>{if(p==='src/layout/kf-nav.js')throw Error('simulated filesystem failure');}});}catch(e){thrown=e;}
- assert.equal(thrown?.rollbackComplete,true);assert.deepEqual(snapshot(),before);
- fs.writeFileSync(nav,'unknown concurrent revision');
- assert.throws(()=>publishFiles({...options,apply:true}),{code:'UNKNOWN_TARGET_CONTENT'});
- assert.equal(fs.readFileSync(nav,'utf8'),'unknown concurrent revision');
- fs.copyFileSync(path.join(base,'production-before/src/layout/kf-nav.js'),nav);
- const applied=publishFiles({...options,apply:true});
- assert.equal(applied.filesystemVerified,true);assert.equal(applied.homepageModified,false);assert.ok(!applied.backup.startsWith(targetDir+path.sep));
- const stamp=fs.statSync(nav).mtimeMs,after=snapshot();
- assert.equal(publishFiles({...options,apply:true}).changes.length,0);assert.equal(fs.statSync(nav).mtimeMs,stamp);assert.deepEqual(snapshot(),after);
- fs.writeFileSync(path.join(targetDir,'index.html'),'changed homepage');
- assert.throws(()=>publishFiles(options),{code:'HOMEPAGE_MISMATCH'});
- const result={ok:true,checks:['dry run writes nothing','failure restores changed and newly created files','unknown target revision is preserved','apply verifies all 71 files and preserves homepage','repeat is a no-op preserving mtime','changed homepage is refused'],productionWrites:0};
- fs.writeFileSync(path.join(base,'static-publisher-validation.json'),JSON.stringify(result,null,2));
- console.log(JSON.stringify(result));
|