mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-05-30 12:18:10 +00:00
175 lines
5.8 KiB
TypeScript
175 lines
5.8 KiB
TypeScript
/*
|
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
*
|
|
* Copyright (C) 2025 Tencent.
|
|
*/
|
|
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
import { defineComponent, h, nextTick } from 'vue';
|
|
import { mount } from '@vue/test-utils';
|
|
|
|
import Sidebar from '@editor/layouts/sidebar/Sidebar.vue';
|
|
|
|
const depService = { get: vi.fn(() => false) };
|
|
const uiService = {
|
|
get: vi.fn(() => ({ left: 200 })),
|
|
set: vi.fn(),
|
|
};
|
|
const propsService = {
|
|
getDisabledDataSource: vi.fn(() => false),
|
|
getDisabledCodeBlock: vi.fn(() => false),
|
|
};
|
|
|
|
vi.mock('@editor/hooks/use-services', () => ({
|
|
useServices: () => ({ depService, uiService, propsService }),
|
|
}));
|
|
|
|
vi.mock('@editor/hooks/use-editor-content-height', () => ({
|
|
useEditorContentHeight: () => ({ height: { value: 600 } }),
|
|
}));
|
|
|
|
const dragstartHandler = vi.fn();
|
|
const dragendHandler = vi.fn();
|
|
vi.mock('@editor/hooks/use-float-box', () => ({
|
|
useFloatBox: () => ({
|
|
dragstartHandler,
|
|
dragendHandler,
|
|
floatBoxStates: { layer: { status: false }, 'code-block': { status: false }, 'data-source': { status: false } },
|
|
showingBoxKeys: { value: [] },
|
|
}),
|
|
}));
|
|
|
|
vi.mock('@editor/layouts/sidebar/code-block/CodeBlockListPanel.vue', () => ({
|
|
default: { name: 'CodeBlockListPanel', render: () => null },
|
|
}));
|
|
vi.mock('@editor/layouts/sidebar/data-source/DataSourceListPanel.vue', () => ({
|
|
default: { name: 'DataSourceListPanel', render: () => null },
|
|
}));
|
|
vi.mock('@editor/layouts/sidebar/layer/LayerPanel.vue', () => ({
|
|
default: { name: 'LayerPanel', render: () => null },
|
|
}));
|
|
vi.mock('@editor/layouts/sidebar/ComponentListPanel.vue', () => ({
|
|
default: { name: 'ComponentListPanel', render: () => null },
|
|
}));
|
|
|
|
const stub = (name: string) =>
|
|
defineComponent({
|
|
name,
|
|
setup() {
|
|
return () => h('div', { class: name });
|
|
},
|
|
});
|
|
|
|
vi.mock('@editor/components/Icon.vue', () => ({
|
|
default: defineComponent({ name: 'MIcon', props: ['icon'], setup: () => () => h('i', { class: 'fake-icon' }) }),
|
|
}));
|
|
|
|
vi.mock('@editor/components/FloatingBox.vue', () => ({
|
|
default: defineComponent({
|
|
name: 'FloatingBox',
|
|
props: ['visible', 'width', 'height', 'title', 'position'],
|
|
setup(_p, { slots }) {
|
|
return () => h('div', { class: 'floating-box' }, slots.body?.());
|
|
},
|
|
}),
|
|
}));
|
|
|
|
vi.mock('@editor/type', async () => {
|
|
const actual = await vi.importActual<any>('@editor/type');
|
|
return {
|
|
...actual,
|
|
SideItemKey: {
|
|
COMPONENT_LIST: 'component-list',
|
|
LAYER: 'layer',
|
|
CODE_BLOCK: 'code-block',
|
|
DATA_SOURCE: 'data-source',
|
|
},
|
|
ColumnLayout: { LEFT: 'left', CENTER: 'center', RIGHT: 'right' },
|
|
};
|
|
});
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
propsService.getDisabledDataSource.mockReturnValue(false);
|
|
propsService.getDisabledCodeBlock.mockReturnValue(false);
|
|
uiService.get.mockReturnValue({ left: 200 });
|
|
});
|
|
|
|
const baseProps = (extra: any = {}) => ({
|
|
data: { type: 'tabs', status: '组件', items: ['component-list', 'layer', 'code-block', 'data-source'] },
|
|
layerContentMenu: [],
|
|
customContentMenu: (m: any) => m,
|
|
...extra,
|
|
});
|
|
|
|
describe('Sidebar', () => {
|
|
test('渲染 4 个 sidebar header 条目', () => {
|
|
const wrapper = mount(Sidebar, { props: baseProps() as any });
|
|
expect(wrapper.findAll('.m-editor-sidebar-header-item').length).toBe(4);
|
|
});
|
|
|
|
test('disabledDataSource 时不展示 data-source', () => {
|
|
propsService.getDisabledDataSource.mockReturnValue(true);
|
|
const wrapper = mount(Sidebar, { props: baseProps() as any });
|
|
expect(wrapper.findAll('.m-editor-sidebar-header-item').length).toBe(3);
|
|
});
|
|
|
|
test('disabledCodeBlock 时不展示 code-block', () => {
|
|
propsService.getDisabledCodeBlock.mockReturnValue(true);
|
|
const wrapper = mount(Sidebar, { props: baseProps() as any });
|
|
expect(wrapper.findAll('.m-editor-sidebar-header-item').length).toBe(3);
|
|
});
|
|
|
|
test('点击 header item 切换 activeTabName', async () => {
|
|
const wrapper = mount(Sidebar, { props: baseProps() as any });
|
|
const items = wrapper.findAll('.m-editor-sidebar-header-item');
|
|
await items[1].trigger('click');
|
|
expect((wrapper.vm as any).activeTabName).toBe('已选组件');
|
|
});
|
|
|
|
test('items 为空时不渲染 sidebar', () => {
|
|
const wrapper = mount(Sidebar, {
|
|
props: baseProps({ data: { type: 'tabs', status: '', items: [] } }) as any,
|
|
});
|
|
expect(wrapper.find('.m-editor-sidebar').exists()).toBe(false);
|
|
});
|
|
|
|
test('sideBarItems 写入 uiService', () => {
|
|
mount(Sidebar, { props: baseProps() as any });
|
|
expect(uiService.set).toHaveBeenCalledWith('sideBarItems', expect.any(Array));
|
|
});
|
|
|
|
test('data.status 变化时同步 activeTabName', async () => {
|
|
const wrapper = mount(Sidebar, { props: baseProps() as any });
|
|
await wrapper.setProps({ data: { type: 'tabs', status: '数据源', items: ['data-source'] } });
|
|
await nextTick();
|
|
expect((wrapper.vm as any).activeTabName).toBe('数据源');
|
|
});
|
|
|
|
test('beforeClick 返回 false 时不切换', async () => {
|
|
const beforeClick = vi.fn(async () => false);
|
|
const wrapper = mount(Sidebar, {
|
|
props: baseProps({
|
|
data: {
|
|
type: 'tabs',
|
|
status: 'A',
|
|
items: [
|
|
{ $key: 'a', text: 'A', component: stub('A'), beforeClick },
|
|
{ $key: 'b', text: 'B', component: stub('B') },
|
|
],
|
|
},
|
|
}) as any,
|
|
});
|
|
const items = wrapper.findAll('.m-editor-sidebar-header-item');
|
|
await items[0].trigger('click');
|
|
await nextTick();
|
|
expect(beforeClick).toHaveBeenCalled();
|
|
});
|
|
|
|
test('dragstartHandler 触发', async () => {
|
|
const wrapper = mount(Sidebar, { props: baseProps() as any });
|
|
const items = wrapper.findAll('.m-editor-sidebar-header-item');
|
|
await items[0].trigger('dragstart');
|
|
expect(dragstartHandler).toHaveBeenCalled();
|
|
});
|
|
});
|