32 lines
3.5 KiB
TypeScript
32 lines
3.5 KiB
TypeScript
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>={}):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\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);
|
|
});
|
|
|
|
test('system categories filter independently of ordinary tags and are searchable',()=>{
|
|
const ranked=rankDocuments([doc('a',{categories:['中国风'],systemTags:['文档入口','document-entry']}),doc('b',{categories:['中国风']})],'','document-entry');
|
|
assert.deepEqual(ranked.map(r=>r.doc.id),['a']);assert.equal(rankDocuments([doc('a',{categories:['中国风'],systemTags:['文档入口']})],'中国风 文档入口').length,1);
|
|
});
|