Files
PlantAI-rag-new/tests/frontend/unit/b3/extraction.pane.test.js
T
jerryandClaude Fable 5 0875bb036c P0/M1: 四部分重构——frontend→ui、backend→sdk 改名 + 引用修复 + 骨架
- 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>
2026-08-31 12:56:47 +08:00

109 lines
4.3 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 '../../../../ui/src/components/bench/kgPaneCompat.js';
import { useBenchStore } from '../../../../ui/src/stores/bench.js';
import ProgressItem from '../../../../ui/src/components/bench/ProgressItem.vue';
vi.mock('../../../../ui/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 解除暂停
});
});