@@ -58,6 +58,7 @@ import {
5858} from '../../src/JsonForms' ;
5959import {
6060 JsonFormsStateProvider ,
61+ Middleware ,
6162 useJsonForms ,
6263 withJsonFormsControlProps ,
6364} from '../../src/JsonFormsContext' ;
@@ -1100,3 +1101,144 @@ test('JsonForms should use react to additionalErrors update', () => {
11001101 expect ( wrapper . find ( 'h5' ) . text ( ) ) . toBe ( 'Foobar' ) ;
11011102 wrapper . unmount ( ) ;
11021103} ) ;
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