import React from "react"; import { startOfDay, startOfMonth } from "date-fns"; import { defaultLocale } from "react-day-picker"; import { activeElement, dateButton, grid, nav, previousButton } from "@/test/elements"; import { fireEvent, render, screen } from "@/test/render"; import { user } from "@/test/user"; import { DayPicker } from "./DayPicker"; import { MonthProps } from "./components/Month"; import { MonthsProps } from "./components/Months"; const testId = "test"; const dayPicker = () => screen.getByTestId(testId); test("should render a date picker component", () => { render(); expect(dayPicker()).toBeInTheDocument(); }); test("render the navigation and month grids", () => { render(); expect(nav()).toBeInTheDocument(); expect(grid()).toBeInTheDocument(); }); test("apply classnames and style according to props", () => { render( ); expect(dayPicker()).toHaveClass("rdp-root"); expect(dayPicker()).toHaveClass("custom-class"); expect(dayPicker()).toHaveStyle({ color: "red" }); }); test("use custom components", () => { render(
Custom Navigation
, Month: (props: MonthProps) =>
Custom Month
, Months: (props: MonthsProps) => (
Custom Months
{props.children}
), Footer: () =>
Custom Footer
}} footer="Footer" /> ); expect(dayPicker()).toHaveTextContent("Custom Navigation"); expect(dayPicker()).toHaveTextContent("Custom Months"); expect(dayPicker()).toHaveTextContent("Custom Month"); expect(dayPicker()).toHaveTextContent("Custom Footer"); }); describe("when the date picker is focused", () => { test("focus the previous button", async () => { render(); await user.tab(); expect(activeElement()).toBe(previousButton()); }); test("on RTL, focus the previous button", async () => { render(); await user.tab(); expect(activeElement()).toBe(previousButton()); }); }); describe("when the grid is focused", () => { const today = new Date(); beforeAll(() => jest.setSystemTime(today)); afterAll(() => jest.useRealTimers()); test("should focus the today's date", async () => { render(); await user.tab(); await user.tab(); await user.tab(); expect(activeElement()).toBe(dateButton(today)); }); describe("when the today’s date is disabled", () => { test("should focus the first day of the month", async () => { render(); await user.tab(); await user.tab(); await user.tab(); expect(activeElement()).toBe(dateButton(startOfMonth(today))); }); }); }); describe("when a day is mouse entered", () => { const handleDayMouseEnter = jest.fn(); const handleDayMouseLeave = jest.fn(); const today = startOfDay(new Date()); beforeEach(async () => { render( ); fireEvent.mouseEnter(dateButton(today)); fireEvent.mouseLeave(dateButton(today)); }); test("should call the event handler", async () => { expect(handleDayMouseEnter).toHaveBeenCalled(); expect(handleDayMouseLeave).toHaveBeenCalled(); }); }); describe("when the `month` is changed programmatically", () => { test("should update the calendar to reflect the new month", async () => { const initialMonth = new Date(2023, 0, 1); // January 2023 const newMonth = new Date(2023, 1, 1); // February 2023 const { rerender } = render( ); expect(grid("January 2023")).toBeInTheDocument(); rerender(); expect(grid("February 2023")).toBeInTheDocument(); }); }); test("extends the default locale", () => { render( "bar" } }} /> ); // Check if the custom month name is rendered expect(grid("bar 2024")).toBeInTheDocument(); }); test("should render the custom components", () => { render(
Custom Nav
, YearsDropdown: () =>
Custom YearsDropdown
, MonthsDropdown: () =>
Custom MonthsDropdown
, Footer: () =>
Custom Footer
}} /> ); expect(screen.getByText("Custom Nav")).toBeInTheDocument(); expect(screen.getByText("Custom Footer")).toBeInTheDocument(); expect(screen.getByText("Custom YearsDropdown")).toBeInTheDocument(); expect(screen.getByText("Custom MonthsDropdown")).toBeInTheDocument(); }); describe("when interactive", () => { test("render a valid HTML", () => { render(); expect(document.body).toHTMLValidate(); }); }); describe("when not interactive", () => { test("render a valid HTML", () => { render(); expect(document.body).toHTMLValidate(); }); });