Skip to content

Commit 662d598

Browse files
dholmes2409sdirix
authored andcommitted
test: unit tests for React middleware support
1 parent a4c8e9c commit 662d598

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

packages/react/test/renderers/JsonForms.test.tsx

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import {
5858
} from '../../src/JsonForms';
5959
import {
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

Comments
 (0)