131 lines
6.5 KiB
JavaScript
131 lines
6.5 KiB
JavaScript
// @vitest-environment jsdom
|
||
// tests/frontend/unit/bioflow/benchpanel.bioflow.test.js —— BenchPanel 生信 TAB 探活显隐(L4)
|
||
// TC-BIO-JOB-012/013(探活失败隐藏「生信任务」TAB / 恢复显示)
|
||
// TC-BIO-PANE-013/014(探活失败隐藏「生信档案」TAB / 恢复显示)
|
||
// FR-BIO-025:启动探测 /api/bioflow/health;不可达隐藏生信 TAB;恢复后出现。
|
||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||
import { mount, flushPromises } from '@vue/test-utils';
|
||
import { createPinia, setActivePinia } from 'pinia';
|
||
import { useBenchStore } from '../../../../ui/src/stores/bench.js';
|
||
|
||
vi.mock('../../../../ui/src/api/bioflow.js', () => ({
|
||
bioflowHealth: vi.fn(async () => ({ ok: true, status: 'ok', db: { connected: true } })),
|
||
listBioflowJobs: vi.fn(async () => ({ ok: true, data: { items: [], total: 0 } })),
|
||
listBioflowArchives: vi.fn(async () => ({ ok: true, data: { items: [], total: 0 } })),
|
||
getBioflowJob: vi.fn(async () => ({ ok: true, data: {} })),
|
||
getBioflowArchive: vi.fn(async () => ({ ok: true, data: {} })),
|
||
deleteBioflowJob: vi.fn(async () => {}),
|
||
deleteBioflowArchive: vi.fn(async () => {}),
|
||
runBioflowArchive: vi.fn(async () => ({ ok: true, data: {} })),
|
||
createBioflowArchive: vi.fn(async () => ({ ok: true, data: {} })),
|
||
createBioflowJob: vi.fn(async () => ({ ok: true, data: { id: 'j1', stages: [] } })),
|
||
confirmBioflowStage: vi.fn(async () => ({ ok: true, data: {} })),
|
||
rerunBioflowStage: vi.fn(async () => ({ ok: true, data: {} })),
|
||
skipBioflowStage: vi.fn(async () => ({ ok: true, data: {} })),
|
||
pauseBioflowJob: vi.fn(async () => ({ ok: true, data: {} })),
|
||
resumeBioflowJob: vi.fn(async () => ({ ok: true, data: {} })),
|
||
getBioflowStageManifest: vi.fn(async () => ({ ok: true, data: {} })),
|
||
bioflowCatalog: vi.fn(async () => ({ ok: true, data: { stages: [] } })),
|
||
uploadBioflowFile: vi.fn(async () => ({ ok: true, data: {} })),
|
||
bioflowChatStream: vi.fn(async () => { throw new Error('unused'); }),
|
||
bioflowJobEvents: vi.fn(async () => { throw new Error('unused'); }),
|
||
bioflowAsk: vi.fn(async () => ({ ok: true, answer: { citations: [] } })),
|
||
reviseBioflowReport: vi.fn(async () => ({ ok: true, data: {} })),
|
||
registerBioflowReport: vi.fn(async () => ({ ok: true, data: {} })),
|
||
runBioflowArchiveByName: vi.fn(async () => ({ ok: true, data: {} })),
|
||
}));
|
||
|
||
vi.mock('../../../../ui/src/api/extraction.js', () => ({
|
||
listJobs: vi.fn(async () => ({ jobs: [], count: 0 })),
|
||
getJob: vi.fn(),
|
||
uploadPaper: vi.fn(),
|
||
getRunLog: vi.fn(async () => ({ text: '' })),
|
||
getProcessingStatus: vi.fn(),
|
||
getSummary: vi.fn(),
|
||
}));
|
||
vi.mock('../../../../ui/src/api/kg.js', () => ({
|
||
kgStatus: vi.fn(async () => ({ ok: true })),
|
||
kgOverview: vi.fn(),
|
||
searchEntities: vi.fn(),
|
||
getEntity: vi.fn(),
|
||
getNeighborhood: vi.fn(),
|
||
}));
|
||
vi.mock('../../../../ui/src/api/sessions.js', () => ({
|
||
createMessage: vi.fn(async () => ({ id: 'm1' })),
|
||
updateMessage: vi.fn(async () => ({ id: 'm1' })),
|
||
createSession: vi.fn(async () => ({ id: 's1', title: 'x', status: 'idle', created_at: 'x', updated_at: 'x', message_count: 0, meta: {} })),
|
||
updateSession: vi.fn(async () => ({})),
|
||
deleteSession: vi.fn(async () => {}),
|
||
listSessions: vi.fn(async () => []),
|
||
getSession: vi.fn(),
|
||
getSessionSources: vi.fn(async () => ({ total: 0, sources: [] })),
|
||
}));
|
||
vi.mock('../../../../ui/src/api/qa.js', () => ({
|
||
chatStream: vi.fn(async () => { throw new Error('unused'); }),
|
||
search: vi.fn(async () => { throw new Error('unused'); }),
|
||
}));
|
||
|
||
import BenchPanel from '../../../../ui/src/components/bench/BenchPanel.vue';
|
||
import { useBioflowStore } from '../../../../ui/src/stores/bioflow.js';
|
||
import * as bioflowApi from '../../../../ui/src/api/bioflow.js';
|
||
|
||
describe('BenchPanel 生信 TAB 探活显隐(FR-BIO-025)', () => {
|
||
let pinia;
|
||
beforeEach(() => {
|
||
pinia = createPinia();
|
||
setActivePinia(pinia);
|
||
vi.clearAllMocks();
|
||
});
|
||
|
||
it('探活成功:五个既有 TAB + 生信任务/生信档案两 TAB(TC-BIO-JOB-001/PANE-001)', async () => {
|
||
const w = mount(BenchPanel, { global: { plugins: [pinia] } });
|
||
await flushPromises();
|
||
const labels = w.findAll('.bench-tab').map((t) => t.text());
|
||
expect(labels).toEqual(['检索过程', '文献来源', '提取任务', '知识图谱', '文档', '生信任务', '生信档案']);
|
||
});
|
||
|
||
it('探活失败(health 不可达):生信 TAB 不渲染(TC-BIO-JOB-012/PANE-013)', async () => {
|
||
bioflowApi.bioflowHealth.mockRejectedValueOnce(new Error('down'));
|
||
const w = mount(BenchPanel, { global: { plugins: [pinia] } });
|
||
await flushPromises();
|
||
const labels = w.findAll('.bench-tab').map((t) => t.text());
|
||
expect(labels).toEqual(['检索过程', '文献来源', '提取任务', '知识图谱', '文档']);
|
||
expect(labels).not.toContain('生信任务');
|
||
expect(labels).not.toContain('生信档案');
|
||
});
|
||
|
||
it('探活恢复:强制重探后 TAB 出现(TC-BIO-JOB-013/PANE-014)', async () => {
|
||
bioflowApi.bioflowHealth.mockRejectedValueOnce(new Error('down'));
|
||
const w = mount(BenchPanel, { global: { plugins: [pinia] } });
|
||
await flushPromises();
|
||
expect(w.findAll('.bench-tab').map((t) => t.text())).not.toContain('生信任务');
|
||
// 服务恢复:强制重探
|
||
bioflowApi.bioflowHealth.mockResolvedValueOnce({ ok: true });
|
||
const bioflow = useBioflowStore();
|
||
await bioflow.probe({ force: true });
|
||
await flushPromises();
|
||
expect(w.findAll('.bench-tab').map((t) => t.text())).toContain('生信任务');
|
||
expect(w.findAll('.bench-tab').map((t) => t.text())).toContain('生信档案');
|
||
});
|
||
|
||
it('切到生信任务 TAB:渲染 BioJobsPane(TC-BIO-JOB-001)', async () => {
|
||
const w = mount(BenchPanel, { global: { plugins: [pinia] } });
|
||
await flushPromises();
|
||
const biojobsTab = w.findAll('.bench-tab').find((t) => t.text() === '生信任务');
|
||
await biojobsTab.trigger('click');
|
||
await flushPromises();
|
||
expect(useBenchStore().activeTab).toBe('biojobs');
|
||
expect(w.findComponent({ name: 'BioJobsPane' }).exists()).toBe(true);
|
||
});
|
||
|
||
it('切到生信档案 TAB:渲染 BioArchivePane(TC-BIO-PANE-001)', async () => {
|
||
const w = mount(BenchPanel, { global: { plugins: [pinia] } });
|
||
await flushPromises();
|
||
const bioarchiveTab = w.findAll('.bench-tab').find((t) => t.text() === '生信档案');
|
||
await bioarchiveTab.trigger('click');
|
||
await flushPromises();
|
||
expect(useBenchStore().activeTab).toBe('bioarchive');
|
||
expect(w.findComponent({ name: 'BioArchivePane' }).exists()).toBe(true);
|
||
});
|
||
});
|