Skip to content

Commit 91123d9

Browse files
committed
wip: commit current progress on useClipboard test
1 parent d1dd31a commit 91123d9

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

site/src/hooks/useClipboard.test.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { type UseClipboardResult, useClipboard } from "./useClipboard";
2+
import { act, renderHook } from "@testing-library/react";
3+
import userEvent from "@testing-library/user-event";
4+
5+
beforeAll(() => {
6+
jest.useFakeTimers();
7+
userEvent.setup({
8+
writeToClipboard: true,
9+
});
10+
});
11+
12+
afterAll(() => {
13+
jest.useRealTimers();
14+
jest.restoreAllMocks();
15+
});
16+
17+
function renderUseClipboard(textToCopy: string) {
18+
type Props = Readonly<{ textToCopy: string }>;
19+
20+
return renderHook<UseClipboardResult, Props>(
21+
({ textToCopy }) => useClipboard(textToCopy),
22+
{ initialProps: { textToCopy } },
23+
);
24+
}
25+
26+
type UseClipboardTestResult = ReturnType<typeof renderUseClipboard>["result"];
27+
28+
// This can and should be cleaned up - trying to call the clipboard's readText
29+
// method caused an error around blob input, even though the method takes no
30+
// arguments whatsoever, so here's this workaround using the lower-level API
31+
async function assertClipboardTextUpdate(
32+
result: UseClipboardTestResult,
33+
textToCheck: string,
34+
): Promise<void> {
35+
await act(() => result.current.copyToClipboard());
36+
expect(result.current.showCopiedSuccess).toBe(true);
37+
38+
const clipboardTextType = "text/plain";
39+
const clipboardItems = await window.navigator.clipboard.read();
40+
const firstItem = clipboardItems[0];
41+
42+
const hasData =
43+
firstItem !== undefined && firstItem.types.includes(clipboardTextType);
44+
45+
if (!hasData) {
46+
throw new Error("No clipboard items to process");
47+
}
48+
49+
const blob = await firstItem.getType(clipboardTextType);
50+
const clipboardText = await blob.text();
51+
expect(textToCheck).toEqual(clipboardText);
52+
}
53+
54+
describe(useClipboard.name, () => {
55+
it("Copies the current text to the user's clipboard", async () => {
56+
const hookText = "dogs";
57+
const { result } = renderUseClipboard(hookText);
58+
await assertClipboardTextUpdate(result, hookText);
59+
});
60+
61+
it("Should indicate to components not to show successful copy after a set period of time", async () => {
62+
const hookText = "cats";
63+
const { result } = renderUseClipboard(hookText);
64+
await assertClipboardTextUpdate(result, hookText);
65+
66+
setTimeout(() => {
67+
expect(result.current.showCopiedSuccess).toBe(false);
68+
}, 10_000);
69+
70+
await jest.runAllTimersAsync();
71+
});
72+
73+
it.skip("Should notify the user that a copy was not successful", () => {
74+
expect.hasAssertions();
75+
});
76+
77+
it.skip("Should work on non-secure (HTTP-only) connections", async () => {
78+
const prevClipboard = window.navigator.clipboard;
79+
80+
Object.assign(window.navigator, {
81+
clipboard: {
82+
...prevClipboard,
83+
writeText: async () => {
84+
throw new Error(
85+
"Trying to call clipboard API in non-secure context!",
86+
);
87+
},
88+
},
89+
});
90+
91+
const hookText = "birds";
92+
const { result } = renderUseClipboard(hookText);
93+
await assertClipboardTextUpdate(result, hookText);
94+
});
95+
});

0 commit comments

Comments
 (0)