101 lines
4.3 KiB
TypeScript
101 lines
4.3 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
import { TitleBar } from '@/components/layout/TitleBar';
|
|
import { useSettingsStore } from '@/stores/settings';
|
|
|
|
const invokeIpcMock = vi.hoisted(() => vi.fn());
|
|
|
|
vi.mock('@/lib/api-client', () => ({
|
|
invokeIpc: (...args: unknown[]) => invokeIpcMock(...args),
|
|
}));
|
|
|
|
describe('TitleBar platform behavior', () => {
|
|
beforeEach(() => {
|
|
invokeIpcMock.mockReset();
|
|
invokeIpcMock.mockResolvedValue(false);
|
|
useSettingsStore.setState({ sidebarCollapsed: false });
|
|
});
|
|
|
|
it('extends the product surfaces through the macOS title bar', () => {
|
|
window.electron.platform = 'darwin';
|
|
|
|
render(<TitleBar integrated />);
|
|
|
|
expect(screen.getByTestId('product-titlebar')).not.toHaveClass('border-b');
|
|
expect(screen.getByTestId('product-titlebar')).toHaveClass('glass-surface', 'bg-background/70');
|
|
expect(screen.getByTestId('titlebar-sidebar-surface')).toHaveClass('w-64', 'bg-surface-sidebar', 'border-r');
|
|
expect(screen.getByTestId('titlebar-main-surface')).toHaveClass('border-b');
|
|
expect(screen.getByTestId('titlebar-project-context')).not.toHaveClass('border-l');
|
|
expect(screen.getByTestId('titlebar-project-context')).toHaveClass('translate-y-[3px]');
|
|
expect(screen.getByTestId('titlebar-logo').querySelector('img')).toHaveAttribute('data-logo-source', 'original-wordmark');
|
|
expect(screen.getByTestId('titlebar-sidebar-toggle')).toHaveClass('translate-y-[3px]');
|
|
expect(screen.getByTestId('titlebar-project-context')).toHaveTextContent('Makelore 工作台');
|
|
expect(screen.queryByRole('button', { name: '打开项目位置' })).not.toBeInTheDocument();
|
|
expect(screen.queryByRole('button', { name: '后退' })).not.toBeInTheDocument();
|
|
expect(screen.queryByRole('button', { name: '前进' })).not.toBeInTheDocument();
|
|
fireEvent.click(screen.getByRole('button', { name: '折叠侧栏' }));
|
|
expect(useSettingsStore.getState().sidebarCollapsed).toBe(true);
|
|
|
|
act(() => useSettingsStore.setState({ sidebarCollapsed: true }));
|
|
|
|
expect(screen.getByTestId('titlebar-sidebar-surface')).toHaveClass('w-[132px]');
|
|
expect(screen.getByTestId('titlebar-sidebar-surface')).toHaveClass('border-r-0');
|
|
expect(screen.getByTestId('product-titlebar')).toHaveClass('bg-background');
|
|
expect(screen.getByTestId('titlebar-sidebar-surface')).toHaveClass('bg-background');
|
|
expect(screen.getByTestId('product-titlebar')).toHaveClass('border-b');
|
|
expect(screen.getByTestId('titlebar-main-surface')).toHaveClass('border-b-0');
|
|
});
|
|
|
|
it('renders macOS drag region', () => {
|
|
window.electron.platform = 'darwin';
|
|
|
|
const { container } = render(<TitleBar />);
|
|
|
|
expect(container.querySelector('.drag-region')).toBeInTheDocument();
|
|
expect(screen.queryByTitle('Minimize')).not.toBeInTheDocument();
|
|
expect(invokeIpcMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('previews the collapsed sidebar on hover and pins it on click', () => {
|
|
window.electron.platform = 'darwin';
|
|
useSettingsStore.setState({ sidebarCollapsed: true });
|
|
const onSidebarPeekChange = vi.fn();
|
|
|
|
render(<TitleBar integrated onSidebarPeekChange={onSidebarPeekChange} />);
|
|
|
|
const toggle = screen.getByTestId('titlebar-sidebar-toggle');
|
|
fireEvent.pointerEnter(toggle);
|
|
expect(onSidebarPeekChange).toHaveBeenCalledWith(true);
|
|
|
|
fireEvent.pointerLeave(toggle);
|
|
expect(onSidebarPeekChange).toHaveBeenCalledWith(false);
|
|
|
|
fireEvent.click(toggle);
|
|
expect(useSettingsStore.getState().sidebarCollapsed).toBe(false);
|
|
});
|
|
|
|
it('renders custom controls on Windows', async () => {
|
|
window.electron.platform = 'win32';
|
|
|
|
render(<TitleBar />);
|
|
|
|
expect(screen.getByTitle('Minimize')).toBeInTheDocument();
|
|
expect(screen.getByTitle('Maximize')).toBeInTheDocument();
|
|
expect(screen.getByTitle('Close')).toBeInTheDocument();
|
|
|
|
await waitFor(() => {
|
|
expect(invokeIpcMock).toHaveBeenCalledWith('window:isMaximized');
|
|
});
|
|
});
|
|
|
|
it('renders no custom title bar on Linux', () => {
|
|
window.electron.platform = 'linux';
|
|
|
|
const { container } = render(<TitleBar />);
|
|
|
|
expect(container.firstChild).toBeNull();
|
|
expect(screen.queryByTitle('Minimize')).not.toBeInTheDocument();
|
|
expect(invokeIpcMock).not.toHaveBeenCalled();
|
|
});
|
|
});
|