- git mv 保留历史:ui/(Vue3+Vite)、sdk/(BFF 中间层)
- 路径语义修正:db_path/figures_cache 改相对 sdk/(BFF cwd),
历史库 sdk/backend/data 迁移至 sdk/data/(会话/图片缓存无损)
- 引用修复 ~15 处:config.py、deploy/*.sh、vitest/playwright 配置、
单测导入路径、docs、README、gitignore、.env.example
- 骨架:agent/{qa,methodology,legacy-rag,vendor}、knowledge/manifest.yaml、
tooling/{compile,kb,crypto,assemble,audit,tools,scripts} + README
- 门禁验证:sdk pytest 125 通过、ui vitest 158 通过、
生产 BFF 脚本重启四上游全绿 + 静态托管 + 会话库无损
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
60 lines
2.4 KiB
JavaScript
60 lines
2.4 KiB
JavaScript
// sources.pane.test.js —— B3 单测:SourcesPane 相关(外链优先级、null 字段不渲染)
|
||
// 组件渲染走 @vue/test-utils,判定规则走 kgPaneCompat 纯函数双保险。
|
||
import { describe, it, expect } from 'vitest';
|
||
import { resolveSourceLink, aggregateSessionSources } from '../../../../ui/src/components/bench/kgPaneCompat.js';
|
||
|
||
describe('SourcesPane 外链优先级(FR-SOURCE-003)', () => {
|
||
it('url > doi > pmid > pmcid', () => {
|
||
const s = {
|
||
url: 'https://doi.org/10.1038/ng.591',
|
||
doi: '10.1038/ng.591',
|
||
pmid: '20393464',
|
||
pmcid: 'PMC123',
|
||
};
|
||
expect(resolveSourceLink(s)).toBe('https://doi.org/10.1038/ng.591');
|
||
});
|
||
|
||
it('无 url 时 doi 拼 https://doi.org/{doi}', () => {
|
||
expect(resolveSourceLink({ doi: '10.1186/s12870-019-1903-y', pmid: '31286919' })).toBe(
|
||
'https://doi.org/10.1186/s12870-019-1903-y',
|
||
);
|
||
});
|
||
|
||
it('无 url 无 doi 时 pmid 拼 PubMed', () => {
|
||
expect(resolveSourceLink({ pmid: '22429691' })).toBe('https://pubmed.ncbi.nlm.nih.gov/22429691/');
|
||
});
|
||
|
||
it('仅 pmcid 时拼 PMC', () => {
|
||
expect(resolveSourceLink({ pmcid: 'PMC6612345' })).toBe(
|
||
'https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6612345/',
|
||
);
|
||
});
|
||
|
||
it('均无(无 doi 无 pmid 无 pmcid)→ null,不显示链接图标', () => {
|
||
expect(resolveSourceLink({ title: 'x' })).toBeNull();
|
||
expect(resolveSourceLink({ doi: null, pmid: null, pmcid: null })).toBeNull();
|
||
expect(resolveSourceLink(null)).toBeNull();
|
||
});
|
||
|
||
it('空字符串按缺失处理(不产生假链接)', () => {
|
||
expect(resolveSourceLink({ doi: '', pmid: '', pmcid: '' })).toBeNull();
|
||
});
|
||
});
|
||
|
||
describe('SourcesPane null 字段不渲染(FR-SOURCE-002)', () => {
|
||
it('聚合去重:缺失字段键不影响渲染数据,null 值透传不抛错', () => {
|
||
const out = aggregateSessionSources([
|
||
{ id: 's1', paper_id: null, pmid: null, doi: null, count: 2 },
|
||
{ id: 's2', paper_id: null, pmid: null, doi: null, count: 1 },
|
||
{ id: 's3', paper_id: 'P2', count: 1 },
|
||
]);
|
||
// 无 paper_id 时按 id 去重(API.md §5):s1/s2 各保留
|
||
expect(out).toHaveLength(3);
|
||
// null 值字段在渲染层判定 falsy 不显示(组件内 v-if 守卫),聚合不丢键也不抛错
|
||
for (const it of out) {
|
||
expect(it.pmid == null).toBe(true);
|
||
expect(it.doi == null).toBe(true);
|
||
}
|
||
});
|
||
});
|