import {linkShared} from './helpers/shared-modules.mjs'; import {routingModuleUrl} from './helpers/routing.mjs'; import {test} from 'node:test'; import assert from 'node:assert/strict'; import {File as NodeFile} from 'node:buffer'; import {readFile} from 'node:fs/promises'; import ts from 'typescript'; if(typeof globalThis.File==='undefined')globalThis.File=NodeFile; async function moduleUrl(file,replace=code=>code){ const filename=new URL(file,import.meta.url); const {outputText}=ts.transpileModule(await readFile(filename,'utf8'),{compilerOptions:{target:ts.ScriptTarget.ES2022,module:ts.ModuleKind.ESNext}}); return 'data:text/javascript;base64,'+Buffer.from(linkShared(replace(outputText)).replace(/(['"])\.\.\/routing\1/g,JSON.stringify(routingModuleUrl))+'\n//# sourceURL='+filename.pathname).toString('base64'); } const protocolUrl=await moduleUrl('../src/lib/api/protocol.ts'); const renderUrl=await moduleUrl('../src/lib/client/render.ts',code=>code.replace('"../api/protocol"',JSON.stringify(protocolUrl))); const {card}=await import(renderUrl); const flush=()=>new Promise(resolve=>setImmediate(resolve)); test('ranking cards retain original poster frames and global positions, and search highlights only escaped titles',()=>{ const drama={id:7,title:'测试 <短剧>',cover:'https://cdn.example/cover.webp',totalEpisode:10}; const ranked=card(drama,false,{rank:25}); assert.ok(ranked.includes('class="ranking-poster-frame"'));assert.ok(ranked.includes('data-rank="25"'));assert.ok(ranked.includes('第 25 名'));assert.ok(ranked.includes('>25')); assert.ok(ranked.includes('href="/detail/7/"'));assert.ok(ranked.includes('data-src="https://cdn.example/cover.webp"')); assert.ok(card(drama,false,{rank:1}).includes('>01')); assert.ok(!card(drama,false,{rank:-1}).includes('rank-home-badge')); const search=card(drama,false,{keyword:'<短剧>'}); assert.ok(search.includes('<短剧>'));assert.ok(!search.includes('<短剧>')); assert.ok(search.includes('aria-label="查看测试 <短剧>"')); }); test('member, settings and feedback client modules are removed from the site',async()=>{ const {access}=await import('node:fs/promises'); for(const file of ['account.ts','feedback.ts','header-history.ts','unlock.ts','analytics.ts'])await assert.rejects(access(new URL('../src/lib/client/'+file,import.meta.url)),file); });