useCompleteOnboarding.spec.js
2 months ago
useDateRangePicker.spec.js
3 months ago
useEmail.spec.js
3 months ago
useEngagementChartData.spec.js
3 months ago
useLicenseSettings.spec.js
3 months ago
useLink.spec.js
3 months ago
useMediaDetail.spec.js
3 months ago
useMediaLibrary.spec.js
3 months ago
useMediaList.spec.js
2 months ago
usePerformanceSettings.spec.js
3 months ago
useRegisterActivePage.spec.js
3 months ago
useSettingOption.spec.js
3 months ago
useSimpleSettingsPage.spec.js
3 months ago
useTopPerforming.spec.js
3 months ago
useTopVideosPaginated.spec.js
3 months ago
useUpgradeCTA.spec.js
3 months ago
useUserDetail.spec.js
3 months ago
useDateRangePicker.spec.js
158 lines
| 1 | import { renderHook, act } from "@testing-library/react-hooks"; |
| 2 | import useDateRangePicker from "../useDateRangePicker"; |
| 3 | |
| 4 | describe("useDateRangePicker", () => { |
| 5 | let refetch; |
| 6 | |
| 7 | beforeEach(() => { |
| 8 | refetch = jest.fn(); |
| 9 | // Clean any stray DOM from prior tests. |
| 10 | document.body.innerHTML = ""; |
| 11 | }); |
| 12 | |
| 13 | it("calls refetchFn(from, to) when both dates are applied", () => { |
| 14 | const { result } = renderHook(() => useDateRangePicker(refetch)); |
| 15 | const from = new Date("2026-01-01"); |
| 16 | const to = new Date("2026-01-05"); |
| 17 | |
| 18 | act(() => { |
| 19 | result.current.handleDateApply({ from, to }); |
| 20 | }); |
| 21 | |
| 22 | expect(result.current.selectedDates).toEqual({ from, to }); |
| 23 | expect(result.current.isDatePickerOpen).toBe(false); |
| 24 | expect(refetch).toHaveBeenCalledWith(from, to); |
| 25 | }); |
| 26 | |
| 27 | it("swaps from/to when the user applies a reversed range", () => { |
| 28 | const { result } = renderHook(() => useDateRangePicker(refetch)); |
| 29 | const earlier = new Date("2026-01-01"); |
| 30 | const later = new Date("2026-02-01"); |
| 31 | |
| 32 | act(() => { |
| 33 | // User picked "from = later, to = earlier" — hook should swap. |
| 34 | result.current.handleDateApply({ from: later, to: earlier }); |
| 35 | }); |
| 36 | |
| 37 | expect(result.current.selectedDates).toEqual({ |
| 38 | from: earlier, |
| 39 | to: later, |
| 40 | }); |
| 41 | }); |
| 42 | |
| 43 | it("treats a single-day pick (only `from`) as { from, to: from }", () => { |
| 44 | const { result } = renderHook(() => useDateRangePicker(refetch)); |
| 45 | const day = new Date("2026-03-15"); |
| 46 | |
| 47 | act(() => { |
| 48 | result.current.handleDateApply({ from: day, to: undefined }); |
| 49 | }); |
| 50 | |
| 51 | expect(result.current.selectedDates).toEqual({ from: day, to: day }); |
| 52 | expect(refetch).toHaveBeenCalledWith(day, day); |
| 53 | }); |
| 54 | |
| 55 | it("clears selection when handleDateApply is called with no dates", () => { |
| 56 | const { result } = renderHook(() => useDateRangePicker(refetch)); |
| 57 | |
| 58 | // Set something first. |
| 59 | act(() => { |
| 60 | result.current.handleDateApply({ |
| 61 | from: new Date("2026-01-01"), |
| 62 | to: new Date("2026-01-02"), |
| 63 | }); |
| 64 | }); |
| 65 | refetch.mockClear(); |
| 66 | |
| 67 | act(() => { |
| 68 | result.current.handleDateApply({ from: null, to: null }); |
| 69 | }); |
| 70 | |
| 71 | expect(result.current.selectedDates).toEqual({ from: null, to: null }); |
| 72 | // No refetch fires for an empty range — only when both ends are set. |
| 73 | expect(refetch).not.toHaveBeenCalled(); |
| 74 | }); |
| 75 | |
| 76 | it("handleClearFilters resets dates and calls refetchFn() with no args", () => { |
| 77 | const { result } = renderHook(() => useDateRangePicker(refetch)); |
| 78 | |
| 79 | act(() => { |
| 80 | result.current.handleDateApply({ |
| 81 | from: new Date("2026-01-01"), |
| 82 | to: new Date("2026-01-05"), |
| 83 | }); |
| 84 | }); |
| 85 | refetch.mockClear(); |
| 86 | |
| 87 | act(() => { |
| 88 | result.current.handleClearFilters(); |
| 89 | }); |
| 90 | |
| 91 | expect(result.current.selectedDates).toEqual({ from: null, to: null }); |
| 92 | expect(refetch).toHaveBeenCalledTimes(1); |
| 93 | expect(refetch).toHaveBeenCalledWith(); |
| 94 | }); |
| 95 | |
| 96 | it("closes the picker when a mousedown fires outside the ref'd element", () => { |
| 97 | const inside = document.createElement("div"); |
| 98 | const outside = document.createElement("div"); |
| 99 | document.body.appendChild(inside); |
| 100 | document.body.appendChild(outside); |
| 101 | |
| 102 | const { result } = renderHook(() => useDateRangePicker(refetch)); |
| 103 | |
| 104 | act(() => { |
| 105 | result.current.datePickerRef.current = inside; |
| 106 | result.current.setIsDatePickerOpen(true); |
| 107 | }); |
| 108 | expect(result.current.isDatePickerOpen).toBe(true); |
| 109 | |
| 110 | act(() => { |
| 111 | outside.dispatchEvent(new MouseEvent("mousedown", { bubbles: true })); |
| 112 | }); |
| 113 | expect(result.current.isDatePickerOpen).toBe(false); |
| 114 | }); |
| 115 | |
| 116 | it("does NOT close the picker when mousedown fires inside the ref'd element", () => { |
| 117 | const inside = document.createElement("div"); |
| 118 | const child = document.createElement("span"); |
| 119 | inside.appendChild(child); |
| 120 | document.body.appendChild(inside); |
| 121 | |
| 122 | const { result } = renderHook(() => useDateRangePicker(refetch)); |
| 123 | |
| 124 | act(() => { |
| 125 | result.current.datePickerRef.current = inside; |
| 126 | result.current.setIsDatePickerOpen(true); |
| 127 | }); |
| 128 | |
| 129 | act(() => { |
| 130 | child.dispatchEvent(new MouseEvent("mousedown", { bubbles: true })); |
| 131 | }); |
| 132 | expect(result.current.isDatePickerOpen).toBe(true); |
| 133 | }); |
| 134 | |
| 135 | it("removes the click-outside listener when the picker closes", () => { |
| 136 | const inside = document.createElement("div"); |
| 137 | const outside = document.createElement("div"); |
| 138 | document.body.appendChild(inside); |
| 139 | document.body.appendChild(outside); |
| 140 | |
| 141 | const { result } = renderHook(() => useDateRangePicker(refetch)); |
| 142 | |
| 143 | act(() => { |
| 144 | result.current.datePickerRef.current = inside; |
| 145 | result.current.setIsDatePickerOpen(true); |
| 146 | }); |
| 147 | act(() => { |
| 148 | result.current.setIsDatePickerOpen(false); |
| 149 | }); |
| 150 | |
| 151 | // After close, a stray outside-click should not toggle anything. |
| 152 | act(() => { |
| 153 | outside.dispatchEvent(new MouseEvent("mousedown", { bubbles: true })); |
| 154 | }); |
| 155 | expect(result.current.isDatePickerOpen).toBe(false); |
| 156 | }); |
| 157 | }); |
| 158 |