143 lines
4.4 KiB
TypeScript
143 lines
4.4 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
import { screen, fireEvent, waitFor } from "@testing-library/react";
|
|
import "@testing-library/jest-dom/vitest";
|
|
import { renderWithProviders } from "../utils/test-utils";
|
|
import Login from "../../app/components/modals/Login";
|
|
|
|
describe("Login", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it("uses blurredYellow backdrop by default (header overlay)", async () => {
|
|
renderWithProviders(
|
|
<Login isOpen onClose={vi.fn()} ariaLabelledBy="login-modal-heading">
|
|
<p id="login-modal-heading">Login content</p>
|
|
</Login>,
|
|
);
|
|
await waitFor(() => {
|
|
expect(screen.getByRole("dialog")).toBeInTheDocument();
|
|
});
|
|
const backdrop = screen.getByRole("dialog").parentElement;
|
|
expect(backdrop).toHaveClass("backdrop-blur-md");
|
|
});
|
|
|
|
it("uses solid backdrop when backdropVariant is solid (/login page)", async () => {
|
|
renderWithProviders(
|
|
<Login
|
|
isOpen
|
|
onClose={vi.fn()}
|
|
ariaLabelledBy="login-modal-heading"
|
|
backdropVariant="solid"
|
|
>
|
|
<p id="login-modal-heading">Login content</p>
|
|
</Login>,
|
|
);
|
|
await waitFor(() => {
|
|
expect(screen.getByRole("dialog")).toBeInTheDocument();
|
|
});
|
|
const backdrop = screen.getByRole("dialog").parentElement;
|
|
expect(backdrop).not.toHaveClass("backdrop-blur-md");
|
|
});
|
|
|
|
it("renders dialog when open and portal is ready", async () => {
|
|
renderWithProviders(
|
|
<Login isOpen onClose={vi.fn()} ariaLabelledBy="login-modal-heading">
|
|
<p id="login-modal-heading">Login content</p>
|
|
</Login>,
|
|
);
|
|
await waitFor(() => {
|
|
expect(screen.getByRole("dialog")).toBeInTheDocument();
|
|
});
|
|
expect(screen.getByText("Login content")).toBeInTheDocument();
|
|
});
|
|
|
|
it("does not render dialog when closed", () => {
|
|
renderWithProviders(
|
|
<Login
|
|
isOpen={false}
|
|
onClose={vi.fn()}
|
|
ariaLabelledBy="login-modal-heading"
|
|
>
|
|
<p>Hidden</p>
|
|
</Login>,
|
|
);
|
|
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("portals overlay outside the rendered subtree by default", async () => {
|
|
const { container } = renderWithProviders(
|
|
<div data-testid="inline-root">
|
|
<Login isOpen onClose={vi.fn()} ariaLabelledBy="login-modal-heading">
|
|
<p id="login-modal-heading">Portaled</p>
|
|
</Login>
|
|
</div>,
|
|
);
|
|
await waitFor(() => {
|
|
expect(screen.getByRole("dialog")).toBeInTheDocument();
|
|
});
|
|
const dialog = screen.getByRole("dialog");
|
|
expect(
|
|
container.querySelector('[data-testid="inline-root"]')?.contains(dialog),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("calls onClose when close button is clicked", async () => {
|
|
const onClose = vi.fn();
|
|
renderWithProviders(
|
|
<Login isOpen onClose={onClose} ariaLabelledBy="login-modal-heading">
|
|
<p id="login-modal-heading">Body</p>
|
|
</Login>,
|
|
);
|
|
await waitFor(() => {
|
|
expect(screen.getByRole("dialog")).toBeInTheDocument();
|
|
});
|
|
fireEvent.click(screen.getByLabelText("Close dialog"));
|
|
expect(onClose).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("calls onClose when Escape is pressed", async () => {
|
|
const onClose = vi.fn();
|
|
renderWithProviders(
|
|
<Login isOpen onClose={onClose} ariaLabelledBy="login-modal-heading">
|
|
<p id="login-modal-heading">Body</p>
|
|
</Login>,
|
|
);
|
|
await waitFor(() => {
|
|
expect(screen.getByRole("dialog")).toBeInTheDocument();
|
|
});
|
|
fireEvent.keyDown(document, { key: "Escape" });
|
|
expect(onClose).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("locks body scroll while open", async () => {
|
|
renderWithProviders(
|
|
<Login isOpen onClose={vi.fn()} ariaLabelledBy="login-modal-heading">
|
|
<p id="login-modal-heading">Body</p>
|
|
</Login>,
|
|
);
|
|
await waitFor(() => {
|
|
expect(document.body.style.overflow).toBe("hidden");
|
|
});
|
|
});
|
|
|
|
it("renders belowCard outside the dialog card", async () => {
|
|
renderWithProviders(
|
|
<Login
|
|
isOpen
|
|
onClose={vi.fn()}
|
|
ariaLabelledBy="login-modal-heading"
|
|
belowCard={<a href="/">Back to home</a>}
|
|
>
|
|
<p id="login-modal-heading">Body</p>
|
|
</Login>,
|
|
);
|
|
await waitFor(() => {
|
|
expect(screen.getByRole("dialog")).toBeInTheDocument();
|
|
});
|
|
expect(
|
|
screen.getByRole("link", { name: /back to home/i }),
|
|
).toBeInTheDocument();
|
|
});
|
|
});
|