diff --git a/app/generator/components/PreviewPanel.mock-integrations.test.tsx b/app/generator/components/PreviewPanel.mock-integrations.test.tsx new file mode 100644 index 000000000..12f1a3c9d --- /dev/null +++ b/app/generator/components/PreviewPanel.mock-integrations.test.tsx @@ -0,0 +1,104 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { render, screen, fireEvent, waitFor } from '@testing-library/react'; +import { PreviewPanel } from './PreviewPanel'; + +vi.mock('@/utils/clipboard', () => ({ + fallbackCopyToClipboard: vi.fn(() => true), +})); + +describe('PreviewPanel Mock Integrations', () => { + const markdown = '# CommitPulse\nMock integration test'; + + beforeEach(() => { + Object.assign(navigator, { + clipboard: { + writeText: vi.fn().mockResolvedValue(undefined), + }, + }); + + Object.defineProperty(window, 'isSecureContext', { + value: true, + configurable: true, + }); + + vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock'); + vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => {}); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('1. copies markdown using mocked clipboard service', async () => { + render(); + + fireEvent.click( + screen.getByRole('button', { + name: /copy markdown text to clipboard/i, + }) + ); + + await waitFor(() => { + expect(navigator.clipboard.writeText).toHaveBeenCalledWith(markdown); + }); + }); + + it('2. downloads markdown using mocked browser APIs', () => { + const clickMock = vi.fn(); + + const originalCreateElement = document.createElement.bind(document); + + vi.spyOn(document, 'createElement').mockImplementation((tagName: string) => { + if (tagName === 'a') { + const anchor = originalCreateElement('a'); + anchor.click = clickMock; + return anchor; + } + + return originalCreateElement(tagName); + }); + + render(); + + fireEvent.click( + screen.getByRole('button', { + name: /download readme\.md/i, + }) + ); + + expect(URL.createObjectURL).toHaveBeenCalled(); + expect(clickMock).toHaveBeenCalled(); + }); + + it('3. renders preview content while integrations are mocked', () => { + render(); + + expect(screen.getByRole('tabpanel')).toBeInTheDocument(); + expect(screen.getByText('README.md')).toBeInTheDocument(); + }); + + it('4. switches between preview and markdown tabs', () => { + render(); + + fireEvent.click(screen.getByRole('tab', { name: /markdown/i })); + + expect(screen.getByRole('tabpanel')).toBeInTheDocument(); + expect(screen.getByText(/CommitPulse/)).toBeInTheDocument(); + expect(screen.getByText(/Mock integration test/)).toBeInTheDocument(); + }); + + it('5. keeps mocked services isolated across repeated interactions', async () => { + render(); + + const copyButton = screen.getByRole('button', { + name: /copy markdown text to clipboard/i, + }); + + fireEvent.click(copyButton); + fireEvent.click(copyButton); + + await waitFor(() => { + expect(navigator.clipboard.writeText).toHaveBeenCalledTimes(2); + }); + }); +});