Skip to content

Commit aa75e22

Browse files
committed
test(copyrepobutton): add error resilience coverage
1 parent aed644b commit aa75e22

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
2+
import { describe, expect, it, vi, beforeEach } from 'vitest';
3+
4+
import CopyRepoButton from './CopyRepoButton';
5+
6+
vi.mock('lucide-react', () => ({
7+
Copy: () => <svg data-testid="copy-icon" />,
8+
}));
9+
10+
describe('CopyRepoButton error resilience', () => {
11+
beforeEach(() => {
12+
vi.restoreAllMocks();
13+
});
14+
15+
it('renders successfully during initial mount', () => {
16+
render(<CopyRepoButton />);
17+
18+
expect(screen.getByRole('button', { name: /copy url/i })).toBeDefined();
19+
});
20+
21+
it('does not crash when clipboard write rejects', async () => {
22+
Object.assign(navigator, {
23+
clipboard: {
24+
writeText: vi.fn().mockRejectedValue(new Error('Clipboard failed')),
25+
},
26+
});
27+
28+
render(<CopyRepoButton />);
29+
30+
fireEvent.click(screen.getByRole('button'));
31+
32+
await waitFor(() => {
33+
expect(screen.getByRole('button')).toBeDefined();
34+
});
35+
});
36+
37+
it('keeps original label visible after clipboard failure', async () => {
38+
Object.assign(navigator, {
39+
clipboard: {
40+
writeText: vi.fn().mockRejectedValue(new Error('Clipboard failed')),
41+
},
42+
});
43+
44+
render(<CopyRepoButton />);
45+
46+
fireEvent.click(screen.getByRole('button'));
47+
48+
await waitFor(() => {
49+
expect(screen.getByText(/copy url/i)).toBeDefined();
50+
});
51+
});
52+
53+
it('renders icon even when copy action fails', async () => {
54+
Object.assign(navigator, {
55+
clipboard: {
56+
writeText: vi.fn().mockRejectedValue(new Error('Clipboard failed')),
57+
},
58+
});
59+
60+
render(<CopyRepoButton />);
61+
62+
fireEvent.click(screen.getByRole('button'));
63+
64+
await waitFor(() => {
65+
expect(screen.getByTestId('copy-icon')).toBeDefined();
66+
});
67+
});
68+
69+
it('allows repeated failed copy attempts without crashing', async () => {
70+
Object.assign(navigator, {
71+
clipboard: {
72+
writeText: vi.fn().mockRejectedValue(new Error('Clipboard failed')),
73+
},
74+
});
75+
76+
render(<CopyRepoButton />);
77+
78+
const button = screen.getByRole('button');
79+
80+
fireEvent.click(button);
81+
fireEvent.click(button);
82+
fireEvent.click(button);
83+
84+
await waitFor(() => {
85+
expect(screen.getByRole('button')).toBeDefined();
86+
});
87+
});
88+
});

0 commit comments

Comments
 (0)