import {test} from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs/promises'; import path from 'node:path'; import os from 'node:os'; import http from 'node:http'; import {manifestFor,verifyRelease} from '../release-admin-web.mjs'; async function fixture(t){ const dir=await fs.mkdtemp(path.join(os.tmpdir(),'xiaoshu-admin-release-')); t.after(()=>fs.rm(dir,{recursive:true,force:true})); await fs.writeFile(path.join(dir,'index.html'),''); await fs.writeFile(path.join(dir,'main-ABC.js'),'console.log("admin");'); const manifest=await manifestFor(dir,'test-release','source-commit'); await fs.writeFile(path.join(dir,'deployment-version.json'),JSON.stringify(manifest)); return{dir,manifest}; } async function server(t,dir,override){ const app=http.createServer(async(req,res)=>{ try{ const url=new URL(req.url,'http://localhost'),name=url.pathname.slice(1); const body=override?.(name); if(body!==undefined){res.setHeader('Content-Type','text/html');res.end(body);return;} const file=name.startsWith('admin/')?'index.html':name; res.setHeader('Content-Type',file.endsWith('.html')?'text/html':file.endsWith('.json')?'application/json':'text/javascript'); res.end(await fs.readFile(path.join(dir,file))); }catch{res.statusCode=404;res.end('missing');} }); await new Promise(resolve=>app.listen(0,'127.0.0.1',resolve)); t.after(()=>new Promise(resolve=>app.close(resolve))); return'http://127.0.0.1:'+app.address().port; } test('核对文件哈希和登录/工资深层路由,不能只凭首页成功判断发布成功',async t=>{ const {dir,manifest}=await fixture(t),url=await server(t,dir); assert.equal((await verifyRelease(url,manifest)).filesVerified,2); await fs.writeFile(path.join(dir,'main-ABC.js'),'old build'); await assert.rejects(verifyRelease(url,manifest),/文件校验失败/); }); test('拒绝版本仍旧或深层路由返回其他页面的发布',async t=>{ const {dir,manifest}=await fixture(t),url=await server(t,dir,name=>name==='admin/payroll'?'old index':undefined); await assert.rejects(verifyRelease(url,manifest),/深层路由/); await fs.writeFile(path.join(dir,'deployment-version.json'),JSON.stringify({...manifest,releaseId:'old-release'})); await assert.rejects(verifyRelease(url,manifest),/版本.*不一致/); }); test('发布包拒绝密钥文件和符号链接',async t=>{ const {dir}=await fixture(t); await fs.writeFile(path.join(dir,'.env'),'EXAMPLE=private'); await assert.rejects(manifestFor(dir,'r','c'),/不允许/); await fs.unlink(path.join(dir,'.env')); await fs.symlink(path.join(dir,'index.html'),path.join(dir,'link')); await assert.rejects(manifestFor(dir,'r','c'),/不允许/); });