@@ -4,6 +4,11 @@ import { describe, it, expect, beforeEach, vi } from 'vitest';
4
4
import { type RangeDatePickerProps , type SingleDatePickerProps } from '..' ;
5
5
import useDatePicker from '../useDatePicker' ;
6
6
7
+ const errorMessages = {
8
+ invalidDate : 'Invalid date' ,
9
+ invalidInput : 'Invalid input' ,
10
+ } ;
11
+
7
12
describe ( 'useDatePicker' , ( ) => {
8
13
let onDayChange : RangeDatePickerProps [ 'onDateChange' ] ;
9
14
let onSlotChange : SingleDatePickerProps [ 'onDateChange' ] ;
@@ -59,22 +64,150 @@ describe('useDatePicker', () => {
59
64
} ) ;
60
65
61
66
describe ( 'input click handling' , ( ) => {
62
- it ( 'should show the picker and call the input onClick callback ' , ( ) => {
63
- const onClickCallback = vi . fn ( ) ;
67
+ it ( 'should not show the picker in single date mode' , ( ) => {
64
68
const { result } = renderHook ( ( ) =>
65
69
useDatePicker ( {
66
- inputProps : { id : 'id' , label : 'label' , onClick : onClickCallback } ,
70
+ inputProps : { id : 'id' , label : 'label' } ,
67
71
isRangeMode : false ,
68
72
onDateChange : onDayChange ,
69
73
} )
70
74
) ;
71
75
72
76
act ( ( ) => {
73
- result . current . handleInputClick ( { } as React . MouseEvent < HTMLInputElement , MouseEvent > ) ;
77
+ result . current . handleInputClick ( ) ;
78
+ } ) ;
79
+
80
+ expect ( result . current . showPicker ) . toBe ( false ) ;
81
+ } ) ;
82
+
83
+ it ( 'should show the picker in range mode' , ( ) => {
84
+ const { result } = renderHook ( ( ) =>
85
+ useDatePicker ( {
86
+ inputProps : { id : 'id' , label : 'label' } ,
87
+ isRangeMode : true ,
88
+ onDateChange : onDayChange ,
89
+ } )
90
+ ) ;
91
+
92
+ act ( ( ) => {
93
+ result . current . handleInputClick ( ) ;
74
94
} ) ;
75
95
76
96
expect ( result . current . showPicker ) . toBe ( true ) ;
77
- expect ( onClickCallback ) . toHaveBeenCalled ( ) ;
97
+ } ) ;
98
+ } ) ;
99
+
100
+ describe ( 'input change handling' , ( ) => {
101
+ describe ( 'single mode' , ( ) => {
102
+ it . each ( [ 'toto' , '01/01/2024' , '01/i' ] ) (
103
+ 'should show an error if the input is invalid (%i)' ,
104
+ ( newValue ) => {
105
+ const { result } = renderHook ( ( ) =>
106
+ useDatePicker ( {
107
+ inputProps : { id : 'id' , label : 'label' } ,
108
+ isRangeMode : false ,
109
+ onDateChange : onDayChange ,
110
+ errorMessages,
111
+ } )
112
+ ) ;
113
+
114
+ act ( ( ) => {
115
+ result . current . handleInputOnChange ( newValue ) ;
116
+ } ) ;
117
+
118
+ expect ( result . current . inputValue ) . toBe ( newValue ) ;
119
+ expect ( result . current . statusWithMessage ) . toEqual ( {
120
+ status : 'error' ,
121
+ message : 'Invalid input' ,
122
+ } ) ;
123
+ expect ( onDayChange ) . not . toBeCalled ( ) ;
124
+ }
125
+ ) ;
126
+
127
+ it ( 'should update the input value if the date string is not complete' , ( ) => {
128
+ const { result } = renderHook ( ( ) =>
129
+ useDatePicker ( {
130
+ inputProps : { id : 'id' , label : 'label' } ,
131
+ isRangeMode : false ,
132
+ onDateChange : onDayChange ,
133
+ errorMessages,
134
+ } )
135
+ ) ;
136
+
137
+ act ( ( ) => {
138
+ result . current . handleInputOnChange ( '3/04/24' ) ;
139
+ } ) ;
140
+
141
+ expect ( result . current . inputValue ) . toBe ( '3/04/24' ) ;
142
+ expect ( result . current . statusWithMessage ) . toBe ( undefined ) ;
143
+ expect ( onDayChange ) . not . toBeCalled ( ) ;
144
+ } ) ;
145
+
146
+ it ( 'should show an error if the date is not within the selectable slot' , ( ) => {
147
+ const { result } = renderHook ( ( ) =>
148
+ useDatePicker ( {
149
+ selectableSlot : { start : new Date ( 2024 , 0 , 1 ) , end : new Date ( 2024 , 1 , 1 ) } ,
150
+ inputProps : { id : 'id' , label : 'label' } ,
151
+ isRangeMode : false ,
152
+ onDateChange : onDayChange ,
153
+ errorMessages,
154
+ } )
155
+ ) ;
156
+
157
+ act ( ( ) => {
158
+ result . current . handleInputOnChange ( '03/04/24' ) ;
159
+ } ) ;
160
+
161
+ expect ( result . current . inputValue ) . toBe ( '03/04/24' ) ;
162
+ expect ( result . current . statusWithMessage ) . toEqual ( {
163
+ status : 'error' ,
164
+ message : 'Invalid date' ,
165
+ } ) ;
166
+ expect ( onDayChange ) . not . toBeCalled ( ) ;
167
+ } ) ;
168
+
169
+ it ( 'should update the parent value is the date is valid' , ( ) => {
170
+ const { result } = renderHook ( ( ) =>
171
+ useDatePicker ( {
172
+ inputProps : { id : 'id' , label : 'label' } ,
173
+ isRangeMode : false ,
174
+ onDateChange : onDayChange ,
175
+ errorMessages,
176
+ } )
177
+ ) ;
178
+
179
+ act ( ( ) => {
180
+ result . current . handleInputOnChange ( '01/02/24' ) ;
181
+ } ) ;
182
+
183
+ expect ( result . current . inputValue ) . toBe ( '01/02/24' ) ;
184
+ expect ( result . current . statusWithMessage ) . toBe ( undefined ) ;
185
+ expect ( onDayChange ) . toHaveBeenCalledWith ( new Date ( 2024 , 1 , 1 ) ) ;
186
+ } ) ;
187
+ } ) ;
188
+
189
+ describe ( 'range mode' , ( ) => {
190
+ it ( 'should do nothing in range mode' , ( ) => {
191
+ const { result } = renderHook ( ( ) =>
192
+ useDatePicker ( {
193
+ value : { start : new Date ( 2024 , 0 , 1 ) , end : null } ,
194
+ inputProps : {
195
+ id : 'id' ,
196
+ label : 'label' ,
197
+ } ,
198
+ isRangeMode : true ,
199
+ onDateChange : onDayChange ,
200
+ errorMessages,
201
+ } )
202
+ ) ;
203
+
204
+ act ( ( ) => {
205
+ result . current . handleInputOnChange ( '01/02/24' ) ;
206
+ } ) ;
207
+
208
+ expect ( result . current . inputValue ) . toBe ( '01/01/24 - ' ) ;
209
+ expect ( onDayChange ) . not . toBeCalled ( ) ;
210
+ } ) ;
78
211
} ) ;
79
212
} ) ;
80
213
} ) ;
0 commit comments