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.
140 lines
3.8 KiB
140 lines
3.8 KiB
import { act, cleanup, render, renderHook, screen } from "@testing-library/react";
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
import { I18nProvider } from "@/translations/provider";
|
|
import {
|
|
MatchProfileOverlay,
|
|
useMatchProfileOverlay,
|
|
} from "./match-profile-overlay";
|
|
|
|
vi.mock("next/navigation", () => ({
|
|
useRouter: () => ({
|
|
push: vi.fn(),
|
|
replace: vi.fn(),
|
|
back: vi.fn(),
|
|
}),
|
|
}));
|
|
|
|
vi.mock("@/hooks/marriage/use-profile-main", () => ({
|
|
useMarriageProfileQuery: () => ({
|
|
data: {
|
|
status: "matched",
|
|
gender: "female",
|
|
active_case: { case_id: "test-case-1", status: "introduced" },
|
|
match_summary: {
|
|
gender: "male",
|
|
public_info: [{ key: "full_name", label: "نام", value: "علی احمدی" }],
|
|
},
|
|
},
|
|
isLoading: false,
|
|
refetch: vi.fn(),
|
|
}),
|
|
}));
|
|
|
|
vi.mock("@/hooks/marriage/use-case-respond", () => ({
|
|
useRespondToMarriageCaseMutation: () => ({
|
|
mutateAsync: vi.fn(),
|
|
isPending: false,
|
|
}),
|
|
}));
|
|
|
|
function createWrapper() {
|
|
const queryClient = new QueryClient({
|
|
defaultOptions: {
|
|
queries: { retry: false },
|
|
},
|
|
});
|
|
|
|
return function Wrapper({ children }: { children: React.ReactNode }) {
|
|
return (
|
|
<QueryClientProvider client={queryClient}>
|
|
<I18nProvider locale="fa">{children}</I18nProvider>
|
|
</QueryClientProvider>
|
|
);
|
|
};
|
|
}
|
|
|
|
describe("MatchProfileOverlay & useMatchProfileOverlay", () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout"] });
|
|
vi.stubGlobal("requestAnimationFrame", (cb: FrameRequestCallback) => {
|
|
return setTimeout(() => cb(Date.now()), 0);
|
|
});
|
|
vi.stubGlobal("cancelAnimationFrame", (id: number) => {
|
|
clearTimeout(id);
|
|
});
|
|
document.body.className = "";
|
|
});
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
vi.restoreAllMocks();
|
|
vi.useRealTimers();
|
|
document.body.className = "";
|
|
});
|
|
|
|
it("hook manages open and close state with history sync", () => {
|
|
const { result } = renderHook(() => useMatchProfileOverlay());
|
|
|
|
expect(result.current.isProfileOpen).toBe(false);
|
|
|
|
act(() => {
|
|
result.current.openProfile();
|
|
});
|
|
|
|
expect(result.current.isProfileOpen).toBe(true);
|
|
|
|
act(() => {
|
|
result.current.closeProfile();
|
|
});
|
|
|
|
expect(result.current.isProfileOpen).toBe(false);
|
|
});
|
|
|
|
it("renders overlay dialog and profile page when open is true", () => {
|
|
const handleClose = vi.fn();
|
|
const wrapper = createWrapper();
|
|
|
|
render(
|
|
<MatchProfileOverlay open={true} onClose={handleClose} />,
|
|
{ wrapper },
|
|
);
|
|
|
|
act(() => {
|
|
vi.advanceTimersByTime(16);
|
|
});
|
|
|
|
const overlay = screen.getByRole("dialog");
|
|
expect(overlay).toBeInTheDocument();
|
|
expect(overlay).toHaveClass("section-overlay");
|
|
expect(document.body.classList.contains("section-overlay-open")).toBe(true);
|
|
});
|
|
|
|
it("handles closing animation and removes body class when open becomes false", () => {
|
|
const handleClose = vi.fn();
|
|
const wrapper = createWrapper();
|
|
|
|
const { rerender } = render(
|
|
<MatchProfileOverlay open={true} onClose={handleClose} />,
|
|
{ wrapper },
|
|
);
|
|
|
|
act(() => {
|
|
vi.advanceTimersByTime(16);
|
|
});
|
|
|
|
expect(screen.getByRole("dialog")).toHaveAttribute("data-state", "open");
|
|
expect(document.body.classList.contains("section-overlay-open")).toBe(true);
|
|
|
|
rerender(<MatchProfileOverlay open={false} onClose={handleClose} />);
|
|
|
|
expect(screen.getByRole("dialog")).toHaveAttribute("data-state", "closing");
|
|
expect(document.body.classList.contains("section-overlay-open")).toBe(false);
|
|
|
|
act(() => {
|
|
vi.advanceTimersByTime(210);
|
|
});
|
|
|
|
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
|
});
|
|
});
|