tmagic-editor/packages/editor/tests/unit/fields/PageFragmentSelect.spec.ts
2026-05-14 15:26:22 +08:00

144 lines
4.4 KiB
TypeScript

/*
* Tencent is pleased to support the open source community by making TMagicEditor available.
*
* Copyright (C) 2025 Tencent.
*/
import { describe, expect, test, vi } from 'vitest';
import { defineComponent, h } from 'vue';
import { mount } from '@vue/test-utils';
import PageFragmentSelect from '@editor/fields/PageFragmentSelect.vue';
const editorService = {
get: vi.fn(),
select: vi.fn(),
};
vi.mock('@editor/hooks/use-services', () => ({
useServices: () => ({ editorService }),
}));
vi.mock('@tmagic/form', () => ({
MSelect: defineComponent({
name: 'MSelect',
props: ['config', 'model', 'name', 'size', 'prop', 'disabled'],
emits: ['change'],
setup(_p, { emit }) {
return () =>
h('select', {
class: 'fake-select',
onChange: (e: Event) => emit('change', (e.target as HTMLSelectElement).value),
});
},
}),
}));
vi.mock('@editor/components/Icon.vue', () => ({
default: defineComponent({
name: 'MEditorIcon',
props: ['icon'],
emits: ['click'],
setup(_p, { emit }) {
return () => h('i', { class: 'fake-icon', onClick: () => emit('click') });
},
}),
}));
vi.mock('@tmagic/core', async () => {
const actual = await vi.importActual<any>('@tmagic/core');
return { ...actual, NodeType: { PAGE: 'page', PAGE_FRAGMENT: 'page-fragment' } };
});
describe('PageFragmentSelect', () => {
test('model[name] 不为空时显示编辑图标', () => {
editorService.get.mockReturnValue({ items: [{ id: 'p1', type: 'page-fragment', name: 'A' }] });
const wrapper = mount(PageFragmentSelect, {
props: {
config: { type: 'page-fragment-select' },
name: 'pf',
model: { pf: 'p1' },
size: 'default',
} as any,
});
expect(wrapper.find('.fake-icon').exists()).toBe(true);
});
test('model[name] 为空不显示编辑图标', () => {
editorService.get.mockReturnValue({ items: [] });
const wrapper = mount(PageFragmentSelect, {
props: {
config: { type: 'page-fragment-select' },
name: 'pf',
model: { pf: '' },
size: 'default',
} as any,
});
expect(wrapper.find('.fake-icon').exists()).toBe(false);
});
test('change emit', async () => {
editorService.get.mockReturnValue({ items: [] });
const wrapper = mount(PageFragmentSelect, {
props: {
config: { type: 'page-fragment-select' },
name: 'pf',
model: { pf: '' },
size: 'default',
} as any,
});
await wrapper.findComponent({ name: 'MSelect' }).vm.$emit('change', 'p2');
expect(wrapper.emitted('change')?.[0]?.[0]).toBe('p2');
});
test('点击编辑图标调用 editorService.select', async () => {
editorService.get.mockReturnValue({ items: [{ id: 'p1', type: 'page-fragment', name: 'A' }] });
editorService.select.mockClear();
const wrapper = mount(PageFragmentSelect, {
props: {
config: { type: 'page-fragment-select' },
name: 'pf',
model: { pf: 'p1' },
size: 'default',
} as any,
});
await wrapper.find('.fake-icon').trigger('click');
expect(editorService.select).toHaveBeenCalledWith('p1');
});
test('selectConfig.options 返回 pageList', () => {
const items = [
{ id: 'p1', type: 'page-fragment', name: 'A', title: 'TitleA' },
{ id: 'p2', type: 'page-fragment', name: 'B', devconfig: { tabName: 'TabB' } },
{ id: 'p3', type: 'page', name: 'normal' },
];
editorService.get.mockReturnValue({ items });
const wrapper = mount(PageFragmentSelect, {
props: {
config: { type: 'page-fragment-select' },
name: 'pf',
model: { pf: '' },
size: 'default',
} as any,
});
const select = wrapper.findComponent({ name: 'MSelect' });
const options = (select.props('config') as any).options();
expect(options.length).toBe(2);
expect(options[0].value).toBe('p1');
expect(options[1].text).toContain('TabB');
});
test('root 为空 options 返回空数组', () => {
editorService.get.mockReturnValue(undefined);
const wrapper = mount(PageFragmentSelect, {
props: {
config: { type: 'page-fragment-select' },
name: 'pf',
model: { pf: '' },
size: 'default',
} as any,
});
const select = wrapper.findComponent({ name: 'MSelect' });
expect((select.props('config') as any).options()).toEqual([]);
});
});