Files
3x-ui/frontend/src/test/app-sidebar.test.tsx
T
PathGao ac584cfc90 fix(ui): reserve space for pinned sidebar
Keep page content accessible when the desktop sidebar remains expanded and cover the complete pin lifecycle.
2026-07-30 14:52:38 +08:00

68 lines
2.4 KiB
TypeScript

import { fireEvent, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router';
import { afterEach, expect, test, vi } from 'vitest';
import AppSidebar from '@/layouts/AppSidebar';
import { renderWithProviders } from './test-utils';
vi.mock('@/api/queries/useAllSettings', () => ({
useAllSettings: () => ({ allSetting: {} }),
}));
afterEach(() => {
localStorage.clear();
});
function renderSidebar() {
return renderWithProviders(
<MemoryRouter>
<AppSidebar />
</MemoryRouter>,
);
}
test('keeps the sidebar expanded after pinning it from the header and restores the choice', () => {
const first = renderSidebar();
const sidebar = first.container.querySelector('.ant-layout-sider');
const sidebarRoot = first.container.querySelector('.ant-sidebar');
expect(sidebar?.classList.contains('ant-layout-sider-collapsed')).toBe(true);
fireEvent.mouseEnter(sidebarRoot!);
const pinButton = screen.getByRole('button', { name: 'Pin sidebar' });
expect(pinButton.closest('.brand-actions')).not.toBeNull();
fireEvent.click(pinButton);
fireEvent.mouseLeave(sidebarRoot!);
expect(sidebar?.classList.contains('ant-layout-sider-collapsed')).toBe(false);
expect(sidebarRoot?.getAttribute('style')).toContain('--sider-rail: 220px');
expect(localStorage.getItem('sidebar-pinned')).toBe('true');
first.unmount();
const second = renderSidebar();
const restoredSidebar = second.container.querySelector('.ant-layout-sider');
const restoredSidebarRoot = second.container.querySelector('.ant-sidebar');
expect(restoredSidebar?.classList.contains('ant-layout-sider-collapsed')).toBe(false);
expect(restoredSidebarRoot?.getAttribute('style')).toContain('--sider-rail: 220px');
expect(screen.getByRole('button', { name: 'Pin sidebar' })).not.toBeNull();
});
test('returns to the compact rail after unpinning', () => {
const view = renderSidebar();
const sidebar = view.container.querySelector('.ant-layout-sider');
const sidebarRoot = view.container.querySelector('.ant-sidebar');
fireEvent.mouseEnter(sidebarRoot!);
fireEvent.click(screen.getByRole('button', { name: 'Pin sidebar' }));
fireEvent.click(screen.getByRole('button', { name: 'Pin sidebar' }));
fireEvent.mouseLeave(sidebarRoot!);
expect(sidebar?.classList.contains('ant-layout-sider-collapsed')).toBe(true);
expect(sidebarRoot?.getAttribute('style')).toContain('--sider-rail: 72px');
expect(localStorage.getItem('sidebar-pinned')).toBe('false');
});