mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
Changed-file rows are easier to scan when previewable files are grouped before source-only files, and the file open-with menu should only expose useful preview, editor, and reveal actions. Output target cards also no longer need a separate copy control now that open/open-with are the primary actions. Constraint: Keep the existing open-with API and menu components shared across changed files, workspace context menus, and output target cards. Rejected: Keep system-default open for files | it duplicated less predictable platform behavior and added a low-value final menu item. Confidence: high Scope-risk: narrow Directive: File open-with menus should stay ordered by immediate preview/open usefulness before editor and reveal actions. Tested: cd desktop && bun run test src/lib/openWithItems.test.ts src/components/workspace/WorkspaceFileOpenWith.test.tsx src/components/chat/AssistantOutputTargetCard.test.tsx src/components/chat/CurrentTurnChangeCard.test.tsx Tested: cd desktop && bun run lint Tested: cd desktop && bun run build Tested: git diff --check
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
// @vitest-environment jsdom
|
|
import '@testing-library/jest-dom'
|
|
import { render, fireEvent } from '@testing-library/react'
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
|
|
const openTarget = vi.hoisted(() => vi.fn())
|
|
const shellOpen = vi.hoisted(() => vi.fn().mockResolvedValue(undefined))
|
|
|
|
vi.mock('../../stores/openTargetStore', () => ({
|
|
useOpenTargetStore: (sel: (s: unknown) => unknown) =>
|
|
sel({
|
|
targets: [
|
|
{ id: 'code', kind: 'ide', label: 'VS Code', icon: '', platform: 'darwin' },
|
|
{ id: 'finder', kind: 'file_manager', label: 'Finder', icon: '', platform: 'darwin' },
|
|
],
|
|
ensureTargets: () => {},
|
|
openTarget,
|
|
}),
|
|
}))
|
|
|
|
vi.mock('@tauri-apps/plugin-shell', () => ({ open: shellOpen }))
|
|
|
|
vi.mock('../../i18n', () => ({
|
|
useTranslation: () => (k: string, v?: Record<string, string>) =>
|
|
v?.target ? `${k}:${v.target}` : k,
|
|
}))
|
|
|
|
import { WorkspaceFileOpenWith } from './WorkspaceFileOpenWith'
|
|
|
|
describe('WorkspaceFileOpenWith', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('renders only IDE and file-manager items', () => {
|
|
const { getAllByRole } = render(
|
|
<WorkspaceFileOpenWith absolutePath="/w/report.md" />,
|
|
)
|
|
|
|
const menuItems = getAllByRole('menuitem')
|
|
expect(menuItems).toHaveLength(2)
|
|
|
|
const labels = menuItems.map((el) => el.textContent)
|
|
expect(labels.some((l) => l?.includes('VS Code'))).toBe(true)
|
|
expect(labels.some((l) => l?.includes('Finder'))).toBe(true)
|
|
expect(labels.some((l) => l?.includes('openWith.systemDefault'))).toBe(false)
|
|
})
|
|
|
|
it('clicking the IDE item calls openTarget and onAfterSelect', () => {
|
|
const onAfter = vi.fn()
|
|
const { getAllByRole } = render(
|
|
<WorkspaceFileOpenWith absolutePath="/w/report.md" onAfterSelect={onAfter} />,
|
|
)
|
|
|
|
const menuItems = getAllByRole('menuitem')
|
|
const ideItem = menuItems.find((el) => el.textContent?.includes('VS Code'))
|
|
if (!ideItem) throw new Error('IDE menu item not found')
|
|
|
|
fireEvent.click(ideItem)
|
|
|
|
expect(openTarget).toHaveBeenCalledWith('code', '/w/report.md')
|
|
expect(onAfter).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('does not call shell open from the file open-with menu', () => {
|
|
render(<WorkspaceFileOpenWith absolutePath="/w/report.md" />)
|
|
expect(shellOpen).not.toHaveBeenCalled()
|
|
})
|
|
})
|