import {test} from 'node:test'; import assert from 'node:assert/strict'; import {mkdtemp,readFile,readdir,rm,writeFile} from 'node:fs/promises'; import {tmpdir} from 'node:os'; import {join} from 'node:path'; import ts from 'typescript'; import {seo,seoUrl,structuredUrl} from './helpers/seo.mjs'; const source=await readFile(new URL('../src/lib/seo-snapshot.server.ts',import.meta.url),'utf8'); const compiled=ts.transpileModule(source,{compilerOptions:{target:ts.ScriptTarget.ES2022,module:ts.ModuleKind.ESNext}}).outputText .replace("'./seo'",JSON.stringify(seoUrl)).replace("'./structured-data'",JSON.stringify(structuredUrl)); const {SeoSnapshotStore}=await import('data:text/javascript;base64,'+Buffer.from(compiled).toString('base64')); const environment=seo.resolveSeoEnvironment({config:{foreverUrlAddr:'https://drama.test'},seoInfo:{webSiteName:'站点品牌',title:'全站标题'}},[{urlValue:'/shorts/',seoInfo:{title:'栏目标题'}}]); async function directory(t){const dir=await mkdtemp(join(tmpdir(),'91-seo-snapshot-'));t.after(()=>rm(dir,{recursive:true,force:true}));return dir;} test('public SEO snapshots survive a new store instance without persisting unrelated credentials',async t=>{ const dir=await directory(t),store=new SeoSnapshotStore('https://api-a.test',dir); await store.write({...environment,token:'private-session',reportSdkConfig:'private-sdk',categories:[{...environment.categories[0],secret:'private-category'}]}); const saved=await new SeoSnapshotStore('https://api-a.test',dir).read(); assert.equal(saved.origin,environment.origin);assert.deepEqual(saved.site,environment.site);assert.equal(saved.categories[0].seoInfo.title,'栏目标题'); const text=await readFile(join(dir,(await readdir(dir))[0]),'utf8'); for(const value of ['private-session','private-sdk','private-category'])assert.ok(!text.includes(value)); assert.equal(await new SeoSnapshotStore('https://api-b.test',dir).read(),undefined); }); test('invalid writes and corrupt files cannot replace the last valid site identity',async t=>{ const dir=await directory(t),store=new SeoSnapshotStore('https://api.test',dir); await store.write(environment);await store.write({...environment,origin:'javascript:bad'}); assert.equal((await store.read()).origin,environment.origin); const filename=join(dir,(await readdir(dir))[0]);await writeFile(filename,'{invalid-json'); assert.equal((await store.read()).origin,environment.origin); assert.equal(await new SeoSnapshotStore('https://api.test',dir).read(),undefined); await writeFile(filename,JSON.stringify({version:1,environment:{...environment,origin:'http://localhost:3000'}})); assert.equal(await new SeoSnapshotStore('https://api.test',dir).read(),undefined); }); test('parallel snapshots are atomic and a non-writable cache still preserves process-local identity',async t=>{ const dir=await directory(t),store=new SeoSnapshotStore('https://api.test',dir); await Promise.all(Array.from({length:8},(_,n)=>store.write({...environment,origin:`https://site-${n}.test`}))); const files=await readdir(dir);assert.equal(files.length,1);assert.ok(files[0].endsWith('.json')); const saved=await new SeoSnapshotStore('https://api.test',dir).read();assert.match(saved.origin,/^https:\/\/site-\d\.test$/); const blocked=join(dir,'not-a-directory');await writeFile(blocked,'file'); const memory=new SeoSnapshotStore('https://blocked.test',blocked);await memory.write(environment); assert.equal((await memory.read()).origin,environment.origin); }); test('test and production snapshots remain isolated even when they use the same API',async t=>{ const root=await directory(t),cwd=process.cwd(),previous=process.env.APP_DIST_DIR; try{ process.chdir(root); process.env.APP_DIST_DIR='.next-test'; await new SeoSnapshotStore('https://same-api.test').write(environment); process.env.APP_DIST_DIR='.next'; assert.equal(await new SeoSnapshotStore('https://same-api.test').read(),undefined); await new SeoSnapshotStore('https://same-api.test').write({...environment,origin:'https://production-site.test'}); process.env.APP_DIST_DIR='.next-test'; assert.equal((await new SeoSnapshotStore('https://same-api.test').read()).origin,environment.origin); }finally{ process.chdir(cwd); if(previous===undefined)delete process.env.APP_DIST_DIR;else process.env.APP_DIST_DIR=previous; } });