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(); 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(); 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(); 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(); 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(); expect(container.firstChild).toBeNull(); expect(screen.queryByTitle('Minimize')).not.toBeInTheDocument(); expect(invokeIpcMock).not.toHaveBeenCalled(); }); });