Files
PlantAI-rag-new/tests/frontend/unit/edu/tracker.panel.test.js

110 lines
4.7 KiB
JavaScript
Raw Permalink 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.
// tests/frontend/unit/edu/tracker.panel.test.js —— TrackerPanel v3(方案 A 极简台账)
// 1) 统计条 5 项计数
// 2) 表单含返修截止日/返修轮次字段
// 3) 卡片显示返修轮次+截止倒计时;无"已开启/未开始返修"联动徽章
// 4) "去写返修"仅 under_review/revision 显示;点击 → section 切 rebuttal + 期刊预填(无 linkSid 回写)
// 5) 空态文案
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mount } from '@vue/test-utils';
import { createPinia, setActivePinia } from 'pinia';
import TrackerPanel from '../../../../ui/src/components/edu/panels/TrackerPanel.vue';
vi.mock('../../../../ui/src/api/review.js', () => ({
getJournals: vi.fn(),
getDirectory: vi.fn(),
getConferences: vi.fn(),
presubmit: vi.fn(),
recommend: vi.fn(),
formatCheck: vi.fn(),
formatErrorMessage: vi.fn(),
reformatTex: vi.fn(),
compileTex: vi.fn(),
reviewErrorMessage: vi.fn((e) => (e && e.message) || 'err'),
rebuttalCreateJob: vi.fn(),
rebuttalCreateFromPdf: vi.fn(),
rebuttalGetJob: vi.fn(),
rebuttalSaveResponse: vi.fn(),
rebuttalDraft: vi.fn(),
rebuttalStructure: vi.fn(),
rebuttalConfirm: vi.fn(),
rebuttalLetter: vi.fn(),
rebuttalDownloadLetterMd: vi.fn(),
rebuttalDeleteJob: vi.fn(),
}));
import { useEduStore } from '../../../../ui/src/stores/edu.js';
function seed(edu) {
edu.submissions = [
{ id: 's1', journal: 'Plant Cell', status: 'revision', submittedAt: '2026-09-01', updatedAt: '2026-10-01', notes: '', revisionDue: '2026-11-01', revisionRound: 2, rebuttalJobId: null },
{ id: 's2', journal: 'Mol Plant', status: 'accepted', submittedAt: '2026-08-01', updatedAt: '2026-09-15', notes: '' },
{ id: 's3', journal: 'GB', status: 'under_review', submittedAt: '2026-09-10', updatedAt: '2026-09-20', notes: '', rebuttalJobId: 'rbt_x1' },
{ id: 's4', journal: 'New Phytol', status: 'rejected', submittedAt: '2026-07-01', updatedAt: '2026-08-01', notes: '' },
];
}
describe('TrackerPanel v3', () => {
let wrapper;
let edu;
beforeEach(() => {
const pinia = createPinia();
setActivePinia(pinia);
edu = useEduStore();
seed(edu);
wrapper = mount(TrackerPanel, { global: { plugins: [pinia] } });
});
it('1) 统计条计数正确', () => {
const stats = wrapper.find('[data-testid="tk-stats"]');
expect(stats.text()).toContain('总投稿');
const b = stats.findAll('b').map((x) => x.text());
expect(b).toEqual(['4', '1', '1', '1', '1']); // total/active/revision/accepted/rejected
});
it('2) 表单含返修截止日与返修轮次字段', async () => {
await wrapper.find('.tk-add').trigger('click');
expect(wrapper.find('[data-testid="tk-revision-due"]').exists()).toBe(true);
expect(wrapper.find('[data-testid="tk-revision-round"]').exists()).toBe(true);
});
it('3) 卡片显示返修轮次+截止信息;无联动徽章', () => {
const rows = wrapper.findAll('[data-testid="tk-row"]');
expect(rows.length).toBe(4);
const rev = wrapper.find('[data-testid="tk-rev-info"]');
expect(rev.text()).toContain('第 2 轮返修');
expect(rev.text()).toContain('due 2026-11-01');
// 倒计时文案(今天 2026-10-12,due 2026-11-01 → 还剩 N 天)
expect(rev.text()).toMatch(/还剩 \d+ 天|今天截止|已逾期/);
// 方案 A:不再显示"已开启/未开始返修"联动徽章
expect(wrapper.find('[data-testid="tk-rebuttal-status"]').exists()).toBe(false);
expect(wrapper.text()).not.toContain('已开启返修任务');
expect(wrapper.text()).not.toContain('未开始返修');
});
it('4) 「去写返修」仅审稿中/返修中显示;点击只跳转+预填期刊(无回写)', () => {
// 按 updatedAt 倒序:s1(revision) → s3(under_review) → s2(accepted) → s4(rejected)
const btns = wrapper.findAll('[data-testid="tk-start-rebuttal"]');
expect(btns.length).toBe(2); // 仅 s1/s3
const rows = wrapper.findAll('[data-testid="tk-row"]');
expect(rows[2].text()).not.toContain('去写返修'); // s2 accepted
expect(rows[3].text()).not.toContain('去写返修'); // s4 rejected
btns[0].trigger('click');
return Promise.resolve().then(() => {
expect(edu.section).toBe('rebuttal');
expect(edu.rebuttal.prefillJournal).toBe('Plant Cell');
expect(edu.rebuttal.linkSid == null).toBe(true); // 方案 A:无回写联动
});
});
it('5) 空态文案', () => {
const pinia = createPinia();
setActivePinia(pinia);
const edu2 = useEduStore();
edu2.submissions = [];
const w = mount(TrackerPanel, { global: { plugins: [pinia] } });
expect(w.find('.tk-empty').text()).toContain('暂无投稿记录');
expect(w.find('.tk-empty').text()).toContain('新增投稿');
});
});