import { describe, it, expect, vi, beforeEach } from 'vitest';
|
import { render, screen } from '@testing-library/react';
|
import React from 'react';
|
import { CSideMenu } from '../../src/framework/sideMenu/CSideMenu';
|
|
// Mock window.matchMedia
|
Object.defineProperty(window, 'matchMedia', {
|
writable: true,
|
value: vi.fn().mockImplementation((query: string) => ({
|
matches: false,
|
media: query,
|
onchange: null,
|
addEventListener: vi.fn(),
|
removeEventListener: vi.fn(),
|
dispatchEvent: vi.fn(),
|
})),
|
});
|
|
// Mock antd Menu component
|
vi.mock('antd', async () => {
|
const actual = await vi.importActual('antd');
|
return {
|
...actual,
|
Menu: vi.fn(({ items, onClick, selectedKeys, openKeys, onOpenChange, children }) => {
|
// Render items as a nested structure for testing
|
const renderItems = (items: any[]): React.ReactNode =>
|
items?.map((item) => (
|
<div key={item.key} data-testid={`menu-item-${item.key}`}>
|
{item.label}
|
{item.children && <div className="submenu">{renderItems(item.children)}</div>}
|
</div>
|
));
|
return <div data-testid="antd-menu">{items ? renderItems(items) : children}</div>;
|
}),
|
Layout: {
|
Sider: vi.fn(({ children, breakpoint, onBreakpointChange }) => children),
|
},
|
};
|
});
|
|
// Mock icons
|
vi.mock('@ant-design/icons', () => ({
|
PieChartOutlined: () => <span data-testid="icon-chart">ChartIcon</span>,
|
SettingOutlined: () => <span data-testid="icon-setting">SettingIcon</span>,
|
FolderOutlined: () => <span data-testid="icon-folder">FolderIcon</span>,
|
FileOutlined: () => <span data-testid="icon-file">FileIcon</span>,
|
RightOutlined: () => <span data-testid="icon-right">RightIcon</span>,
|
}));
|
|
describe('CSideMenu 组件', () => {
|
const mockOnClickMenuItem = vi.fn();
|
const mockOnSetMenuCollapse = vi.fn();
|
|
const basicTree = {
|
key: '1',
|
label: '导航1',
|
children: [
|
{
|
key: '1-1',
|
label: '子菜单1-1',
|
children: [
|
{ key: '1-1-1', label: '页面1-1-1', path: '/page1-1-1', pageName: 'Page111' },
|
{ key: '1-1-2', label: '页面1-1-2', path: '/page1-1-2', pageName: 'Page112' },
|
],
|
},
|
{
|
key: '1-2',
|
label: '页面1-2',
|
path: '/page1-2',
|
pageName: 'Page12',
|
},
|
],
|
};
|
|
beforeEach(() => {
|
vi.clearAllMocks();
|
});
|
|
describe('基础渲染', () => {
|
it('1.1 渲染空树时不报错', () => {
|
render(
|
<CSideMenu
|
title="测试标题"
|
tree={undefined as any}
|
collapsed={false}
|
onClickMenuItem={mockOnClickMenuItem}
|
onSetMenuCollapse={mockOnSetMenuCollapse}
|
/>
|
);
|
expect(screen.getByText('测试标题')).toBeDefined();
|
});
|
|
it('1.2 渲染标题', () => {
|
render(
|
<CSideMenu
|
title="我的侧边栏"
|
tree={basicTree}
|
collapsed={false}
|
onClickMenuItem={mockOnClickMenuItem}
|
onSetMenuCollapse={mockOnSetMenuCollapse}
|
/>
|
);
|
expect(screen.getByText('我的侧边栏')).toBeDefined();
|
});
|
});
|
|
describe('三级菜单渲染', () => {
|
it('3.1 渲染三级菜单结构', () => {
|
render(
|
<CSideMenu
|
title="测试"
|
tree={basicTree}
|
collapsed={false}
|
onClickMenuItem={mockOnClickMenuItem}
|
onSetMenuCollapse={mockOnSetMenuCollapse}
|
/>
|
);
|
expect(screen.getByText('导航1')).toBeDefined();
|
expect(screen.getByText('子菜单1-1')).toBeDefined();
|
expect(screen.getByText('页面1-1-1')).toBeDefined();
|
});
|
});
|
});
|