Files
PlantAI-rag-new/tests/frontend/unit/b3/extraction.pane.test.js
T
jerryandClaude Fable 5 1e94de7464 PlantAI-rag-new 首次提交:文献知识工作台
- BFF 薄适配层(FastAPI,8090):QA 代理/SSE 中继/Neo4j 直连/抽取代理/会话持久化
- Vue3 前端:五相位检索流水线、文献来源与证据链、知识图谱、提取任务四 tab
- 四档响应式(桌面/笔记本/平板/手机)、深浅主题
- 81 个 FR 全部实现,测试追溯矩阵 81/81,后端 121 测/前端 156 测
- 真实凭据已脱敏,运行时配置在 backend/.env(不入 git)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 20:47:52 +08:00

109 lines
4.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// extraction.pane.test.js —— B3 单测:ExtractionPane(progress_pct 派生展示、failed 错误态、轮询条件)
import { describe, it, expect, vi } from 'vitest';
import { mount } from '@vue/test-utils';
import { createPinia, setActivePinia } from 'pinia';
import { deriveProgressPct, shouldPoll } from '../../../../frontend/src/components/bench/kgPaneCompat.js';
import { useBenchStore } from '../../../../frontend/src/stores/bench.js';
import ProgressItem from '../../../../frontend/src/components/bench/ProgressItem.vue';
vi.mock('../../../../frontend/src/api/extraction.js', () => ({
listJobs: vi.fn().mockResolvedValue({ jobs: [], count: 0 }),
getJob: vi.fn(),
uploadPaper: vi.fn(),
getRunLog: vi.fn().mockResolvedValue({ text: '' }),
getProcessingStatus: vi.fn(),
getSummary: vi.fn(),
}));
describe('ExtractionPane progress_pct 派生(FR-EXTRACT-001)', () => {
it('按 stage 派生:queued=5 / mineru=35 / llm=75 / completed=100 / failed=null', () => {
expect(deriveProgressPct({ stage: 'queued' })).toBe(5);
expect(deriveProgressPct({ stage: 'mineru' })).toBe(35);
expect(deriveProgressPct({ stage: 'llm' })).toBe(75);
expect(deriveProgressPct({ stage: 'completed' })).toBe(100);
expect(deriveProgressPct({ stage: 'failed' })).toBeNull();
expect(deriveProgressPct({ stage: 'unknown' })).toBeNull();
expect(deriveProgressPct(null)).toBeNull();
});
it('BFF 已给 progress_pct 时优先使用', () => {
expect(deriveProgressPct({ stage: 'llm', progress_pct: 77 })).toBe(77);
});
it('ProgressItem:failed 显示错误态且不渲染进度条', () => {
const wrapper = mount(ProgressItem, {
props: {
job: {
job_id: 'j3',
title: 'Rice_NAC_2020.pdf',
status: 'failed',
stage: 'failed',
progress_pct: null,
message: 'MinerU 解析失败:/home/xia-lab/miniconda3/envs/minerupy311/bin/mineru 不存在',
},
open: false,
},
});
expect(wrapper.find('.pi-pct.err').text()).toBe('失败');
expect(wrapper.find('.prog-track').exists()).toBe(false); // 不显示进度条
expect(wrapper.find('.pi-errmsg').exists()).toBe(true);
expect(wrapper.find('.pi-errmsg').text()).toContain('MinerU 解析失败');
});
it('ProgressItem:completed 显示 100% success 停扫光', () => {
const wrapper = mount(ProgressItem, {
props: {
job: { job_id: 'j1', title: 'wang2019.pdf', status: 'completed', stage: 'completed', progress_pct: 100 },
open: false,
},
});
expect(wrapper.find('.pi-pct.ok').text()).toBe('100%');
expect(wrapper.find('.prog-fill.full').exists()).toBe(true);
});
it('ProgressItem:running 显示派生的 75% 渐变进度条', () => {
const wrapper = mount(ProgressItem, {
props: {
job: { job_id: 'j2', title: 'Pecan_SPL_2021.pdf', status: 'running', stage: 'llm', progress_pct: 75 },
open: false,
},
});
expect(wrapper.find('.pi-pct').text()).toBe('75%');
expect(wrapper.find('.prog-fill').exists()).toBe(true);
expect(wrapper.find('.prog-fill.full').exists()).toBe(false);
});
});
describe('ExtractionPane 轮询条件(FR-EXTRACT-005)', () => {
it('存在 running/queued 才轮询;全终态停止', () => {
expect(shouldPoll([{ status: 'completed' }, { status: 'failed' }])).toBe(false);
expect(shouldPoll([{ status: 'completed' }, { status: 'running' }])).toBe(true);
expect(shouldPoll([{ status: 'queued' }])).toBe(true);
expect(shouldPoll([])).toBe(false);
});
it('store.hasActiveJobs 与 shouldPoll 一致', () => {
setActivePinia(createPinia());
const store = useBenchStore();
store.jobs = [
{ job_id: 'a', status: 'completed' },
{ job_id: 'b', status: 'failed' },
];
expect(store.hasActiveJobs).toBe(false);
store.jobs.push({ job_id: 'c', status: 'running' });
expect(store.hasActiveJobs).toBe(true);
});
it('tab 切走即暂停:setActiveTab 离开 extract 调用 pausePolling', () => {
setActivePinia(createPinia());
const store = useBenchStore();
store.pollPaused = false;
store.setActiveTab('extract');
store.pollPaused = true; // 轮询曾启动
store.setActiveTab('retrieval');
expect(store.pollPaused).toBe(true); // 保持暂停
store.setActiveTab('extract');
expect(store.pollPaused).toBe(false); // 回到 extract 解除暂停
});
});