镜像自地址
https://github.com/lhly/cloud-drive-renamer.git
已同步 2026-10-20 13:47:47 +08:00
137 行
5.1 KiB
TypeScript
137 行
5.1 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { ConfigPanel } from '../../src/content/components/config-panel';
|
|
import type { RulePresetRecord } from '../../src/types/rule-preset';
|
|
|
|
function createPreset(overrides: Partial<RulePresetRecord>): RulePresetRecord {
|
|
return {
|
|
id: 'preset-id',
|
|
config: {
|
|
type: 'prefix',
|
|
params: { prefix: 'Show', separator: '.' },
|
|
},
|
|
createdAt: 1,
|
|
updatedAt: 1,
|
|
source: 'recent',
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
describe('ConfigPanel rule preset interactions', () => {
|
|
beforeEach(() => {
|
|
vi.stubGlobal('prompt', vi.fn(() => '剧集模板'));
|
|
vi.stubGlobal('confirm', vi.fn(() => true));
|
|
});
|
|
|
|
it('marks invalid presets as disabled and does not dispatch apply events', async () => {
|
|
const panel = new ConfigPanel();
|
|
panel.recentRulePresets = [
|
|
createPreset({
|
|
id: 'invalid-1',
|
|
source: 'recent',
|
|
name: '失效模板',
|
|
config: { type: 'replace', params: { search: '', replace: '' } },
|
|
}),
|
|
];
|
|
|
|
const applyEvents: Array<Event> = [];
|
|
panel.addEventListener('apply-rule-preset', (event) => applyEvents.push(event));
|
|
|
|
document.body.appendChild(panel);
|
|
await panel.updateComplete;
|
|
|
|
const applyButton = panel.shadowRoot?.querySelector<HTMLButtonElement>(
|
|
'[data-preset-id="invalid-1"] [data-role="apply-rule-preset"]'
|
|
);
|
|
const badgeText = panel.shadowRoot?.querySelector('[data-preset-id="invalid-1"] .preset-invalid-badge')?.textContent ?? '';
|
|
|
|
expect(applyButton?.disabled).toBe(true);
|
|
expect(badgeText).toContain('失效');
|
|
|
|
applyButton?.dispatchEvent(new MouseEvent('click', { bubbles: true, composed: true }));
|
|
expect(applyEvents).toHaveLength(0);
|
|
|
|
panel.remove();
|
|
});
|
|
|
|
it('renders recent/templates and dispatches apply, save, delete events', async () => {
|
|
const panel = new ConfigPanel();
|
|
panel.activeRuleConfig = {
|
|
type: 'episodeExtract',
|
|
params: {
|
|
template: '{prefix}.S{season}E{episode}{ext}',
|
|
prefix: '',
|
|
season: 1,
|
|
offset: 0,
|
|
leadingZeroCount: 2,
|
|
helperPre: '',
|
|
helperPost: '',
|
|
},
|
|
};
|
|
panel.recentRulePresets = [
|
|
createPreset({ id: 'recent-1', source: 'recent', name: '最近规则' }),
|
|
];
|
|
panel.templateRulePresets = [
|
|
createPreset({ id: 'template-1', source: 'template', name: '我的模板' }),
|
|
];
|
|
|
|
document.body.appendChild(panel);
|
|
await panel.updateComplete;
|
|
|
|
const text = panel.shadowRoot?.textContent ?? '';
|
|
expect(text).toContain('最近规则');
|
|
expect(text).toContain('我的模板');
|
|
|
|
const applyEvents: Array<CustomEvent<{ presetId: string }>> = [];
|
|
const saveEvents: Array<CustomEvent<{ name: string }>> = [];
|
|
const renameEvents: Array<CustomEvent<{ presetId: string; name: string }>> = [];
|
|
const deleteEvents: Array<CustomEvent<{ presetId: string }>> = [];
|
|
panel.addEventListener('apply-rule-preset', (event) => applyEvents.push(event as CustomEvent<{ presetId: string }>));
|
|
panel.addEventListener('save-rule-template', (event) => saveEvents.push(event as CustomEvent<{ name: string }>));
|
|
panel.addEventListener('rename-rule-template', (event) => renameEvents.push(event as CustomEvent<{ presetId: string; name: string }>));
|
|
panel.addEventListener('delete-rule-template', (event) => deleteEvents.push(event as CustomEvent<{ presetId: string }>));
|
|
|
|
panel.shadowRoot
|
|
?.querySelector<HTMLElement>('[data-preset-id="recent-1"] [data-role="apply-rule-preset"]')
|
|
?.dispatchEvent(new MouseEvent('click', { bubbles: true, composed: true }));
|
|
panel.shadowRoot
|
|
?.querySelector<HTMLElement>('[data-role="save-template-button"]')
|
|
?.dispatchEvent(new MouseEvent('click', { bubbles: true, composed: true }));
|
|
vi.mocked(prompt).mockReturnValueOnce('重命名模板');
|
|
panel.shadowRoot
|
|
?.querySelector<HTMLElement>('[data-preset-id="template-1"] [data-role="rename-rule-template"]')
|
|
?.dispatchEvent(new MouseEvent('click', { bubbles: true, composed: true }));
|
|
panel.shadowRoot
|
|
?.querySelector<HTMLElement>('[data-preset-id="template-1"] [data-role="delete-rule-template"]')
|
|
?.dispatchEvent(new MouseEvent('click', { bubbles: true, composed: true }));
|
|
|
|
expect(applyEvents).toHaveLength(1);
|
|
expect(applyEvents[0].detail.presetId).toBe('recent-1');
|
|
expect(saveEvents).toHaveLength(1);
|
|
expect(saveEvents[0].detail.name).toBe('剧集模板');
|
|
expect(renameEvents).toHaveLength(1);
|
|
expect(renameEvents[0].detail.presetId).toBe('template-1');
|
|
expect(renameEvents[0].detail.name).toBe('重命名模板');
|
|
expect(deleteEvents).toHaveLength(1);
|
|
expect(deleteEvents[0].detail.presetId).toBe('template-1');
|
|
|
|
panel.remove();
|
|
});
|
|
|
|
it('does not render rename action for recent presets', async () => {
|
|
const panel = new ConfigPanel();
|
|
panel.recentRulePresets = [
|
|
createPreset({ id: 'recent-only', source: 'recent', name: '最近规则' }),
|
|
];
|
|
|
|
document.body.appendChild(panel);
|
|
await panel.updateComplete;
|
|
|
|
expect(
|
|
panel.shadowRoot?.querySelector('[data-preset-id="recent-only"] [data-role="rename-rule-template"]')
|
|
).toBeNull();
|
|
|
|
panel.remove();
|
|
});
|
|
|
|
});
|