mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-02 10:00:17 +05:30
74 lines
3.0 KiB
TypeScript
74 lines
3.0 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { render, screen } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { FindInFilesDialog } from '@/components/modals/FindInFilesDialog';
|
|
import { useFileStore } from '@/stores/file-store';
|
|
|
|
vi.mock('@/lib/ipc', () => ({
|
|
ipc: {
|
|
file: {
|
|
search: vi.fn(),
|
|
},
|
|
},
|
|
}));
|
|
|
|
import { ipc } from '@/lib/ipc';
|
|
import { useAppStore } from '@/stores/app-store';
|
|
|
|
describe('FindInFilesDialog', () => {
|
|
beforeEach(() => {
|
|
localStorage.clear();
|
|
vi.clearAllMocks();
|
|
useFileStore.setState({ rootPath: '/project' } as any);
|
|
useAppStore.setState({ modal: { kind: null } } as any);
|
|
});
|
|
|
|
it('renders with a query input and toggles', () => {
|
|
render(<FindInFilesDialog />);
|
|
expect(screen.getByText(/find in files/i)).toBeInTheDocument();
|
|
expect(screen.getByRole('textbox', { name: /query/i })).toBeInTheDocument();
|
|
expect(screen.getByRole('checkbox', { name: /regex/i })).toBeInTheDocument();
|
|
expect(screen.getByRole('checkbox', { name: /case/i })).toBeInTheDocument();
|
|
expect(screen.getByRole('button', { name: /search/i })).toBeInTheDocument();
|
|
});
|
|
|
|
it('submits a search and shows results', async () => {
|
|
(ipc.file.search as any).mockResolvedValueOnce({
|
|
ok: true,
|
|
data: [
|
|
{ filePath: '/project/a.md', line: 5, content: 'matching line' },
|
|
{ filePath: '/project/b.md', line: 12, content: 'another match' },
|
|
],
|
|
});
|
|
render(<FindInFilesDialog />);
|
|
await userEvent.type(screen.getByRole('textbox', { name: /query/i }), 'match');
|
|
await userEvent.click(screen.getByRole('button', { name: /search/i }));
|
|
expect(await screen.findByText('/project/a.md:5')).toBeInTheDocument();
|
|
expect(await screen.findByText(/another match/)).toBeInTheDocument();
|
|
});
|
|
|
|
it('clicking a result calls useFileStore.openFile', async () => {
|
|
(ipc.file.search as any).mockResolvedValueOnce({
|
|
ok: true,
|
|
data: [{ filePath: '/project/a.md', line: 5, content: 'matching line' }],
|
|
});
|
|
const openFileSpy = vi.fn();
|
|
useFileStore.setState({ openFile: openFileSpy, rootPath: '/project' } as any);
|
|
render(<FindInFilesDialog />);
|
|
await userEvent.type(screen.getByRole('textbox', { name: /query/i }), 'match');
|
|
await userEvent.click(screen.getByRole('button', { name: /search/i }));
|
|
const result = await screen.findByText('/project/a.md:5');
|
|
await userEvent.click(result);
|
|
// openFile is called with the filePath; the test verifies it was called
|
|
expect(openFileSpy).toHaveBeenCalled();
|
|
});
|
|
|
|
it('shows an error banner when search fails', async () => {
|
|
(ipc.file.search as any).mockResolvedValueOnce({ ok: false, error: { code: 'E', message: 'regex invalid' } });
|
|
render(<FindInFilesDialog />);
|
|
await userEvent.paste('[invalid', { initialSelectionStart: 0, initialSelectionEnd: 0 });
|
|
await userEvent.click(screen.getByRole('button', { name: /search/i }));
|
|
expect(await screen.findByText(/regex invalid/i)).toBeInTheDocument();
|
|
});
|
|
});
|