@@ -58,6 +58,7 @@ import {
58
58
} from '../../src/JsonForms' ;
59
59
import {
60
60
JsonFormsStateProvider ,
61
+ Middleware ,
61
62
useJsonForms ,
62
63
withJsonFormsControlProps ,
63
64
} from '../../src/JsonFormsContext' ;
@@ -1100,3 +1101,144 @@ test('JsonForms should use react to additionalErrors update', () => {
1100
1101
expect ( wrapper . find ( 'h5' ) . text ( ) ) . toBe ( 'Foobar' ) ;
1101
1102
wrapper . unmount ( ) ;
1102
1103
} ) ;
1104
+
1105
+ test ( 'JsonForms middleware should be called if provided' , async ( ) => {
1106
+ // given
1107
+ const onChangeHandler = jest . fn ( ) ;
1108
+ const customMiddleware = jest . fn ( ) ;
1109
+ const TestInputRenderer = withJsonFormsControlProps ( ( props ) => (
1110
+ < input
1111
+ onChange = { ( ev ) => props . handleChange ( 'foo' , ev . target . value ) }
1112
+ value = { props . data }
1113
+ />
1114
+ ) ) ;
1115
+ const renderers = [
1116
+ {
1117
+ tester : ( ) => 10 ,
1118
+ renderer : TestInputRenderer ,
1119
+ } ,
1120
+ ] ;
1121
+ const controlledMiddleware : Middleware = ( state , action , reducer ) => {
1122
+ if ( action . type === 'jsonforms/UPDATE' ) {
1123
+ customMiddleware ( ) ;
1124
+ return state ;
1125
+ } else {
1126
+ return reducer ( state , action ) ;
1127
+ }
1128
+ } ;
1129
+ const wrapper = mount (
1130
+ < JsonForms
1131
+ data = { fixture . data }
1132
+ uischema = { fixture . uischema }
1133
+ schema = { fixture . schema }
1134
+ middleware = { controlledMiddleware }
1135
+ onChange = { onChangeHandler }
1136
+ renderers = { renderers }
1137
+ />
1138
+ ) ;
1139
+
1140
+ // wait for 50 ms for the change handler invocation
1141
+ await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) ) ;
1142
+
1143
+ // initial rendering should call onChange 1 time
1144
+ expect ( onChangeHandler ) . toHaveBeenCalledTimes ( 1 ) ;
1145
+ const calls = onChangeHandler . mock . calls ;
1146
+ const lastCallParameter = calls [ calls . length - 1 ] [ 0 ] ;
1147
+ expect ( lastCallParameter . data ) . toEqual ( { foo : 'John Doe' } ) ;
1148
+ expect ( lastCallParameter . errors ) . toEqual ( [ ] ) ;
1149
+
1150
+ // adapt test input
1151
+ wrapper . find ( 'input' ) . simulate ( 'change' , {
1152
+ target : {
1153
+ value : 'Test Value' ,
1154
+ } ,
1155
+ } ) ;
1156
+
1157
+ expect ( customMiddleware ) . toHaveBeenCalledTimes ( 1 ) ;
1158
+
1159
+ // wait for 50 ms for the change handler invocation
1160
+ await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) ) ;
1161
+ // change handler should not have been called another time as we blocked the update in the middleware
1162
+ expect ( onChangeHandler ) . toHaveBeenCalledTimes ( 1 ) ;
1163
+ // The rendered field should also not have been updated
1164
+ expect ( wrapper . find ( 'input' ) . getDOMNode < HTMLInputElement > ( ) . value ) . toBe (
1165
+ 'John Doe'
1166
+ ) ;
1167
+
1168
+ wrapper . unmount ( ) ;
1169
+ } ) ;
1170
+
1171
+ test ( 'JsonForms middleware should update state if modified' , async ( ) => {
1172
+ // given
1173
+ const onChangeHandler = jest . fn ( ) ;
1174
+ const customMiddleware = jest . fn ( ) ;
1175
+ const TestInputRenderer = withJsonFormsControlProps ( ( props ) => (
1176
+ < input
1177
+ onChange = { ( ev ) => props . handleChange ( 'foo' , ev . target . value ) }
1178
+ value = { props . data }
1179
+ />
1180
+ ) ) ;
1181
+ const renderers = [
1182
+ {
1183
+ tester : ( ) => 10 ,
1184
+ renderer : TestInputRenderer ,
1185
+ } ,
1186
+ ] ;
1187
+ const controlledMiddleware : Middleware = ( state , action , reducer ) => {
1188
+ if ( action . type === 'jsonforms/UPDATE' ) {
1189
+ customMiddleware ( ) ;
1190
+ const newState = reducer ( state , action ) ;
1191
+ return { ...newState , data : { foo : `${ newState . data . foo } Test` } } ;
1192
+ } else {
1193
+ return reducer ( state , action ) ;
1194
+ }
1195
+ } ;
1196
+ const wrapper = mount (
1197
+ < JsonForms
1198
+ data = { fixture . data }
1199
+ uischema = { fixture . uischema }
1200
+ schema = { fixture . schema }
1201
+ middleware = { controlledMiddleware }
1202
+ onChange = { onChangeHandler }
1203
+ renderers = { renderers }
1204
+ />
1205
+ ) ;
1206
+
1207
+ // wait for 50 ms for the change handler invocation
1208
+ await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) ) ;
1209
+
1210
+ // initial rendering should call onChange 1 time
1211
+ expect ( onChangeHandler ) . toHaveBeenCalledTimes ( 1 ) ;
1212
+ {
1213
+ const calls = onChangeHandler . mock . calls ;
1214
+ const lastCallParameter = calls [ calls . length - 1 ] [ 0 ] ;
1215
+ expect ( lastCallParameter . data ) . toEqual ( { foo : 'John Doe' } ) ;
1216
+ expect ( lastCallParameter . errors ) . toEqual ( [ ] ) ;
1217
+ }
1218
+
1219
+ // adapt input
1220
+ wrapper . find ( 'input' ) . simulate ( 'change' , {
1221
+ target : {
1222
+ value : 'Test Value' ,
1223
+ } ,
1224
+ } ) ;
1225
+
1226
+ // then
1227
+ expect ( customMiddleware ) . toHaveBeenCalledTimes ( 1 ) ;
1228
+ expect ( wrapper . find ( 'input' ) . getDOMNode < HTMLInputElement > ( ) . value ) . toBe (
1229
+ 'Test Value Test'
1230
+ ) ;
1231
+
1232
+ // wait for 50 ms for the change handler invocation
1233
+ await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) ) ;
1234
+ // onChangeHandler should have been called after the state update
1235
+ expect ( onChangeHandler ) . toHaveBeenCalledTimes ( 2 ) ;
1236
+ {
1237
+ const calls = onChangeHandler . mock . calls ;
1238
+ const lastCallParameter = calls [ calls . length - 1 ] [ 0 ] ;
1239
+ expect ( lastCallParameter . data ) . toEqual ( { foo : 'Test Value Test' } ) ;
1240
+ expect ( lastCallParameter . errors ) . toEqual ( [ ] ) ;
1241
+ }
1242
+
1243
+ wrapper . unmount ( ) ;
1244
+ } ) ;
0 commit comments