mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-09 03:09:33 -06:00
122 lines
4.2 KiB
TypeScript
122 lines
4.2 KiB
TypeScript
import { cleanup, render, screen } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import Prism from "prismjs";
|
|
import toast from "react-hot-toast";
|
|
import { afterEach, describe, expect, test, vi } from "vitest";
|
|
import { CodeBlock } from "./index";
|
|
|
|
// Import toast
|
|
|
|
// Mock Prism.js
|
|
vi.mock("prismjs", () => ({
|
|
default: {
|
|
highlightAll: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
// Mock react-hot-toast
|
|
vi.mock("react-hot-toast", async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import("react-hot-toast")>();
|
|
return {
|
|
...actual,
|
|
default: {
|
|
success: vi.fn(), // Mock toast.success directly here
|
|
},
|
|
};
|
|
});
|
|
|
|
describe("CodeBlock", () => {
|
|
afterEach(() => {
|
|
cleanup();
|
|
vi.resetAllMocks(); // Reset mocks to avoid interference between tests
|
|
});
|
|
|
|
test("renders children and applies language class", () => {
|
|
const codeSnippet = "const greeting = 'Hello, world!';";
|
|
const language = "javascript";
|
|
render(<CodeBlock language={language}>{codeSnippet}</CodeBlock>);
|
|
|
|
const codeElement = screen.getByText(codeSnippet);
|
|
expect(codeElement).toBeInTheDocument();
|
|
expect(codeElement).toHaveClass(`language-${language}`);
|
|
});
|
|
|
|
test("calls Prism.highlightAll on render and when children change", () => {
|
|
const codeSnippet = "const greeting = 'Hello, world!';";
|
|
const language = "javascript";
|
|
const { rerender } = render(<CodeBlock language={language}>{codeSnippet}</CodeBlock>);
|
|
expect(Prism.highlightAll).toHaveBeenCalledTimes(1);
|
|
|
|
const newCodeSnippet = "const newGreeting = 'Hello, Vitest!';";
|
|
rerender(<CodeBlock language={language}>{newCodeSnippet}</CodeBlock>);
|
|
expect(Prism.highlightAll).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
test("copies code to clipboard when copy icon is clicked", async () => {
|
|
const user = userEvent.setup();
|
|
const codeSnippet = "console.log('Copy me!');";
|
|
const language = "typescript";
|
|
render(<CodeBlock language={language}>{codeSnippet}</CodeBlock>);
|
|
|
|
// Store the original clipboard
|
|
const originalClipboard = navigator.clipboard;
|
|
// Mock clipboard API for this test
|
|
Object.defineProperty(navigator, "clipboard", {
|
|
value: {
|
|
writeText: vi.fn().mockResolvedValue(undefined),
|
|
},
|
|
writable: true,
|
|
configurable: true, // Allow redefining for cleanup
|
|
});
|
|
|
|
// Find the copy icon by its role and accessible name (if any) or by a more robust selector
|
|
// If the icon itself doesn't have a role or accessible name, find its container
|
|
const copyButtonContainer = screen.getByTestId("copy-icon"); // Assuming the button or its container has an accessible name like "Copy to clipboard"
|
|
expect(copyButtonContainer).toBeInTheDocument();
|
|
|
|
await user.click(copyButtonContainer);
|
|
|
|
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(codeSnippet);
|
|
// Use the imported toast for assertion
|
|
expect(vi.mocked(toast.success)).toHaveBeenCalledWith("common.copied_to_clipboard");
|
|
|
|
// Restore the original clipboard
|
|
Object.defineProperty(navigator, "clipboard", {
|
|
value: originalClipboard,
|
|
writable: true,
|
|
});
|
|
});
|
|
|
|
test("does not show copy to clipboard button when showCopyToClipboard is false", () => {
|
|
const codeSnippet = "const secret = 'Do not copy!';";
|
|
const language = "text";
|
|
render(
|
|
<CodeBlock language={language} showCopyToClipboard={false}>
|
|
{codeSnippet}
|
|
</CodeBlock>
|
|
);
|
|
// Check if the copy button is not present
|
|
const copyButton = screen.queryByTestId("copy-icon");
|
|
expect(copyButton).not.toBeInTheDocument();
|
|
});
|
|
|
|
test("applies custom editor and code classes", () => {
|
|
const codeSnippet = "<p>Custom classes</p>";
|
|
const language = "html";
|
|
const customEditorClass = "custom-editor";
|
|
const customCodeClass = "custom-code";
|
|
render(
|
|
<CodeBlock language={language} customEditorClass={customEditorClass} customCodeClass={customCodeClass}>
|
|
{codeSnippet}
|
|
</CodeBlock>
|
|
);
|
|
|
|
const preElement = screen.getByText(codeSnippet).closest("pre");
|
|
expect(preElement).toHaveClass(customEditorClass);
|
|
|
|
const codeElement = screen.getByText(codeSnippet);
|
|
expect(codeElement).toHaveClass(`language-${language}`);
|
|
expect(codeElement).toHaveClass(customCodeClass);
|
|
});
|
|
});
|