import { act, renderHook } from "@/test/render"; import { defaultDateLib } from "../classes/DateLib"; import type { DayPickerProps } from "../types"; import { useRange } from "./useRange"; describe("useRange", () => { test("initialize with initiallySelected date range", () => { const initiallySelected = { from: new Date(2023, 6, 1), to: new Date(2023, 6, 5), }; const { result } = renderHook(() => useRange( { mode: "range", selected: initiallySelected, required: false }, defaultDateLib, ), ); expect(result.current.selected).toEqual(initiallySelected); }); test("update the selected range on select", () => { const initiallySelected = { from: new Date(2023, 6, 1), to: new Date(2023, 6, 5), }; const { result } = renderHook(() => useRange( { mode: "range", selected: initiallySelected, required: false }, defaultDateLib, ), ); act(() => { result.current.select?.( new Date(2023, 6, 10), {}, {} as React.MouseEvent, ); }); expect(result.current.selected).toEqual({ from: new Date(2023, 6, 1), to: new Date(2023, 6, 10), }); }); test("reset range if new range exceeds max days", () => { const { result } = renderHook(() => useRange( { mode: "range", selected: undefined, required: false, max: 5, }, defaultDateLib, ), ); act(() => { result.current.select?.(new Date(2023, 6, 1), {}, {} as React.MouseEvent); result.current.select?.( new Date(2023, 6, 10), {}, {} as React.MouseEvent, ); }); expect(result.current.selected).toEqual({ from: new Date(2023, 6, 10), to: new Date(2023, 6, 10), }); }); test("reset range if new range is less than min days", () => { const { result } = renderHook(() => useRange( { mode: "range", selected: undefined, required: false, min: 5 }, defaultDateLib, ), ); act(() => { result.current.select?.(new Date(2023, 6, 1), {}, {} as React.MouseEvent); result.current.select?.(new Date(2023, 6, 3), {}, {} as React.MouseEvent); }); expect(result.current.selected).toEqual({ from: new Date(2023, 6, 3), to: undefined, }); }); test("exclude disabled dates when selecting range", () => { const disabled = [{ from: new Date(2023, 6, 5), to: new Date(2023, 6, 7) }]; const { result } = renderHook(() => useRange( { mode: "range", selected: undefined, required: false, excludeDisabled: true, disabled, }, defaultDateLib, ), ); act(() => { result.current.select?.(new Date(2023, 6, 1), {}, {} as React.MouseEvent); result.current.select?.( new Date(2023, 6, 10), {}, {} as React.MouseEvent, ); }); expect(result.current.selected).toEqual({ from: new Date(2023, 6, 10), to: new Date(2023, 6, 10), }); }); it("uses the selected value from props when onSelect is provided", () => { const mockOnSelect = jest.fn(); const selectedRange = { from: new Date(2023, 9, 1), to: new Date(2023, 9, 5), }; const props: DayPickerProps = { mode: "range", selected: selectedRange, onSelect: mockOnSelect, }; const { result } = renderHook(() => useRange(props, defaultDateLib)); expect(result.current.selected).toBe(selectedRange); }); it("uses the internally selected value when onSelect is not provided", () => { const initialSelectedRange = { from: new Date(2023, 9, 1), to: new Date(2023, 9, 5), }; const props: DayPickerProps = { mode: "range", selected: initialSelectedRange, }; const { result } = renderHook(() => useRange(props, defaultDateLib)); act(() => { result.current.select?.(new Date(2023, 9, 6), {}, {} as React.MouseEvent); }); expect(result.current.selected).toEqual({ from: new Date(2023, 9, 1), to: new Date(2023, 9, 6), }); }); });