55 lines
2.3 KiB
TypeScript
55 lines
2.3 KiB
TypeScript
// @vitest-environment jsdom
|
|
//
|
|
// A Copy button beside its value: "Copied" for a moment and a notice a screen reader hears, or a
|
|
// warning when the clipboard refused — the same at every such button.
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { act, renderHook } from "@testing-library/react";
|
|
|
|
const h = vi.hoisted(() => ({ copyText: vi.fn(async (_t: string) => true), notify: vi.fn() }));
|
|
vi.mock("react-i18next", async (importOriginal) => ({
|
|
...(await importOriginal<typeof import("react-i18next")>()),
|
|
useTranslation: () => ({ i18n: { language: "en" }, t: (key: string) => key }),
|
|
}));
|
|
vi.mock("../lib/clipboard", () => ({ copyText: h.copyText }));
|
|
vi.mock("../lib/notifications", () => ({ notify: h.notify }));
|
|
|
|
import { useCopyFeedback } from "./useCopyFeedback";
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
h.notify.mockClear();
|
|
});
|
|
|
|
describe("useCopyFeedback", () => {
|
|
it("a copy that worked reads Copied for a moment and is said out loud", async () => {
|
|
vi.useFakeTimers();
|
|
const { result } = renderHook(() => useCopyFeedback());
|
|
await act(() => result.current.copy("sfl_x"));
|
|
expect(h.copyText).toHaveBeenCalledWith("sfl_x");
|
|
expect(result.current.copied).toBe(true);
|
|
expect(h.notify).toHaveBeenCalledWith({ level: "success", message: "common.copy.done" });
|
|
act(() => void vi.advanceTimersByTime(2000));
|
|
expect(result.current.copied).toBe(false);
|
|
});
|
|
|
|
it("a copy again within the moment reads Copied for a whole moment again", async () => {
|
|
vi.useFakeTimers();
|
|
const { result } = renderHook(() => useCopyFeedback());
|
|
await act(() => result.current.copy("sfl_x"));
|
|
act(() => void vi.advanceTimersByTime(1500));
|
|
await act(() => result.current.copy("sfl_x"));
|
|
act(() => void vi.advanceTimersByTime(1000)); // past the first copy's moment
|
|
expect(result.current.copied).toBe(true);
|
|
act(() => void vi.advanceTimersByTime(1000));
|
|
expect(result.current.copied).toBe(false);
|
|
});
|
|
|
|
it("a copy the clipboard refused is a warning, and nothing reads Copied", async () => {
|
|
h.copyText.mockResolvedValueOnce(false);
|
|
const { result } = renderHook(() => useCopyFeedback());
|
|
await act(() => result.current.copy("sfl_x"));
|
|
expect(result.current.copied).toBe(false);
|
|
expect(h.notify).toHaveBeenCalledWith({ level: "warning", message: "common.copy.failed" });
|
|
});
|
|
});
|