Download desktop/src/components/shared/RepositoryLaunchControls.test.tsx from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 5.47 kB
-
https://huggingface.co/chenbhao/codev/resolve/e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/components/shared/RepositoryLaunchControls.test.tsx
- Command line
-
hf download hf://chenbhao/codev@e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/components/shared/RepositoryLaunchControls.test.tsx
-
curl -L -o RepositoryLaunchControls.test.tsx https://huggingface.co/chenbhao/codev/resolve/e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/components/shared/RepositoryLaunchControls.test.tsx
5.47 kB
| import { fireEvent, render, screen, waitFor } from '@testing-library/react' | |
| import type { ComponentProps } from 'react' | |
| import { beforeEach, describe, expect, it, vi } from 'vitest' | |
| import '@testing-library/jest-dom' | |
| const viewportMocks = vi.hoisted(() => ({ | |
| isMobile: false, | |
| isTauri: false, | |
| })) | |
| const apiMocks = vi.hoisted(() => ({ | |
| getRepositoryContext: vi.fn(), | |
| })) | |
| vi.mock('../../hooks/useMobileViewport', () => ({ | |
| useMobileViewport: () => viewportMocks.isMobile, | |
| })) | |
| vi.mock('../../lib/desktopRuntime', () => ({ | |
| isTauriRuntime: () => viewportMocks.isTauri, | |
| })) | |
| vi.mock('../../api/sessions', () => ({ | |
| sessionsApi: { | |
| getRepositoryContext: apiMocks.getRepositoryContext, | |
| }, | |
| })) | |
| vi.mock('./DirectoryPicker', () => ({ | |
| DirectoryPicker: ({ value }: { value: string }) => ( | |
| <button type="button">Project {value}</button> | |
| ), | |
| })) | |
| vi.mock('../../i18n', () => ({ | |
| useTranslation: () => (key: string) => ({ | |
| 'common.loading': 'Loading', | |
| 'repoLaunch.checkedOut': 'Checked out', | |
| 'repoLaunch.checkedOutWarning': 'Branch is checked out elsewhere', | |
| 'repoLaunch.currentBranch': 'Current branch', | |
| 'repoLaunch.dirtyWarning': 'Dirty worktree', | |
| 'repoLaunch.localBranch': 'Local branch', | |
| 'repoLaunch.missingWorkdir': 'Missing working directory', | |
| 'repoLaunch.noBranch': 'No branch', | |
| 'repoLaunch.noBranchMatch': 'No matching branches', | |
| 'repoLaunch.remoteBranch': 'Remote branch', | |
| 'repoLaunch.searchBranch': 'Search branches', | |
| 'repoLaunch.selectBranch': 'Select branch', | |
| 'repoLaunch.selectWorktree': 'Select worktree mode', | |
| 'repoLaunch.worktreeCurrent': 'Current worktree', | |
| 'repoLaunch.worktreeIsolated': 'Isolated worktree', | |
| 'tabs.close': 'Close', | |
| }[key] ?? key), | |
| })) | |
| import { RepositoryLaunchControls } from './RepositoryLaunchControls' | |
| const okRepositoryContext = { | |
| state: 'ok' as const, | |
| root: '/repo', | |
| currentBranch: 'main', | |
| defaultBranch: 'main', | |
| dirty: false, | |
| branches: [ | |
| { | |
| name: 'main', | |
| current: true, | |
| local: true, | |
| remote: false, | |
| checkedOut: false, | |
| remoteRef: null, | |
| worktreePath: null, | |
| }, | |
| { | |
| name: 'feature/h5', | |
| current: false, | |
| local: true, | |
| remote: false, | |
| checkedOut: false, | |
| remoteRef: null, | |
| worktreePath: null, | |
| }, | |
| ], | |
| } | |
| function renderControls(props: Partial<ComponentProps<typeof RepositoryLaunchControls>> = {}) { | |
| const defaultProps: ComponentProps<typeof RepositoryLaunchControls> = { | |
| workDir: '/repo', | |
| onWorkDirChange: vi.fn(), | |
| branch: 'main', | |
| onBranchChange: vi.fn(), | |
| useWorktree: false, | |
| onUseWorktreeChange: vi.fn(), | |
| } | |
| return render(<RepositoryLaunchControls {...defaultProps} {...props} />) | |
| } | |
| async function openBranchMenu() { | |
| const trigger = await screen.findByRole('button', { name: 'Select branch: main' }) | |
| fireEvent.click(trigger) | |
| return trigger | |
| } | |
| describe('RepositoryLaunchControls', () => { | |
| beforeEach(() => { | |
| viewportMocks.isMobile = false | |
| viewportMocks.isTauri = false | |
| apiMocks.getRepositoryContext.mockReset() | |
| apiMocks.getRepositoryContext.mockResolvedValue(okRepositoryContext) | |
| Element.prototype.scrollIntoView = vi.fn() | |
| }) | |
| it('keeps the desktop branch dropdown when not in mobile browser mode', async () => { | |
| renderControls() | |
| await openBranchMenu() | |
| const listbox = await screen.findByRole('listbox', { name: 'Select branch' }) | |
| expect(listbox).toBeInTheDocument() | |
| expect(screen.queryByRole('dialog', { name: 'Select branch' })).not.toBeInTheDocument() | |
| expect(listbox.parentElement?.className).toContain('w-[390px]') | |
| }) | |
| it('uses the flatter desktop bar when embedded in a composer', async () => { | |
| renderControls({ placement: 'composer' }) | |
| const trigger = await screen.findByRole('button', { name: 'Select branch: main' }) | |
| const bar = trigger.parentElement | |
| expect(bar).toHaveClass('min-h-[44px]', 'bg-transparent') | |
| expect(bar).not.toHaveClass('rounded-b-xl') | |
| expect(bar).not.toHaveClass('bg-[var(--color-surface-container-low)]') | |
| }) | |
| it('uses the full-width mobile bottom sheet in H5 mobile browser mode', async () => { | |
| viewportMocks.isMobile = true | |
| viewportMocks.isTauri = false | |
| renderControls() | |
| await openBranchMenu() | |
| const dialog = await screen.findByRole('dialog', { name: 'Select branch' }) | |
| expect(dialog).toHaveClass('inset-x-0') | |
| expect(screen.getByRole('button', { name: 'Close' })).toBeInTheDocument() | |
| expect(screen.getByRole('listbox', { name: 'Select branch' })).toBeInTheDocument() | |
| }) | |
| it('does not use the H5 mobile sheet inside Tauri even on a narrow viewport', async () => { | |
| viewportMocks.isMobile = true | |
| viewportMocks.isTauri = true | |
| renderControls() | |
| await openBranchMenu() | |
| const listbox = await screen.findByRole('listbox', { name: 'Select branch' }) | |
| expect(listbox).toBeInTheDocument() | |
| expect(screen.queryByRole('dialog', { name: 'Select branch' })).not.toBeInTheDocument() | |
| }) | |
| it('keeps keyboard branch selection working from the search field', async () => { | |
| const onBranchChange = vi.fn() | |
| renderControls({ onBranchChange }) | |
| await openBranchMenu() | |
| const input = await screen.findByPlaceholderText('Search branches') | |
| fireEvent.keyDown(input, { key: 'ArrowDown' }) | |
| fireEvent.keyDown(input, { key: 'Enter' }) | |
| await waitFor(() => { | |
| expect(onBranchChange).toHaveBeenCalledWith('feature/h5') | |
| }) | |
| }) | |
| }) | |