Files
community-rule/tests/components/Login.test.tsx
T
adilalloandCursor c180e79c38 Give every public route its own description, and keep canonicals and structured data on the host that serves the page.
Decorative images on the marketing pages stay quiet, and every dialog close button is named Close.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-04 11:04:52 -07:00

176 lines
5.5 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"));
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("closes on backdrop pointerdown, not a leftover click", 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();
});
const backdrop = screen.getByRole("dialog").parentElement;
expect(backdrop).not.toBeNull();
fireEvent.click(backdrop!);
expect(onClose).not.toHaveBeenCalled();
fireEvent.pointerDown(screen.getByRole("dialog"));
expect(onClose).not.toHaveBeenCalled();
fireEvent.pointerDown(backdrop!);
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();
});
it("does not render a more-options kebab", async () => {
renderWithProviders(
<Login isOpen onClose={vi.fn()} ariaLabelledBy="login-modal-heading">
<p id="login-modal-heading">Body</p>
</Login>,
);
await waitFor(() => {
expect(screen.getByRole("dialog")).toBeInTheDocument();
});
expect(screen.getByLabelText("Close")).toBeInTheDocument();
expect(screen.queryByLabelText("More options")).not.toBeInTheDocument();
});
});