// Synthetic publication check. Uses only Node standard-library modules.
const http = require('node:http');
const fs = require('node:fs');
const path = require('node:path');
const crypto = require('node:crypto');
const assert = require('node:assert/strict');
const output = path.resolve(process.argv[2] || path.join(__dirname, 'result'));
const sha = value => crypto.createHash('sha256').update(value).digest('hex');
const now = () => new Date().toISOString();
const approved = {version:'weekly-report-v2',title:'Export a weekly report',instruction:'Select Last seven days before exporting.',link:{href:'/help/date-range/',text:'Date-range help'},media:{label:'A report limited to seven days',svg:''}};
const old = {...approved,version:'weekly-report-v1',instruction:'Select All dates before exporting.'};
const css = 'body{margin:0;background:#fafaf8;color:#182433;font:18px/1.6 system-ui,sans-serif}main{max-width:700px;margin:36px auto;padding:0 18px}aside{font-size:14px;color:#536173;border-bottom:1px solid #ccd4db;padding-bottom:12px}h1{font-size:32px;line-height:1.2}figure{max-width:360px;margin:24px 0}svg{width:100%;height:auto}a{color:#125b94}pre{white-space:pre-wrap;overflow-wrap:anywhere;background:#edf0f4;padding:12px;font:13px/1.5 monospace}';
const render = (record) => `
${record.title}${record.title}
${record.instruction}
${record.link.text}
${record.media.svg}\n`;
const approvedHtml = render(approved);
let cachedBody = render(old);
const requests = [];
const events = [];
const server = http.createServer((req,res) => {
requests.push({at:now(),method:req.method,path:req.url,authorization_present:!!req.headers.authorization,cookie_present:!!req.headers.cookie});
const send = (status,body,type='text/html; charset=utf-8',headers={}) => {res.writeHead(status,{'Content-Type':type,...headers});res.end(body)};
if(req.method==='GET' && req.url==='/mock-cms/posts/42') return send(200,JSON.stringify({fixture_only:true,provider:'synthetic-local-cms',id:42,status:'publish',link:'/weekly-report/',version:approved.version}),'application/json');
if(req.method==='GET' && req.url==='/preview/42') return send(200,approvedHtml);
if(req.method==='GET' && req.url==='/weekly-report/') {
const hit=cachedBody!==null;
if(!hit) cachedBody=approvedHtml;
return send(200,cachedBody,'text/html; charset=utf-8',{'Cache-Control':'public, max-age=60','X-Fixture-Cache':hit?'HIT':'MISS'});
}
if(req.method==='POST' && req.url==='/fixture/invalidate') {
cachedBody=null;
events.push({at:now(),action:'Clear only this local fixture cache',path:'/weekly-report/'});
return send(200,JSON.stringify({fixture_only:true,cleared:'/weekly-report/'}),'application/json');
}
if(req.method==='GET' && req.url==='/help/date-range/') return send(200,'Use Last seven days for this synthetic weekly report.','text/plain; charset=utf-8');
send(404,'Not found','text/plain; charset=utf-8');
});
function request(url,method='GET') {
return new Promise((resolve,reject) => {
const started=now();
const req=http.request(url,{method,headers:{Accept:'*/*'},agent:false},res=>{
const chunks=[];
res.on('data',chunk=>chunks.push(chunk));
res.on('end',()=>{const body=Buffer.concat(chunks).toString('utf8');resolve({started_at:started,completed_at:now(),url,method,status:res.statusCode,headers:res.headers,body,body_sha256:sha(body)})});
});
req.on('error',reject);req.end();
});
}
function inspect(html,base) {
// A deliberately small parser for this fixed fixture, not a general HTML verifier.
const title=html.match(/([^<]*)<\/title>/)?.[1];
const heading=html.match(/([^<]*)<\/h1>/)?.[1];
const instruction=html.match(/
([^<]*)<\/p>/)?.[1];
const link=html.match(/([^<]*)<\/a>/);
const media=html.match(/