import { fireEvent, render } from "@testing-library/react"; import { act } from "react"; import React from "react"; import DatePicker from "../index"; import TimeComponent from "../time"; import { safeQuerySelector, setupMockResizeObserver } from "./test_utils"; describe("DatePicker", () => { beforeAll(() => { setupMockResizeObserver(); }); it("should show time component when showTimeSelect prop is present", () => { const { container } = render(); const timeComponent = container.querySelector( ".react-datepicker__time-container", ); expect(timeComponent).not.toBeNull(); }); it("should have custom time caption", () => { const { container } = render(); const caption = container.querySelector(".react-datepicker-time__header"); expect(caption?.textContent).toEqual("Custom time"); }); describe("Time Select Only", () => { let datePicker: HTMLElement; beforeEach(() => { datePicker = render( , ).container; const input = safeQuerySelector(datePicker, "input"); fireEvent.click(input); }); it("should not show month container when showTimeSelectOnly prop is present", () => { const elem = datePicker.querySelectorAll( ".react-datepicker__month-container", ); expect(elem).toHaveLength(0); }); it("should not show previous month button when showTimeSelectOnly prop is present", () => { const elem = datePicker.querySelectorAll( ".react-datepicker__navigation--previous", ); expect(elem).toHaveLength(0); }); it("should not show next month button when showTimeSelectOnly prop is present", () => { const elem = datePicker.querySelectorAll( ".react-datepicker__navigation--next", ); expect(elem).toHaveLength(0); }); it("should not show today button when showTimeSelectOnly prop is present", () => { const elem = datePicker.querySelectorAll( ".react-datepicker__today-button", ); expect(elem).toHaveLength(0); }); }); describe("Time input interactions", () => { it("should show input-time container when showTimeInput prop is present", () => { const { container } = render(); const component = container.querySelector( ".react-datepicker__input-time-container", ); expect(component).not.toBeNull(); }); it("should retain focus on input after value change", () => { const { container } = render(); const input = safeQuerySelector(container, "input"); act(() => { input.focus(); }); expect(document.activeElement).toBe(input); fireEvent.change(input, { target: { value: "13:00" }, }); expect(document.activeElement).toBe(input); }); it("should focus the time input when clicked", () => { const { container } = render( , ); const input = safeQuerySelector(container, "input"); fireEvent.focus(input); const timeInput = safeQuerySelector( container, 'input[type="time"].react-datepicker-time__input', ); fireEvent.click(timeInput); expect(document.activeElement).toBe(timeInput); }); it("should handle invalid time input gracefully", () => { const onChange = jest.fn(); const { container } = render( , ); const input = safeQuerySelector(container, "input"); fireEvent.focus(input); const timeInput = safeQuerySelector( container, 'input[type="time"].react-datepicker-time__input', ); fireEvent.change(timeInput, { target: { value: "invalid" }, }); expect(onChange).toHaveBeenCalled(); }); it("should handle time change when no date is selected", () => { const onChange = jest.fn(); const { container } = render( , ); const input = safeQuerySelector(container, "input"); fireEvent.focus(input); const timeInput = safeQuerySelector( container, 'input[type="time"].react-datepicker-time__input', ); fireEvent.change(timeInput, { target: { value: "14:30" }, }); expect(onChange).toHaveBeenCalled(); }); it("should call onChange with updated date when valid time is entered", () => { const onChange = jest.fn(); const selectedDate = new Date("2024-01-15T10:00:00"); const { container } = render( , ); const input = safeQuerySelector(container, "input"); fireEvent.focus(input); const timeInput = safeQuerySelector( container, 'input[type="time"].react-datepicker-time__input', ); fireEvent.change(timeInput, { target: { value: "15:45" }, }); const expectedDate = new Date(selectedDate); expectedDate.setHours(15); expectedDate.setMinutes(45); expect(onChange).toHaveBeenCalledWith(expectedDate); }); }); describe("Time Select Only with openToDate", () => { it("should use openToDate as the base date when selecting time with showTimeSelectOnly and selected is null", () => { const onChange = jest.fn(); const openToDate = new Date("2025-11-01T00:00:00"); const { container } = render( , ); const input = safeQuerySelector(container, "input"); fireEvent.click(input); // Find and click a time option (e.g., 09:00) const timeListItems = container.querySelectorAll( ".react-datepicker__time-list-item", ); expect(timeListItems.length).toBeGreaterThan(0); // Click on a time option fireEvent.click(timeListItems[0]!); expect(onChange).toHaveBeenCalled(); const selectedDate = onChange.mock.calls[0][0] as Date; // Verify the date part comes from openToDate expect(selectedDate.getFullYear()).toBe(2025); expect(selectedDate.getMonth()).toBe(10); // November is month 10 (0-indexed) expect(selectedDate.getDate()).toBe(1); }); it("should use current date when showTimeSelectOnly is true and neither selected nor openToDate is provided", () => { const onChange = jest.fn(); const today = new Date(); const { container } = render( , ); const input = safeQuerySelector(container, "input"); fireEvent.click(input); const timeListItems = container.querySelectorAll( ".react-datepicker__time-list-item", ); expect(timeListItems.length).toBeGreaterThan(0); fireEvent.click(timeListItems[0]!); expect(onChange).toHaveBeenCalled(); const selectedDate = onChange.mock.calls[0][0] as Date; // Verify the date part comes from today expect(selectedDate.getFullYear()).toBe(today.getFullYear()); expect(selectedDate.getMonth()).toBe(today.getMonth()); expect(selectedDate.getDate()).toBe(today.getDate()); }); it("should use openToDate for showTimeInput when selected is null", () => { const onChange = jest.fn(); const openToDate = new Date("2025-11-01T00:00:00"); const { container } = render( , ); const input = safeQuerySelector(container, "input"); fireEvent.focus(input); const timeInput = safeQuerySelector( container, 'input[type="time"].react-datepicker-time__input', ); fireEvent.change(timeInput, { target: { value: "14:30" }, }); expect(onChange).toHaveBeenCalled(); const selectedDate = onChange.mock.calls[0][0] as Date; // Verify the date part comes from openToDate expect(selectedDate.getFullYear()).toBe(2025); expect(selectedDate.getMonth()).toBe(10); // November expect(selectedDate.getDate()).toBe(1); expect(selectedDate.getHours()).toBe(14); expect(selectedDate.getMinutes()).toBe(30); }); }); });