81 lines
3.5 KiB
TypeScript
81 lines
3.5 KiB
TypeScript
import { render, screen } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
|
|
import { DateTimeField } from "@/shared/ui/date-time-field";
|
|
import "@/test/radix-select-test-setup";
|
|
|
|
describe("DateTimeField", () => {
|
|
it("does not change the controlled value when opening and cancelling", async () => {
|
|
const onChange = vi.fn();
|
|
const user = userEvent.setup();
|
|
render(<DateTimeField label="时窗开始" value="2026-09-17T08:00" onChange={onChange} />);
|
|
|
|
await user.click(screen.getByRole("button", { name: "时窗开始" }));
|
|
expect(screen.getByRole("dialog", { name: "选择时窗开始" })).toBeVisible();
|
|
await user.click(screen.getByRole("button", { name: "取消" }));
|
|
|
|
expect(onChange).not.toHaveBeenCalled();
|
|
expect(screen.getByRole("button", { name: "时窗开始" })).toHaveFocus();
|
|
});
|
|
|
|
it("emits a minute-precision local datetime only after confirmation", async () => {
|
|
const onChange = vi.fn();
|
|
const user = userEvent.setup();
|
|
render(<DateTimeField label="时窗开始" value="2024-02-28T09:30" onChange={onChange} />);
|
|
|
|
await user.click(screen.getByRole("button", { name: "时窗开始" }));
|
|
await user.click(screen.getByRole("gridcell", { name: "2024年2月29日" }));
|
|
expect(onChange).not.toHaveBeenCalled();
|
|
await user.click(screen.getByRole("button", { name: "确认" }));
|
|
|
|
expect(onChange).toHaveBeenCalledOnce();
|
|
expect(onChange).toHaveBeenCalledWith("2024-02-29T09:30");
|
|
});
|
|
|
|
it("limits minute choices to the configured step", async () => {
|
|
const user = userEvent.setup();
|
|
render(<DateTimeField label="演示开始时间" value="2024-02-28T09:25" onChange={vi.fn()} minuteStep={5} />);
|
|
|
|
await user.click(screen.getByRole("button", { name: "演示开始时间" }));
|
|
await user.click(screen.getByRole("combobox", { name: "分钟" }));
|
|
expect(screen.getByRole("option", { name: "25" })).toBeVisible();
|
|
expect(screen.queryByRole("option", { name: "26" })).not.toBeInTheDocument();
|
|
});
|
|
|
|
it.each(["2025-02-29T12:00", "2024-04-31T12:00", "2024-02-29T12:00:30"])(
|
|
"rejects invalid or unexpected source value %s",
|
|
async (value) => {
|
|
const user = userEvent.setup();
|
|
render(<DateTimeField label="时窗开始" value={value} onChange={vi.fn()} />);
|
|
|
|
await user.click(screen.getByRole("button", { name: "时窗开始" }));
|
|
expect(screen.getByRole("alert")).toHaveTextContent("当前值格式无效");
|
|
expect(screen.getByRole("button", { name: "确认" })).toBeDisabled();
|
|
}
|
|
);
|
|
|
|
it("renders the correct leap-month day count", async () => {
|
|
const user = userEvent.setup();
|
|
render(<DateTimeField label="时窗开始" value="2024-02-01T00:00" onChange={vi.fn()} />);
|
|
|
|
await user.click(screen.getByRole("button", { name: "时窗开始" }));
|
|
expect(screen.getAllByRole("gridcell")).toHaveLength(29);
|
|
expect(screen.getByRole("gridcell", { name: "2024年2月29日" })).toBeVisible();
|
|
});
|
|
|
|
it("cannot open or confirm while disabled", async () => {
|
|
const onChange = vi.fn();
|
|
const user = userEvent.setup();
|
|
render(
|
|
<DateTimeField label="时窗开始" value="2026-09-17T08:00" onChange={onChange} disabled />
|
|
);
|
|
|
|
const trigger = screen.getByRole("button", { name: "时窗开始" });
|
|
expect(trigger).toBeDisabled();
|
|
await user.click(trigger);
|
|
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
|
expect(onChange).not.toHaveBeenCalled();
|
|
});
|
|
});
|