File size: 3,757 Bytes
1f21206 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import '@testing-library/jest-dom'
vi.mock('../../i18n', () => ({
useTranslation: () => (key: string, params?: Record<string, string | number>) => {
const template = {
'openProject.openIn': 'Open in {target}',
'openProject.openProject': 'Open project',
'openProject.openFailed': 'Could not open project',
}[key] ?? key
if (!params) return template
return Object.entries(params).reduce(
(text, [name, value]) => text.replaceAll(`{${name}}`, String(value)),
template,
)
},
}))
const storeMocks = vi.hoisted(() => ({
ensureTargets: vi.fn(),
openTarget: vi.fn(),
state: {
targets: [] as Array<{
id: string
kind: 'ide' | 'file_manager'
label: string
icon: string
iconUrl?: string
platform: string
}>,
primaryTargetId: null as string | null,
loading: false,
error: null as string | null,
},
}))
vi.mock('../../stores/openTargetStore', () => ({
useOpenTargetStore: (
selector: (state: typeof storeMocks.state & {
ensureTargets: typeof storeMocks.ensureTargets
openTarget: typeof storeMocks.openTarget
}) => unknown,
) => selector({
...storeMocks.state,
ensureTargets: storeMocks.ensureTargets,
openTarget: storeMocks.openTarget,
}),
}))
import { OpenProjectMenu } from './OpenProjectMenu'
describe('OpenProjectMenu', () => {
beforeEach(() => {
storeMocks.ensureTargets.mockReset()
storeMocks.openTarget.mockReset()
storeMocks.state = {
targets: [],
primaryTargetId: null,
loading: false,
error: null,
}
})
it('renders a single Finder action when only file manager is detected', async () => {
storeMocks.state.targets = [{ id: 'finder', kind: 'file_manager', label: 'Finder', icon: 'finder', platform: 'darwin' }]
storeMocks.state.primaryTargetId = 'finder'
storeMocks.openTarget.mockResolvedValue(undefined)
render(<OpenProjectMenu path="/repo" />)
await waitFor(() => expect(storeMocks.ensureTargets).toHaveBeenCalled())
await act(async () => {
fireEvent.click(screen.getByRole('button', { name: 'Open in Finder' }))
})
expect(storeMocks.openTarget).toHaveBeenCalledWith('finder', '/repo')
expect(screen.queryByRole('menu')).not.toBeInTheDocument()
})
it('renders a dropdown with detected IDEs and Finder', async () => {
storeMocks.state.targets = [
{ id: 'vscode', kind: 'ide', label: 'VS Code', icon: 'vscode', iconUrl: '/api/open-targets/icons/vscode', platform: 'darwin' },
{ id: 'finder', kind: 'file_manager', label: 'Finder', icon: 'finder', iconUrl: '/api/open-targets/icons/finder', platform: 'darwin' },
]
storeMocks.state.primaryTargetId = 'vscode'
storeMocks.openTarget.mockResolvedValue(undefined)
const { container } = render(<OpenProjectMenu path="/repo" />)
await act(async () => {
fireEvent.click(screen.getByRole('button', { name: 'Open project' }))
})
expect(screen.getByRole('menu')).toBeInTheDocument()
expect([
...Array.from(container.querySelectorAll('img')),
...Array.from(document.body.querySelectorAll('[role="menu"] img')),
].map((img) => img.getAttribute('src'))).toContain('/api/open-targets/icons/vscode')
await act(async () => {
fireEvent.click(screen.getByRole('menuitem', { name: 'Finder' }))
})
expect(storeMocks.openTarget).toHaveBeenCalledWith('finder', '/repo')
})
it('does not render without a path', () => {
const { container } = render(<OpenProjectMenu path={null} />)
expect(container).toBeEmptyDOMElement()
})
})
|