- New summary row: shows the journal's rules (even if no diff applies) - Fixes user confusion when switching journals yields same diff - When all rules are null: 'no explicit format requirements' - Vitest: add case for summary rendering
124 lines
4.8 KiB
JavaScript
124 lines
4.8 KiB
JavaScript
// tests/frontend/unit/edu/reformat.rules-summary.test.js
|
||
// 目标期刊规则摘要行(data-testid="rf-rules-summary"):
|
||
// 1) 有规则字段 + 有 diff → 摘要 + "已修改 N 处"
|
||
// 2) 规则全 null + diff=0 → "无强制约束" + "样本已满足该刊要求,无需修改"
|
||
// 背景:GB/BMC PB/Rice 规则相同、Frontiers 几乎无规则,用户切换期刊看不到 diff 差异,
|
||
// 即使 diff=0 也要展示"该刊要求什么",消除"没生效"错觉。
|
||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||
import { mount } from '@vue/test-utils';
|
||
import { createPinia, setActivePinia } from 'pinia';
|
||
import ReformatPanel from '../../../../ui/src/components/edu/panels/ReformatPanel.vue';
|
||
|
||
vi.mock('../../../../ui/src/api/review.js', async (importOriginal) => {
|
||
const actual = await importOriginal();
|
||
return {
|
||
...actual,
|
||
getJournals: vi.fn().mockResolvedValue({ ok: true, items: [] }),
|
||
getDirectory: vi.fn(),
|
||
reformatTex: vi.fn(),
|
||
compileTex: vi.fn(),
|
||
};
|
||
});
|
||
|
||
import { useEduStore } from '../../../../ui/src/stores/edu.js';
|
||
|
||
function mountWithResult(eduSeed) {
|
||
const pinia = createPinia();
|
||
setActivePinia(pinia);
|
||
const edu = useEduStore();
|
||
Object.assign(edu, eduSeed);
|
||
const wrapper = mount(ReformatPanel, { global: { plugins: [pinia] } });
|
||
return { wrapper, edu };
|
||
}
|
||
|
||
function resultWith(rules, changes) {
|
||
return {
|
||
ok: true,
|
||
job_id: 'abc123def456',
|
||
modified_tex: 'x',
|
||
changes,
|
||
warnings: [],
|
||
meta: {
|
||
filename: 'paper.tex',
|
||
journal_name: 'Molecular Plant',
|
||
rules_source: 'official',
|
||
rules_note: 'journals.json 期刊专属规则',
|
||
rules,
|
||
},
|
||
};
|
||
}
|
||
|
||
describe('ReformatPanel 目标期刊规则摘要', () => {
|
||
beforeEach(() => {
|
||
global.fetch = vi.fn().mockRejectedValue(new Error('no network'));
|
||
if (!URL.createObjectURL) URL.createObjectURL = vi.fn(() => 'blob:mock');
|
||
if (!URL.revokeObjectURL) URL.revokeObjectURL = vi.fn();
|
||
});
|
||
|
||
it('1) 有规则字段 + 有 diff → 摘要列出字段且标注"已修改 N 处"', async () => {
|
||
// Molecular Plant 真实规则形态:12pt / 1.5 / author_year(font/margin null 不显示)
|
||
const { wrapper } = mountWithResult({
|
||
reformatStatus: 'ready',
|
||
reformatResult: resultWith(
|
||
{
|
||
min_font_pt: 12, min_margin_mm: null, min_line_spacing: 1.5,
|
||
refs_style: 'author_year', max_pages: null, min_figures: null, max_fonts: null,
|
||
},
|
||
[
|
||
{ line: 1, original: 'a', modified: 'b', reason: 'r', rule_key: 'font_pt', action: 'modified' },
|
||
{ line: 3, original: 'a', modified: 'b', reason: 'r', rule_key: 'line_spacing', action: 'modified' },
|
||
{ line: 4, original: 'a', modified: 'b', reason: 'r', rule_key: 'bib_style', action: 'modified' },
|
||
],
|
||
),
|
||
});
|
||
await wrapper.vm.$nextTick();
|
||
const el = wrapper.find('[data-testid="rf-rules-summary"]');
|
||
expect(el.exists()).toBe(true);
|
||
const text = el.text();
|
||
expect(text).toContain('1.5 倍行距');
|
||
expect(text).toContain('作者-年份引用');
|
||
expect(text).toContain('字号 ≥12pt');
|
||
expect(text).not.toContain('null');
|
||
expect(text).not.toContain('边距'); // min_margin_mm=null → 不显示
|
||
expect(text).toContain('已修改 3 处');
|
||
});
|
||
|
||
it('2) 规则全 null + diff=0 → "无强制约束" + "样本已满足该刊要求,无需修改"', async () => {
|
||
const { wrapper } = mountWithResult({
|
||
reformatStatus: 'ready',
|
||
reformatResult: resultWith(
|
||
{
|
||
min_font_pt: null, min_margin_mm: null, min_line_spacing: null,
|
||
refs_style: null, max_pages: null, min_figures: null, max_fonts: null,
|
||
},
|
||
[],
|
||
),
|
||
});
|
||
await wrapper.vm.$nextTick();
|
||
const el = wrapper.find('[data-testid="rf-rules-summary"]');
|
||
expect(el.exists()).toBe(true);
|
||
const text = el.text();
|
||
expect(text).toContain('该刊官网未规定明确格式要求,无强制约束');
|
||
expect(text).toContain('样本已满足该刊要求,无需修改');
|
||
expect(text).not.toContain('已修改');
|
||
});
|
||
|
||
it('3) 双倍行距 + Vancouver(GB/BMC/Rice 形态)→ 正确映射中文标签', async () => {
|
||
const { wrapper } = mountWithResult({
|
||
reformatStatus: 'ready',
|
||
reformatResult: resultWith(
|
||
{
|
||
min_font_pt: null, min_margin_mm: null, min_line_spacing: 2.0,
|
||
refs_style: 'vancouver', max_pages: null, min_figures: null, max_fonts: null,
|
||
},
|
||
[{ line: 3, original: 'a', modified: 'b', reason: 'r', rule_key: 'line_spacing', action: 'modified' }],
|
||
),
|
||
});
|
||
await wrapper.vm.$nextTick();
|
||
const text = wrapper.find('[data-testid="rf-rules-summary"]').text();
|
||
expect(text).toContain('双倍行距');
|
||
expect(text).toContain('Vancouver 引用');
|
||
expect(text).toContain('已修改 1 处');
|
||
});
|
||
});
|