@@ -3980,3 +3980,96 @@ it('should accept formId and return it', () => {
3980
3980
3981
3981
expect ( form . formId ) . toEqual ( 'age' )
3982
3982
} )
3983
+
3984
+ it ( 'should call onSubmitInvalid with current error state when canSubmit is false' , async ( ) => {
3985
+ const onInvalid = vi . fn ( )
3986
+
3987
+ const form = new FormApi ( {
3988
+ defaultValues : { name : '' , email : '' } ,
3989
+ validators : {
3990
+ onMount : ( { value } ) => {
3991
+ const errors : Record < string , string > = { }
3992
+ if ( ! value . name ) errors . name = 'Name is required'
3993
+ if ( ! value . email ) errors . email = 'Email is required'
3994
+ return Object . keys ( errors ) . length > 0 ? errors : undefined
3995
+ } ,
3996
+ } ,
3997
+ onSubmitInvalid : ( { value, formApi } ) => {
3998
+ onInvalid ( value , formApi . state . errors )
3999
+ } ,
4000
+ } )
4001
+
4002
+ form . mount ( )
4003
+
4004
+ new FieldApi ( { form, name : 'name' } ) . mount ( )
4005
+ new FieldApi ( { form, name : 'email' } ) . mount ( )
4006
+
4007
+ expect ( form . state . canSubmit ) . toBe ( false )
4008
+
4009
+ await form . handleSubmit ( )
4010
+
4011
+ expect ( onInvalid ) . toHaveBeenCalledTimes ( 1 )
4012
+ expect ( onInvalid ) . toHaveBeenCalledWith (
4013
+ { name : '' , email : '' } ,
4014
+ expect . any ( Object ) ,
4015
+ )
4016
+ } )
4017
+
4018
+ it ( 'should not run submit validation when canSubmit is false' , async ( ) => {
4019
+ const onSubmitValidator = vi . fn ( )
4020
+ const onInvalid = vi . fn ( )
4021
+
4022
+ const form = new FormApi ( {
4023
+ defaultValues : { name : '' } ,
4024
+ validators : {
4025
+ onMount : ( { value } ) => ( ! value . name ? 'Name required' : undefined ) ,
4026
+ onSubmit : ( { value } ) => {
4027
+ onSubmitValidator ( )
4028
+ return ! value . name ? 'Submit validation failed' : undefined
4029
+ } ,
4030
+ } ,
4031
+ onSubmitInvalid : ( { value, formApi } ) => {
4032
+ onInvalid ( value , formApi )
4033
+ } ,
4034
+ } )
4035
+
4036
+ form . mount ( )
4037
+ new FieldApi ( { form, name : 'name' } ) . mount ( )
4038
+
4039
+ expect ( form . state . canSubmit ) . toBe ( false )
4040
+
4041
+ await form . handleSubmit ( )
4042
+
4043
+ expect ( onSubmitValidator ) . not . toHaveBeenCalled ( )
4044
+ expect ( onInvalid ) . toHaveBeenCalledTimes ( 1 )
4045
+ } )
4046
+
4047
+ it ( 'should respect canSubmitWhenInvalid option and run validation even when canSubmit is false' , async ( ) => {
4048
+ const onSubmitValidator = vi . fn ( )
4049
+ const onInvalid = vi . fn ( )
4050
+
4051
+ const form = new FormApi ( {
4052
+ defaultValues : { name : '' } ,
4053
+ canSubmitWhenInvalid : true ,
4054
+ validators : {
4055
+ onMount : ( { value } ) => ( ! value . name ? 'Name required' : undefined ) ,
4056
+ onSubmit : ( { value } ) => {
4057
+ onSubmitValidator ( )
4058
+ return ! value . name ? 'Submit validation failed' : undefined
4059
+ } ,
4060
+ } ,
4061
+ onSubmitInvalid : ( { value, formApi } ) => {
4062
+ onInvalid ( value , formApi )
4063
+ } ,
4064
+ } )
4065
+
4066
+ form . mount ( )
4067
+ new FieldApi ( { form, name : 'name' } ) . mount ( )
4068
+
4069
+ expect ( form . state . canSubmit ) . toBe ( true )
4070
+
4071
+ await form . handleSubmit ( )
4072
+
4073
+ expect ( onSubmitValidator ) . toHaveBeenCalledTimes ( 1 )
4074
+ expect ( onInvalid ) . toHaveBeenCalledTimes ( 1 )
4075
+ } )
0 commit comments