@@ -33,7 +33,17 @@ interface Props {
3333 onData : FormSubmitHandler < MyForm > ;
3434}
3535
36+ let formHook : FormHook < any > | null = null ;
37+
38+ const onFormHook = ( _form : FormHook < any > ) => {
39+ formHook = _form ;
40+ } ;
41+
3642describe ( 'use_form() hook' , ( ) => {
43+ beforeEach ( ( ) => {
44+ formHook = null ;
45+ } ) ;
46+
3747 describe ( 'form.submit() & config.onSubmit()' , ( ) => {
3848 const onFormData = jest . fn ( ) ;
3949
@@ -125,12 +135,6 @@ describe('use_form() hook', () => {
125135 } ) ;
126136
127137 test ( 'should not build the object if the form is not valid' , async ( ) => {
128- let formHook : FormHook < MyForm > | null = null ;
129-
130- const onFormHook = ( _form : FormHook < MyForm > ) => {
131- formHook = _form ;
132- } ;
133-
134138 const TestComp = ( { onForm } : { onForm : ( form : FormHook < MyForm > ) => void } ) => {
135139 const { form } = useForm < MyForm > ( { defaultValue : { username : 'initialValue' } } ) ;
136140 const validator : ValidationFunc = ( { value } ) => {
@@ -141,7 +145,7 @@ describe('use_form() hook', () => {
141145
142146 useEffect ( ( ) => {
143147 onForm ( form ) ;
144- } , [ form ] ) ;
148+ } , [ onForm , form ] ) ;
145149
146150 return (
147151 < Form form = { form } >
@@ -297,4 +301,145 @@ describe('use_form() hook', () => {
297301 } ) ;
298302 } ) ;
299303 } ) ;
304+
305+ describe ( 'form.reset()' , ( ) => {
306+ const defaultValue = {
307+ username : 'defaultValue' ,
308+ deeply : { nested : { value : 'defaultValue' } } ,
309+ } ;
310+
311+ type RestFormTest = typeof defaultValue ;
312+
313+ const TestComp = ( { onForm } : { onForm : ( form : FormHook < any > ) => void } ) => {
314+ const { form } = useForm < RestFormTest > ( {
315+ defaultValue,
316+ options : { stripEmptyFields : false } ,
317+ } ) ;
318+
319+ useEffect ( ( ) => {
320+ onForm ( form ) ;
321+ } , [ onForm , form ] ) ;
322+
323+ return (
324+ < Form form = { form } >
325+ < UseField
326+ path = "username"
327+ config = { { defaultValue : 'configDefaultValue' } }
328+ data-test-subj = "userNameField"
329+ />
330+ < UseField
331+ path = "city"
332+ config = { { defaultValue : 'configDefaultValue' } }
333+ defaultValue = "inlineDefaultValue"
334+ data-test-subj = "cityField"
335+ />
336+ < UseField path = "deeply.nested.value" data-test-subj = "deeplyNestedField" />
337+ </ Form >
338+ ) ;
339+ } ;
340+
341+ const setup = registerTestBed ( TestComp , {
342+ defaultProps : { onForm : onFormHook } ,
343+ memoryRouter : { wrapComponent : false } ,
344+ } ) ;
345+
346+ test ( 'should put back the defaultValue for each field' , async ( ) => {
347+ const {
348+ form : { setInputValue } ,
349+ } = setup ( ) as TestBed ;
350+
351+ if ( ! formHook ) {
352+ throw new Error (
353+ `formHook is not defined. Use the onForm() prop to update the reference to the form hook.`
354+ ) ;
355+ }
356+
357+ let formData : Partial < RestFormTest > = { } ;
358+
359+ await act ( async ( ) => {
360+ formData = formHook ! . getFormData ( ) ;
361+ } ) ;
362+ expect ( formData ) . toEqual ( {
363+ username : 'defaultValue' ,
364+ city : 'inlineDefaultValue' ,
365+ deeply : { nested : { value : 'defaultValue' } } ,
366+ } ) ;
367+
368+ setInputValue ( 'userNameField' , 'changedValue' ) ;
369+ setInputValue ( 'cityField' , 'changedValue' ) ;
370+ setInputValue ( 'deeplyNestedField' , 'changedValue' ) ;
371+
372+ await act ( async ( ) => {
373+ formData = formHook ! . getFormData ( ) ;
374+ } ) ;
375+ expect ( formData ) . toEqual ( {
376+ username : 'changedValue' ,
377+ city : 'changedValue' ,
378+ deeply : { nested : { value : 'changedValue' } } ,
379+ } ) ;
380+
381+ await act ( async ( ) => {
382+ formHook ! . reset ( ) ;
383+ } ) ;
384+
385+ await act ( async ( ) => {
386+ formData = formHook ! . getFormData ( ) ;
387+ } ) ;
388+ expect ( formData ) . toEqual ( {
389+ username : 'defaultValue' ,
390+ city : 'inlineDefaultValue' , // Inline default value is correctly kept after resetting
391+ deeply : { nested : { value : 'defaultValue' } } ,
392+ } ) ;
393+ } ) ;
394+
395+ test ( 'should allow to pass a new "defaultValue" object for the fields' , async ( ) => {
396+ const {
397+ form : { setInputValue } ,
398+ } = setup ( ) as TestBed ;
399+
400+ if ( ! formHook ) {
401+ throw new Error (
402+ `formHook is not defined. Use the onForm() prop to update the reference to the form hook.`
403+ ) ;
404+ }
405+
406+ setInputValue ( 'userNameField' , 'changedValue' ) ;
407+ setInputValue ( 'cityField' , 'changedValue' ) ;
408+ setInputValue ( 'deeplyNestedField' , 'changedValue' ) ;
409+
410+ let formData : Partial < RestFormTest > = { } ;
411+
412+ await act ( async ( ) => {
413+ formHook ! . reset ( {
414+ defaultValue : {
415+ city : ( ) => 'newDefaultValue' , // A function can also be passed
416+ deeply : { nested : { value : 'newDefaultValue' } } ,
417+ } ,
418+ } ) ;
419+ } ) ;
420+ await act ( async ( ) => {
421+ formData = formHook ! . getFormData ( ) ;
422+ } ) ;
423+ expect ( formData ) . toEqual ( {
424+ username : 'configDefaultValue' , // Back to the config defaultValue as no value was provided when resetting
425+ city : 'newDefaultValue' ,
426+ deeply : { nested : { value : 'newDefaultValue' } } ,
427+ } ) ;
428+
429+ // Make sure all field are back to the config defautlValue, even when we have a UseField with inline prop "defaultValue"
430+ await act ( async ( ) => {
431+ formHook ! . reset ( {
432+ defaultValue : { } ,
433+ } ) ;
434+ } ) ;
435+ await act ( async ( ) => {
436+ formData = formHook ! . getFormData ( ) ;
437+ } ) ;
438+ expect ( formData ) . toEqual ( {
439+ username : 'configDefaultValue' ,
440+ city : 'configDefaultValue' , // Inline default value **is not** kept after resetting with undefined "city" value
441+ deeply : { nested : { value : '' } } , // Fallback to empty string as no config was provided
442+ } ) ;
443+ } ) ;
444+ } ) ;
300445} ) ;
0 commit comments