Download desktop/src/components/chat/FileSearchMenu.test.tsx from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 6.15 kB
-
https://huggingface.co/chenbhao/codev/resolve/e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/components/chat/FileSearchMenu.test.tsx
- Command line
-
hf download hf://chenbhao/codev@e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/components/chat/FileSearchMenu.test.tsx
-
curl -L -o FileSearchMenu.test.tsx https://huggingface.co/chenbhao/codev/resolve/e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/components/chat/FileSearchMenu.test.tsx
6.15 kB
| import { describe, expect, it, vi, beforeEach } from 'vitest' | |
| import { fireEvent, render, screen, waitFor } from '@testing-library/react' | |
| import '@testing-library/jest-dom' | |
| import { FileSearchMenu } from './FileSearchMenu' | |
| import { ApiError } from '../../api/client' | |
| import { filesystemApi } from '../../api/filesystem' | |
| import { useSettingsStore } from '../../stores/settingsStore' | |
| vi.mock('../../api/filesystem', () => ({ | |
| filesystemApi: { | |
| browse: vi.fn(), | |
| search: vi.fn(), | |
| }, | |
| })) | |
| describe('FileSearchMenu', () => { | |
| beforeEach(() => { | |
| vi.clearAllMocks() | |
| useSettingsStore.setState({ locale: 'en' }) | |
| }) | |
| it('shows an explicit error when directory browsing is denied', async () => { | |
| vi.mocked(filesystemApi.browse).mockRejectedValueOnce( | |
| new ApiError(403, { error: 'Access denied: path outside allowed directory' }), | |
| ) | |
| render( | |
| <FileSearchMenu | |
| cwd="/private/tmp" | |
| onSelect={() => {}} | |
| />, | |
| ) | |
| expect(await screen.findByText('Cannot access this directory')).toBeInTheDocument() | |
| expect(screen.queryByText('No files in this directory')).not.toBeInTheDocument() | |
| }) | |
| it('renders returned files when browsing succeeds', async () => { | |
| vi.mocked(filesystemApi.browse).mockResolvedValueOnce({ | |
| currentPath: '/tmp', | |
| parentPath: '/', | |
| entries: [ | |
| { name: 'preview.png', path: '/tmp/preview.png', isDirectory: false }, | |
| ], | |
| }) | |
| render( | |
| <FileSearchMenu | |
| cwd="/tmp" | |
| onSelect={() => {}} | |
| />, | |
| ) | |
| await waitFor(() => { | |
| expect(screen.getByText('preview.png')).toBeInTheDocument() | |
| }) | |
| }) | |
| it('selects directories from search results and keeps a separate drill-in action', async () => { | |
| const onSelect = vi.fn() | |
| const onNavigate = vi.fn() | |
| vi.mocked(filesystemApi.search).mockResolvedValueOnce({ | |
| currentPath: '/repo', | |
| parentPath: '/', | |
| query: 'backend', | |
| entries: [ | |
| { name: 'backend', path: '/repo/backend', relativePath: 'backend', isDirectory: true }, | |
| ], | |
| }) | |
| vi.mocked(filesystemApi.browse).mockResolvedValueOnce({ | |
| currentPath: '/repo/backend', | |
| parentPath: '/repo', | |
| entries: [ | |
| { name: 'src', path: '/repo/backend/src', isDirectory: true }, | |
| ], | |
| }) | |
| vi.mocked(filesystemApi.browse).mockResolvedValueOnce({ | |
| currentPath: '/repo/backend/src', | |
| parentPath: '/repo/backend', | |
| entries: [ | |
| { name: 'commands', path: '/repo/backend/src/commands', isDirectory: true }, | |
| ], | |
| }) | |
| render( | |
| <FileSearchMenu | |
| cwd="/repo" | |
| filter="backend" | |
| onSelect={onSelect} | |
| onNavigate={onNavigate} | |
| />, | |
| ) | |
| fireEvent.click(await screen.findByText('backend/')) | |
| expect(onSelect).toHaveBeenCalledWith('/repo/backend', 'backend', true) | |
| expect(onNavigate).not.toHaveBeenCalled() | |
| fireEvent.click(screen.getByLabelText('Open folder')) | |
| expect(onNavigate).toHaveBeenCalledWith('backend/') | |
| await waitFor(() => { | |
| expect(filesystemApi.browse).toHaveBeenCalledWith('/repo/backend', { includeFiles: true }) | |
| }) | |
| fireEvent.click(await screen.findByText('src')) | |
| expect(onSelect).toHaveBeenLastCalledWith('/repo/backend/src', 'backend/src', true) | |
| fireEvent.click(screen.getByLabelText('Open folder')) | |
| expect(onNavigate).toHaveBeenLastCalledWith('backend/src/') | |
| await waitFor(() => { | |
| expect(filesystemApi.browse).toHaveBeenCalledWith('/repo/backend/src', { includeFiles: true }) | |
| }) | |
| }) | |
| it('passes nested relative file paths when selecting a file', async () => { | |
| const onSelect = vi.fn() | |
| vi.mocked(filesystemApi.search).mockResolvedValueOnce({ | |
| currentPath: '/repo', | |
| parentPath: '/', | |
| query: 'pictactic', | |
| entries: [ | |
| { name: 'pictactic', path: '/repo/backend/src/pictactic', relativePath: 'backend/src/pictactic', isDirectory: false }, | |
| ], | |
| }) | |
| render( | |
| <FileSearchMenu | |
| cwd="/repo" | |
| filter="backend/src/pictactic" | |
| onSelect={onSelect} | |
| />, | |
| ) | |
| fireEvent.click(await screen.findByText('backend/src/pictactic')) | |
| expect(onSelect).toHaveBeenCalledWith('/repo/backend/src/pictactic', 'backend/src/pictactic', false) | |
| }) | |
| it('renders search results as insertable paths instead of repeated basenames', async () => { | |
| vi.mocked(filesystemApi.search).mockResolvedValueOnce({ | |
| currentPath: '/repo', | |
| parentPath: '/', | |
| query: 'src', | |
| entries: [ | |
| { name: 'src', path: '/repo/src', relativePath: 'src', isDirectory: true }, | |
| { name: 'hooks', path: '/repo/src/hooks', relativePath: 'src/hooks', isDirectory: true }, | |
| { name: 'src', path: '/repo/desktop/src', relativePath: 'desktop/src', isDirectory: true }, | |
| ], | |
| }) | |
| render( | |
| <FileSearchMenu | |
| cwd="/repo" | |
| filter="src" | |
| onSelect={() => {}} | |
| />, | |
| ) | |
| expect(await screen.findByText('src/')).toBeInTheDocument() | |
| expect(screen.getByText('src/hooks/')).toBeInTheDocument() | |
| expect(screen.getByText('desktop/src/')).toBeInTheDocument() | |
| }) | |
| it('uses the resolved home root for typed folder filters when no workspace is selected', async () => { | |
| vi.mocked(filesystemApi.search).mockResolvedValueOnce({ | |
| currentPath: '/Users/nanmi', | |
| parentPath: '/', | |
| query: 'workspace', | |
| entries: [ | |
| { name: 'workspace', path: '/Users/nanmi/workspace', relativePath: 'workspace', isDirectory: true }, | |
| ], | |
| }) | |
| vi.mocked(filesystemApi.browse).mockResolvedValueOnce({ | |
| currentPath: '/Users/nanmi/workspace', | |
| parentPath: '/Users/nanmi', | |
| entries: [], | |
| }) | |
| const { rerender } = render( | |
| <FileSearchMenu | |
| cwd="" | |
| filter="workspace" | |
| onSelect={() => {}} | |
| />, | |
| ) | |
| expect(await screen.findByText('workspace/')).toBeInTheDocument() | |
| rerender( | |
| <FileSearchMenu | |
| cwd="" | |
| filter="workspace/" | |
| onSelect={() => {}} | |
| />, | |
| ) | |
| await waitFor(() => { | |
| expect(filesystemApi.browse).toHaveBeenCalledWith('/Users/nanmi/workspace', { includeFiles: true }) | |
| }) | |
| }) | |
| }) | |