Files
Reactive-Resume/src/hooks/use-confirm.test.tsx
T
2026-04-02 00:14:54 +02:00

123 lines
3.4 KiB
TypeScript

import { act, render, renderHook, screen } from "@testing-library/react";
import React from "react";
import { afterEach, describe, expect, it } from "vite-plus/test";
import { ConfirmDialogProvider, useConfirm } from "./use-confirm";
afterEach(() => {
document.body.innerHTML = "";
});
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function wrapper({ children }: { children: React.ReactNode }) {
return <ConfirmDialogProvider>{children}</ConfirmDialogProvider>;
}
/** A test component that triggers confirm and stores the result */
function ConfirmTester() {
const confirm = useConfirm();
const [result, setResult] = React.useState<boolean | null>(null);
return (
<div>
<button
onClick={async () => {
const confirmed = await confirm("Delete this?", {
description: "This action cannot be undone.",
confirmText: "Delete",
cancelText: "Keep",
});
setResult(confirmed);
}}
>
Trigger
</button>
{result !== null && <span data-testid="result">{String(result)}</span>}
</div>
);
}
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
describe("useConfirm", () => {
it("throws when used outside provider", () => {
expect(() => {
renderHook(() => useConfirm());
}).toThrow("useConfirm must be used within a <ConfirmDialogProvider />");
});
it("returns a function when used inside provider", () => {
const { result } = renderHook(() => useConfirm(), { wrapper });
expect(typeof result.current).toBe("function");
});
it("confirm() returns a promise", () => {
const { result } = renderHook(() => useConfirm(), { wrapper });
let promise: Promise<boolean> | undefined;
act(() => {
promise = result.current("Are you sure?");
});
expect(promise).toBeInstanceOf(Promise);
});
it("opens dialog with title and description when confirm is called", async () => {
render(
<ConfirmDialogProvider>
<ConfirmTester />
</ConfirmDialogProvider>,
);
await act(async () => {
screen.getByText("Trigger").click();
});
expect(screen.getByText("Delete this?")).toBeDefined();
expect(screen.getByText("This action cannot be undone.")).toBeDefined();
expect(screen.getByText("Delete")).toBeDefined();
expect(screen.getByText("Keep")).toBeDefined();
});
it("resolves true when confirm button is clicked", async () => {
render(
<ConfirmDialogProvider>
<ConfirmTester />
</ConfirmDialogProvider>,
);
await act(async () => {
screen.getByText("Trigger").click();
});
await act(async () => {
screen.getByText("Delete").click();
});
expect(screen.getByTestId("result").textContent).toBe("true");
});
it("resolves false when cancel button is clicked", async () => {
render(
<ConfirmDialogProvider>
<ConfirmTester />
</ConfirmDialogProvider>,
);
await act(async () => {
screen.getByText("Trigger").click();
});
await act(async () => {
screen.getByText("Keep").click();
});
expect(screen.getByTestId("result").textContent).toBe("false");
});
});