UNPKG

5.25 kBTypeScriptView Raw
1import React from "react";
2
3import { addMonths, startOfDay, startOfMonth } from "date-fns";
4import { defaultLocale } from "react-day-picker";
5
6import {
7 activeElement,
8 dateButton,
9 grid,
10 nav,
11 previousButton
12} from "@/test/elements";
13import { fireEvent, render, screen } from "@/test/render";
14import { user } from "@/test/user";
15
16import { DayPicker } from "./DayPicker";
17import { MonthProps } from "./components/Month";
18import { MonthsProps } from "./components/Months";
19import { labelGrid } from "./labels";
20
21const testId = "test";
22const dayPicker = () => screen.getByTestId(testId);
23
24test("should render a date picker component", () => {
25 render(<DayPicker data-testid={testId} />);
26 expect(dayPicker()).toBeInTheDocument();
27});
28
29test("render the navigation and month grids", () => {
30 render(<DayPicker data-testid={testId} />);
31
32 expect(nav()).toBeInTheDocument();
33 expect(grid()).toBeInTheDocument();
34});
35
36test("apply classnames and style according to props", () => {
37 render(
38 <DayPicker
39 data-testid={testId}
40 className="custom-class"
41 numberOfMonths={2}
42 showWeekNumber
43 style={{ color: "red" }}
44 />
45 );
46
47 expect(dayPicker()).toHaveClass("rdp-root");
48 expect(dayPicker()).toHaveClass("custom-class");
49 expect(dayPicker()).toHaveStyle({ color: "red" });
50});
51
52test("use custom components", () => {
53 render(
54 <DayPicker
55 data-testid={testId}
56 components={{
57 Nav: () => <div>Custom Navigation</div>,
58 Month: (props: MonthProps) => <div>Custom Month</div>,
59 Months: (props: MonthsProps) => (
60 <div {...props}>
61 Custom Months<div>{props.children}</div>
62 </div>
63 ),
64 Footer: () => <div>Custom Footer</div>
65 }}
66 footer="Footer"
67 />
68 );
69
70 expect(dayPicker()).toHaveTextContent("Custom Navigation");
71 expect(dayPicker()).toHaveTextContent("Custom Months");
72 expect(dayPicker()).toHaveTextContent("Custom Month");
73 expect(dayPicker()).toHaveTextContent("Custom Footer");
74});
75
76describe("when the date picker is focused", () => {
77 test("focus the previous button", async () => {
78 render(<DayPicker />);
79 await user.tab();
80 expect(activeElement()).toBe(previousButton());
81 });
82
83 test("on RTL, focus the previous button", async () => {
84 render(<DayPicker dir="rtl" />);
85 await user.tab();
86 expect(activeElement()).toBe(previousButton());
87 });
88});
89
90describe("when the grid is focused", () => {
91 const today = new Date();
92
93 beforeAll(() => jest.setSystemTime(today));
94 afterAll(() => jest.useRealTimers());
95
96 test("should focus the today's date", async () => {
97 render(<DayPicker mode="single" today={today} />);
98 await user.tab();
99 await user.tab();
100 await user.tab();
101 expect(activeElement()).toBe(dateButton(today));
102 });
103 describe("when the today’s date is disabled", () => {
104 test("should focus the first day of the month", async () => {
105 render(<DayPicker mode="single" disabled={today} />);
106 await user.tab();
107 await user.tab();
108 await user.tab();
109 expect(activeElement()).toBe(dateButton(startOfMonth(today)));
110 });
111 });
112});
113
114describe("when a day is mouse entered", () => {
115 const handleDayMouseEnter = jest.fn();
116 const handleDayMouseLeave = jest.fn();
117 const today = startOfDay(new Date());
118 beforeEach(async () => {
119 render(
120 <DayPicker
121 today={today}
122 defaultMonth={today}
123 mode="single"
124 onDayMouseEnter={handleDayMouseEnter}
125 onDayMouseLeave={handleDayMouseLeave}
126 />
127 );
128 fireEvent.mouseEnter(dateButton(today));
129 fireEvent.mouseLeave(dateButton(today));
130 });
131 test("should call the event handler", async () => {
132 expect(handleDayMouseEnter).toHaveBeenCalled();
133 expect(handleDayMouseLeave).toHaveBeenCalled();
134 });
135});
136
137describe("when the `month` is changed programmatically", () => {
138 test("should update the calendar to reflect the new month", async () => {
139 const initialMonth = new Date(2023, 0, 1); // January 2023
140 const newMonth = new Date(2023, 1, 1); // February 2023
141 const { rerender } = render(
142 <DayPicker month={initialMonth} mode="single" />
143 );
144 expect(grid("January 2023")).toBeInTheDocument();
145 rerender(<DayPicker month={newMonth} mode="single" />);
146 expect(grid("February 2023")).toBeInTheDocument();
147 });
148});
149
150describe("when the `startMonth` is changed programmatically", () => {
151 test("should update the calendar to reflect the new month", async () => {
152 const initialStartMonth = new Date();
153 const newStartMonth = addMonths(new Date(), 2);
154 const { rerender } = render(
155 <DayPicker startMonth={initialStartMonth} mode="single" />
156 );
157 expect(grid(labelGrid(initialStartMonth))).toBeInTheDocument();
158 rerender(<DayPicker startMonth={newStartMonth} mode="single" />);
159 expect(grid(labelGrid(newStartMonth))).toBeInTheDocument();
160 });
161});
162
163test("extends the default locale", () => {
164 render(
165 <DayPicker
166 month={new Date(2024, 0)}
167 locale={{
168 localize: {
169 ...defaultLocale.localize,
170 month: () => "bar"
171 }
172 }}
173 />
174 );
175 // Check if the custom month name is rendered
176 expect(grid("bar 2024")).toBeInTheDocument();
177});