import '@testing-library/jest-dom' import { fireEvent, render, screen } from '@testing-library/react' import { afterEach, describe, expect, it, vi } from 'vitest' const { openBrowser } = vi.hoisted(() => ({ openBrowser: vi.fn() })) vi.mock('../../stores/browserPanelStore', () => ({ useBrowserPanelStore: { getState: () => ({ open: openBrowser }) }, })) vi.mock('../../lib/desktopRuntime', async (orig) => ({ ...(await orig>()), getServerBaseUrl: () => 'http://127.0.0.1:4321', })) const ensureTargets = vi.hoisted(() => vi.fn().mockResolvedValue(undefined)) const openTargetFn = vi.hoisted(() => vi.fn()) vi.mock('../../stores/openTargetStore', () => ({ useOpenTargetStore: { getState: () => ({ ensureTargets, targets: [], openTarget: openTargetFn }), }, })) const openPreviewFn = vi.hoisted(() => vi.fn().mockResolvedValue(undefined)) vi.mock('../../stores/workspacePanelStore', () => ({ useWorkspacePanelStore: { getState: () => ({ statusBySession: {}, openPreview: openPreviewFn }), }, })) const shellOpen = vi.hoisted(() => vi.fn().mockResolvedValue(undefined)) vi.mock('@tauri-apps/plugin-shell', () => ({ open: shellOpen })) // Mock i18n — return the key (plus interpolation) so we can assert on keys vi.mock('../../i18n', () => ({ useTranslation: () => (k: string, v?: Record) => (v?.target ? `${k}:${v.target}` : k), })) import { AssistantOutputTargetCard } from './AssistantOutputTargetCard' import type { AssistantOutputTarget } from '../../lib/assistantOutputTargets' const markdownTarget: AssistantOutputTarget = { id: 'markdown:docs/readme.md', kind: 'markdown', title: 'readme.md', subtitle: 'docs/readme.md', href: 'docs/readme.md', normalizedPath: 'docs/readme.md', confidence: 'high', source: 'markdown-link', } const localhostTarget: AssistantOutputTarget = { id: 'localhost-url:http://localhost:5173/', kind: 'localhost-url', title: 'http://localhost:5173/', href: 'http://localhost:5173/', confidence: 'high', source: 'plain-url', } afterEach(() => { openBrowser.mockReset() ensureTargets.mockReset().mockResolvedValue(undefined) openTargetFn.mockReset() openPreviewFn.mockReset().mockResolvedValue(undefined) shellOpen.mockReset().mockResolvedValue(undefined) }) describe('AssistantOutputTargetCard', () => { it('renders a markdown target title + Markdown badge', () => { render() expect(screen.getByText('readme.md')).toBeInTheDocument() expect(screen.getByText('assistantOutputs.kind.markdown')).toBeInTheDocument() expect(screen.getByText('docs/readme.md')).toBeInTheDocument() }) it('renders a localhost target title + Localhost badge', () => { render() // Title + subtitle both fall back to href, so it appears twice. expect(screen.getAllByText('http://localhost:5173/').length).toBeGreaterThan(0) expect(screen.getByText('assistantOutputs.kind.localhost')).toBeInTheDocument() }) it('routes Open to workspace preview for a markdown target', () => { render() fireEvent.click(screen.getByLabelText('assistantOutputs.open')) expect(openPreviewFn).toHaveBeenCalledWith('s1', 'docs/readme.md', 'file') }) it('routes Open to the in-app browser for a localhost target', () => { render() fireEvent.click(screen.getByLabelText('assistantOutputs.open')) expect(openBrowser).toHaveBeenCalledWith('s1', 'http://localhost:5173/') }) it('copies the normalized path when Copy is clicked', () => { const writeText = vi.fn().mockResolvedValue(undefined) Object.assign(navigator, { clipboard: { writeText } }) render() fireEvent.click(screen.getByLabelText('assistantOutputs.copy')) expect(writeText).toHaveBeenCalledWith('docs/readme.md') }) it('opens the open-with menu with URL items for a localhost target', async () => { render() fireEvent.click(screen.getByLabelText('openWith.title')) expect(await screen.findByText('openWith.inAppBrowser')).toBeInTheDocument() expect(screen.getByText('openWith.systemBrowser')).toBeInTheDocument() }) })