import { test } from 'node:test'; import assert from 'node:assert/strict'; import { evidenceExcerpts } from '../src/core/report-evidence.js'; test('excerpts retain exact saved text and resolve original sources without inventing dates or authors', () => { const text = '全放太辣。\n少放又觉得淡。'; const report = { evidence: { need: { sourceId:'s1', quotes:[{text, ref:'产品A|评价|观察日2026-11-11'}] } } }; const [quote] = evidenceExcerpts(report, 'need', {s1:{title:'原始评价', sourceUrl:'https://example.org/review/1'}}); assert.equal(quote.text, text); assert.equal(quote.sourceId, 's1'); assert.equal(quote.author, ''); assert.equal(quote.url, 'https://example.org/review/1'); assert.equal(quote.sourceAvailable, true); assert.equal(Object.hasOwn(quote, 'publishedAt'), false); }); test('quote-specific source overrides entry source, missing sources stay visibly unresolved', () => { const report = { evidence:{e:{sourceId:'entry',quotes:[{text:'原句',sourceId:'actual',ref:'https://example.org/source'}]}} }; const [quote] = evidenceExcerpts(report,'e',{entry:{title:'不可误归属'}}); assert.equal(quote.sourceId,'actual'); assert.equal(quote.sourceTitle,''); assert.equal(quote.sourceAvailable,false); assert.equal(quote.url,'https://example.org/source'); }); test('source links reject executable protocols and embedded credentials', () => { for(const ref of ['javascript:alert(1)','data:text/html,test','file:///secret','https://name:secret@example.org/']) { const [quote] = evidenceExcerpts({evidence:{e:{quotes:[{text:'原句',ref}]}}},'e'); assert.equal(quote.url,''); assert.equal(quote.ref,ref); } }); test('missing or malformed quotes never turn a summary into an original quotation', () => { for(const evidence of [undefined,{e:{claim:'摘要'}},{e:{quotes:{text:'非列表'}}},{e:{quotes:[null,{}, {text:' '},{text:12}]}}]) { assert.deepEqual(evidenceExcerpts({evidence},'e'),[]); } });