You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

125 lines
4.5 KiB

import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import TermsSheet from "./terms-sheet";
vi.mock("@/translations/provider", () => ({
useI18n: () => ({
locale: "fa",
dictionary: {
"terms & conditions": "قوانین و مقررات",
"Got it": "متوجه شدم",
"Close terms and conditions": "بستن قوانین و مقررات",
},
}),
}));
describe("TermsSheet Component (DraggableScrollableSheet Parity)", () => {
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
cleanup();
});
it("does not render when isOpen is false", () => {
render(<TermsSheet isOpen={false} />);
expect(screen.queryByRole("dialog")).toBeNull();
});
it("renders with initial 75% height when isOpen is true", () => {
render(<TermsSheet isOpen={true} />);
const dialog = screen.getByRole("dialog");
expect(dialog).toBeInTheDocument();
const section = dialog.querySelector("section")!;
expect(section).toHaveClass("h-[calc(var(--sheet-size,0.75)*100svh)]");
expect(screen.getByText("قوانین و مقررات")).toBeInTheDocument();
expect(screen.getByText("متوجه شدم")).toBeInTheDocument();
});
it("grows sheet when pulling up at top of content", () => {
render(<TermsSheet isOpen={true} />);
const dialog = screen.getByRole("dialog");
const section = dialog.querySelector("section")!;
const content = screen.getByTestId("terms-sheet-content");
Object.defineProperty(content, "scrollHeight", { value: 1200, configurable: true });
Object.defineProperty(content, "clientHeight", { value: 400, configurable: true });
Object.defineProperty(content, "scrollTop", { value: 0, configurable: true });
fireEvent.touchStart(content, { touches: [{ clientX: 0, clientY: 400 }] });
fireEvent.touchMove(content, { touches: [{ clientX: 0, clientY: 300 }] });
expect(section.style.getPropertyValue("--sheet-size")).toBe(
(0.75 + 100 / window.innerHeight).toFixed(4),
);
});
it("grows sheet on wheel event at top of content", () => {
render(<TermsSheet isOpen={true} />);
const dialog = screen.getByRole("dialog");
const section = dialog.querySelector("section")!;
const content = screen.getByTestId("terms-sheet-content");
Object.defineProperty(content, "scrollHeight", { value: 1200, configurable: true });
Object.defineProperty(content, "clientHeight", { value: 400, configurable: true });
Object.defineProperty(content, "scrollTop", { value: 0, configurable: true });
fireEvent.wheel(content, { deltaY: 120 });
expect(section.style.getPropertyValue("--sheet-size")).toBe(
(0.75 + 120 / window.innerHeight).toFixed(4),
);
});
it("shrinks to 60% floor and closes when pulled past it (shouldCloseOnMinExtent: true)", async () => {
const handleClose = vi.fn();
render(<TermsSheet isOpen={true} onClose={handleClose} />);
const dialog = screen.getByRole("dialog");
const section = dialog.querySelector("section")!;
const content = screen.getByTestId("terms-sheet-content");
Object.defineProperty(content, "scrollTop", { value: 0, configurable: true });
// Pull down at the top: sheet shrinks and clamps at 0.6 floor
fireEvent.touchStart(content, { touches: [{ clientX: 0, clientY: 400 }] });
fireEvent.touchMove(content, { touches: [{ clientX: 0, clientY: 560 }] });
expect(section.style.getPropertyValue("--sheet-size")).toBe("0.6000");
// Pull further past 0.6: triggers close
fireEvent.touchMove(content, { touches: [{ clientX: 0, clientY: 580 }] });
await waitFor(() => {
expect(handleClose).toHaveBeenCalled();
});
});
it("calls onClose when Got it button is clicked", async () => {
const handleClose = vi.fn();
render(<TermsSheet isOpen={true} onClose={handleClose} />);
const gotItButton = screen.getByRole("button", { name: "متوجه شدم" });
fireEvent.click(gotItButton);
await waitFor(() => {
expect(handleClose).toHaveBeenCalled();
});
});
it("calls onClose when close X button is clicked", async () => {
const handleClose = vi.fn();
render(<TermsSheet isOpen={true} onClose={handleClose} />);
const closeButton = screen.getByRole("button", { name: "بستن قوانین و مقررات" });
fireEvent.click(closeButton);
await waitFor(() => {
expect(handleClose).toHaveBeenCalled();
});
});
});