import {test} from 'node:test'; import assert from 'node:assert/strict'; import {backlinksFor,documentLinks,rankDocuments,discoveryPage,InvalidDiscoveryCursor,type SearchDocument} from '../src/lib/discovery'; const doc=(id:string,patch:Partial={}):SearchDocument=>({id,title:'普通笔记 '+id,description:'',markdown:'',categories:[],namespace:'Main',createdAt:'2026-01-01',...patch}); test('backlinks count distinct documents, resolve UUID aliases and ignore self/external/image/code links',()=>{ const a=doc('a',{aliases:['aaaa-1111'],markdown:'[self](/explore/a)'}),b=doc('b',{markdown:'[inline](/explore/a) [again](http://8.211.154.134:18131/explore/aaaa-1111?agent_mode=True#x)\n\n[reference][target]\n\n[target]: /api/notes/a\n\n![image](/explore/c)\n\n`[code](/explore/c)`\n\n```md\n[fenced](/explore/c)\n```\n[external](https://example.com/explore/c)'}),c=doc('c',{markdown:'[a](/explore/a)'}); const refs=backlinksFor([a,b,c]);assert.deepEqual(refs.get('a')?.map(r=>r.id),['b','c']);assert.equal(refs.get('c')?.length,0);assert.equal(documentLinks(b.markdown).length,4); }); test('search includes body, tags and descriptions; matches all terms, casefolds and ranks title above body',()=>{ const documents=[doc('a',{markdown:'正文专属关键词 React 实践',categories:['课程']}),doc('b',{title:'REACT 实践',description:'正文专属关键词'}),doc('c',{description:'React 介绍'})]; assert.deepEqual(rankDocuments(documents,'react 实践').map(r=>r.doc.id),['b','a']); assert.deepEqual(rankDocuments(documents,'课程 正文专属关键词').map(r=>r.doc.id),['a']); assert.deepEqual(rankDocuments(documents,'"react 实践"').map(r=>r.doc.id),['b','a']);assert.equal(rankDocuments(documents,'不存在').length,0); }); test('default order favors inbound links and filters the entire corpus before paginating',()=>{ const documents=Array.from({length:52},(_,i)=>doc(i.toString(16).padStart(3,'0'),{categories:i%2?['wanted']:[],markdown:i?'[target](/explore/000)':''})); const ranked=rankDocuments(documents);assert.equal(ranked[0].doc.id,'000');assert.equal(ranked[0].backlinkCount,51); const filtered=rankDocuments(documents,'','wanted'),first=discoveryPage(filtered,'','wanted'),second=discoveryPage(filtered,'','wanted',first.nextCursor!); assert.equal(first.total,26);assert.equal(first.rows.length,24);assert.equal(second.rows.length,2);assert.equal(second.nextCursor,null);assert.equal(new Set([...first.rows,...second.rows].map(r=>r.doc.id)).size,26); assert.throws(()=>discoveryPage(filtered,'different','wanted',first.nextCursor!),InvalidDiscoveryCursor);assert.throws(()=>discoveryPage(filtered,'','wanted','bad'),InvalidDiscoveryCursor); }); test('pasted full URLs count but disguised link labels and inline code do not',()=>{ const source=doc('b',{markdown:'http://8.211.154.134:18131/explore/a。\n\n[http://8.211.154.134:18131/explore/c](https://example.com)\n\n`http://8.211.154.134:18131/explore/c`'}); const refs=backlinksFor([doc('a'),source,doc('c')]);assert.equal(refs.get('a')?.length,1);assert.equal(refs.get('c')?.length,0); });