Add tests for Dialog and Tooltip, raise components/ui threshold to 93%

Dialog: open/close lifecycle, cancel event handling, DialogHeader.
Tooltip: show on pointer enter, hide on pointer leave. Raises
components/ui coverage threshold to enforce testing of future
primitives.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-03-29 17:22:17 +02:00
parent 2bc22369ce
commit 110f4726ae
3 changed files with 115 additions and 2 deletions

View File

@@ -0,0 +1,71 @@
// @vitest-environment jsdom
import { cleanup, render, screen } from "@testing-library/react";
import { userEvent } from "@testing-library/user-event";
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import { Dialog, DialogHeader } from "../ui/dialog.js";
beforeAll(() => {
HTMLDialogElement.prototype.showModal =
HTMLDialogElement.prototype.showModal ||
function showModal(this: HTMLDialogElement) {
this.setAttribute("open", "");
};
HTMLDialogElement.prototype.close =
HTMLDialogElement.prototype.close ||
function close(this: HTMLDialogElement) {
this.removeAttribute("open");
};
});
afterEach(cleanup);
describe("Dialog", () => {
it("opens when open=true", () => {
render(
<Dialog open={true} onClose={() => {}}>
Content
</Dialog>,
);
expect(screen.getByText("Content")).toBeDefined();
});
it("closes when open changes from true to false", () => {
const { rerender } = render(
<Dialog open={true} onClose={() => {}}>
Content
</Dialog>,
);
const dialog = document.querySelector("dialog");
expect(dialog?.hasAttribute("open")).toBe(true);
rerender(
<Dialog open={false} onClose={() => {}}>
Content
</Dialog>,
);
expect(dialog?.hasAttribute("open")).toBe(false);
});
it("calls onClose on cancel event", () => {
const onClose = vi.fn();
render(
<Dialog open={true} onClose={onClose}>
Content
</Dialog>,
);
const dialog = document.querySelector("dialog");
dialog?.dispatchEvent(new Event("cancel"));
expect(onClose).toHaveBeenCalledOnce();
});
});
describe("DialogHeader", () => {
it("renders title and close button", async () => {
const onClose = vi.fn();
render(<DialogHeader title="Test Title" onClose={onClose} />);
expect(screen.getByText("Test Title")).toBeDefined();
await userEvent.click(screen.getByRole("button"));
expect(onClose).toHaveBeenCalledOnce();
});
});

View File

@@ -0,0 +1,42 @@
// @vitest-environment jsdom
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it } from "vitest";
import { Tooltip } from "../ui/tooltip.js";
afterEach(cleanup);
describe("Tooltip", () => {
it("renders children", () => {
render(
<Tooltip content="Hint">
<button type="button">Hover me</button>
</Tooltip>,
);
expect(screen.getByText("Hover me")).toBeDefined();
});
it("does not show tooltip initially", () => {
render(
<Tooltip content="Hint">
<span>Target</span>
</Tooltip>,
);
expect(screen.queryByRole("tooltip")).toBeNull();
});
it("shows tooltip on pointer enter and hides on pointer leave", () => {
render(
<Tooltip content="Hint text">
<span>Target</span>
</Tooltip>,
);
const wrapper = screen.getByText("Target").closest("span");
fireEvent.pointerEnter(wrapper as HTMLElement);
expect(screen.getByRole("tooltip")).toBeDefined();
expect(screen.getByText("Hint text")).toBeDefined();
fireEvent.pointerLeave(wrapper as HTMLElement);
expect(screen.queryByRole("tooltip")).toBeNull();
});
});