import { UserOutlined } from '@ant-design/icons'; import React, { useState } from 'react'; import { act } from 'react-dom/test-utils'; import Layout from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; import { fireEvent, render } from '../../../tests/utils'; import Menu from '../../menu'; const { Sider, Content, Footer, Header } = Layout; describe('Layout', () => { mountTest(Layout); mountTest(Content); mountTest(Sider); mountTest(() => ( )); rtlTest(Layout); rtlTest(Content); rtlTest(Sider); it('detect the sider as children', () => { const { container, unmount } = render( Sider Content , ); expect(container.querySelector('.ant-layout')?.className.includes('ant-layout-has-sider')).toBe( true, ); unmount(); }); it('umount from multiple siders', async () => { const App: React.FC = () => { const [hide1, setHide1] = useState(false); const [hide2, setHide2] = useState(false); return ( {hide1 ? null : Sider} {hide2 ? null : Sider} ); }; const { container } = render(); expect(container.querySelector('.ant-layout')?.className.includes('ant-layout-has-sider')).toBe( true, ); fireEvent.click(container.querySelectorAll('button')[0]); expect(container.querySelector('.ant-layout')?.className.includes('ant-layout-has-sider')).toBe( true, ); fireEvent.click(container.querySelectorAll('button')[1]); expect(container.querySelector('.ant-layout')?.className.includes('ant-layout-has-sider')).toBe( false, ); }); it('detect the sider inside the children', async () => { const { container } = render(
Sider
Content
, ); expect(container.querySelector('.ant-layout')?.className.includes('ant-layout-has-sider')).toBe( true, ); }); it('detect ant-layout-sider-has-trigger class in sider when ant-layout-sider-trigger div tag exists', async () => { const { container } = render(
Sider
Content
, ); expect( container .querySelector('.ant-layout-sider') ?.className.includes('ant-layout-sider-has-trigger'), ).toBe(true); }); it('should have 50% width of sidebar', async () => { const { container } = render(
Sider
Content
, ); expect(container.querySelector('.ant-layout-sider')?.style.width).toBe('50%'); expect(container.querySelector('.ant-layout-sider')?.style.flex).toBe('0 0 50%'); }); describe('zeroWidth', () => { it('detect ant-layout-sider-zero-width class in sider when its width is 0%', async () => { const { container } = render(
Sider
Content
, ); expect( container .querySelector('.ant-layout-sider') ?.className.includes('ant-layout-sider-zero-width'), ).toBe(true); }); describe('should collapsible', () => { it('uncontrolled', () => { const onCollapse = vi.fn(); const { container } = render( Sider Content , ); onCollapse.mockReset(); fireEvent.click(container.querySelector('.ant-layout-sider-zero-width-trigger')!); expect(onCollapse).toHaveBeenCalledTimes(1); }); it('controlled', () => { const Demo: React.FC = () => { const [collapsed, setCollapsed] = React.useState(true); return ( Sider Content ); }; const { container } = render(); expect(container.querySelector('.ant-layout-sider-collapsed')).toBeTruthy(); fireEvent.click(container.querySelector('.ant-layout-sider-zero-width-trigger')!); expect(container.querySelector('.ant-layout-sider-collapsed')).toBeFalsy(); }); }); }); it('detect ant-layout-sider-dark as default theme', async () => { const { container } = render(Sider); expect( container.querySelector('.ant-layout-sider')?.className.includes('ant-layout-sider-dark'), ).toBe(true); }); it('detect ant-layout-sider-light when set light theme', async () => { const { container } = render(Sider); expect( container.querySelector('.ant-layout-sider')?.className.includes('ant-layout-sider-light'), ).toBe(true); }); it('renders string width correctly', () => { const { asFragment } = render(Sider); expect(asFragment().firstChild).toMatchSnapshot(); }); it('should be controlled by collapsed', () => { const { asFragment, rerender } = render(Sider); expect(asFragment().firstChild).toMatchSnapshot(); rerender(Sider); expect(asFragment().firstChild).toMatchSnapshot(); }); it('should not add ant-layout-has-sider when `hasSider` is `false`', () => { const { container } = render( Sider , ); expect(container.querySelector('.ant-layout')?.className.includes('ant-layout-has-sider')).toBe( false, ); }); it('render correct with Tooltip', () => { vi.useFakeTimers(); const { container, rerender } = render( Light , ); fireEvent.mouseEnter(container.querySelector('.ant-menu-item')!); act(() => { vi.runAllTimers(); }); expect(container.querySelectorAll('.ant-tooltip-inner').length).toBeFalsy(); rerender( Light , ); fireEvent.mouseEnter(container.querySelector('.ant-menu-item')!); act(() => { vi.runAllTimers(); }); expect(container.querySelectorAll('.ant-tooltip-inner').length).toBeTruthy(); vi.useRealTimers(); }); }); describe('Sider', () => { const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); afterEach(() => { errorSpy.mockReset(); }); afterAll(() => { errorSpy.mockRestore(); }); it('should trigger onBreakpoint', async () => { const onBreakpoint = vi.fn(); render( Sider , ); expect(onBreakpoint).toHaveBeenCalledWith(true); }); it('should warning if use `inlineCollapsed` with menu', () => { render( , ); expect(errorSpy).toHaveBeenCalledWith( 'Warning: [antd: Menu] `inlineCollapsed` not control Menu under Sider. Should set `collapsed` on Sider instead.', ); }); it('zeroWidthTriggerStyle should work', () => { const { container } = render( nav 1 , ); expect( container.querySelector('.ant-layout-sider-zero-width-trigger')?.style .background, ).toEqual('rgb(255, 153, 102)'); }); it('should be able to customize zero width trigger by trigger prop', () => { const { container } = render( }> nav 1 , ); expect( container.querySelector('.ant-layout-sider-zero-width-trigger')?.querySelector('.my-trigger'), ).toBeTruthy(); }); (['Layout', 'Header', 'Footer', 'Sider'] as const).forEach((tag) => { const ComponentMap = { Layout, Header, Footer, Sider }; it(`should get ${tag} element from ref`, () => { const ref = React.createRef(); const onSelect = vi.fn(); const Component = ComponentMap[tag]; render( {tag} , ); expect(ref.current instanceof HTMLElement).toBe(true); }); }); });