Skip to content

Commit cf6e21b

Browse files
committed
Add tests for common wizard
1 parent 3d00774 commit cf6e21b

File tree

1 file changed

+350
-0
lines changed

1 file changed

+350
-0
lines changed
Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
import React, { useContext } from 'react';
2+
import { act } from 'react-dom/test-utils';
3+
import { FormRenderer, WizardContext, componentTypes, useFieldApi } from '@data-driven-forms/react-form-renderer';
4+
import { mount } from 'enzyme';
5+
6+
import Wizard from '../../wizard';
7+
8+
describe('wizard test', () => {
9+
let state;
10+
let wrapper;
11+
12+
const fields = [
13+
{
14+
name: 'step1',
15+
nextStep: 'step2',
16+
title: 'step1',
17+
fields: []
18+
},
19+
{
20+
name: 'step2',
21+
substepOf: { title: 'title', name: 'eaa' },
22+
nextStep: 'step3',
23+
fields: []
24+
},
25+
{
26+
name: 'step3',
27+
substepOf: 'eaa',
28+
nextStep: {
29+
when: 'field1',
30+
stepMapper: {
31+
x: 'step4'
32+
}
33+
},
34+
fields: []
35+
},
36+
{ name: 'step4', nextStep: ({ values }) => values.field2, fields: [] },
37+
{ name: 'step5', fields: [] }
38+
];
39+
40+
// expected navSchema
41+
const navSchema = [
42+
{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' },
43+
{ index: 1, name: 'step2', primary: true, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
44+
{ index: 2, name: 'step3', primary: false, substepOf: 'eaa', substepOfTitle: 'title', title: undefined }
45+
];
46+
47+
const spyState = (newState) => {
48+
state = newState;
49+
};
50+
51+
const Dummy = () => {
52+
const { handleNext, handlePrev, setPrevSteps, onKeyDown, formOptions, selectNext, jumpToStep, ...state } = useContext(WizardContext);
53+
54+
spyState(state);
55+
56+
return (
57+
<React.Fragment>
58+
<button id="handleNext" onClick={() => handleNext(selectNext(state.currentStep.nextStep, formOptions.getState))} />
59+
<button id="handlePrev" onClick={handlePrev} />
60+
<button id="setPrevSteps" onClick={setPrevSteps} />
61+
<button id="jumpToStepValid" onClick={() => jumpToStep(0, true)} />
62+
<button id="jumpToStepInvalid" onClick={() => jumpToStep(0, false)} />
63+
<button id="handleSubmit" onClick={formOptions.handleSubmit} />
64+
<div id="onKeyDown" onKeyDown={onKeyDown} />
65+
{formOptions.renderForm(state.currentStep?.fields || [])}
66+
</React.Fragment>
67+
);
68+
};
69+
70+
const WizardTest = (props) => <Wizard Wizard={Dummy} {...props} />;
71+
72+
const rendererProps = {
73+
onSubmit: jest.fn(),
74+
FormTemplate: ({ formFields }) => formFields,
75+
componentMapper: { [componentTypes.WIZARD]: WizardTest },
76+
schema: {
77+
fields: [
78+
{
79+
name: 'wizard',
80+
component: componentTypes.WIZARD,
81+
fields
82+
}
83+
]
84+
}
85+
};
86+
87+
it('handle next and handle prev', async () => {
88+
await act(async () => {
89+
wrapper = mount(<FormRenderer {...rendererProps} />);
90+
});
91+
wrapper.update();
92+
93+
expect(state).toEqual({
94+
activeStepIndex: 0,
95+
crossroads: undefined,
96+
currentStep: { fields: [], name: 'step1', nextStep: 'step2', title: 'step1' },
97+
isDynamic: true,
98+
maxStepIndex: 0,
99+
navSchema,
100+
prevSteps: []
101+
});
102+
103+
await act(async () => {
104+
wrapper.find('#handleNext').simulate('click');
105+
});
106+
wrapper.update();
107+
108+
expect(state).toEqual({
109+
activeStepIndex: 1,
110+
crossroads: undefined,
111+
currentStep: { fields: [], name: 'step2', nextStep: 'step3', substepOf: { name: 'eaa', title: 'title' } },
112+
isDynamic: true,
113+
maxStepIndex: 1,
114+
navSchema,
115+
prevSteps: ['step1']
116+
});
117+
118+
await act(async () => {
119+
wrapper.find('#handlePrev').simulate('click');
120+
});
121+
wrapper.update();
122+
123+
expect(state).toEqual({
124+
activeStepIndex: 0,
125+
crossroads: undefined,
126+
currentStep: { fields: [], name: 'step1', nextStep: 'step2', title: 'step1' },
127+
isDynamic: true,
128+
maxStepIndex: 1,
129+
navSchema,
130+
prevSteps: ['step1', 'step2']
131+
});
132+
});
133+
134+
it('creates full schema', async () => {
135+
await act(async () => {
136+
wrapper = mount(<FormRenderer {...rendererProps} initialValues={{ field1: 'x', field2: 'step5' }} />);
137+
});
138+
wrapper.update();
139+
140+
expect(state.navSchema).toEqual([
141+
{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' },
142+
{ index: 1, name: 'step2', primary: true, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
143+
{ index: 2, name: 'step3', primary: false, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
144+
{ index: 3, name: 'step4', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined },
145+
{ index: 4, name: 'step5', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined }
146+
]);
147+
});
148+
149+
it('onKeyDown - goes to the next step', async () => {
150+
await act(async () => {
151+
wrapper = mount(<FormRenderer {...rendererProps} />);
152+
});
153+
wrapper.update();
154+
155+
await act(async () => {
156+
wrapper.find('#onKeyDown').simulate('keydown', { preventDefault: jest.fn(), key: 'Enter' });
157+
});
158+
wrapper.update();
159+
160+
expect(state).toEqual({
161+
activeStepIndex: 1,
162+
crossroads: undefined,
163+
currentStep: { fields: [], name: 'step2', nextStep: 'step3', substepOf: { name: 'eaa', title: 'title' } },
164+
isDynamic: true,
165+
maxStepIndex: 1,
166+
navSchema,
167+
prevSteps: ['step1']
168+
});
169+
});
170+
171+
it('jumpToStep - when valid', async () => {
172+
await act(async () => {
173+
wrapper = mount(<FormRenderer {...rendererProps} />);
174+
});
175+
wrapper.update();
176+
177+
await act(async () => {
178+
wrapper.find('#handleNext').simulate('click');
179+
});
180+
wrapper.update();
181+
182+
await act(async () => {
183+
wrapper.find('#jumpToStepValid').simulate('click');
184+
});
185+
wrapper.update();
186+
187+
expect(state).toEqual({
188+
activeStepIndex: 0,
189+
crossroads: undefined,
190+
currentStep: { fields: [], name: 'step1', nextStep: 'step2', title: 'step1' },
191+
isDynamic: true,
192+
maxStepIndex: 1,
193+
navSchema,
194+
prevSteps: ['step1', 'step2']
195+
});
196+
});
197+
198+
it('jumpToStep - when invalid', async () => {
199+
await act(async () => {
200+
wrapper = mount(<FormRenderer {...rendererProps} />);
201+
});
202+
wrapper.update();
203+
204+
await act(async () => {
205+
wrapper.find('#handleNext').simulate('click');
206+
});
207+
wrapper.update();
208+
209+
await act(async () => {
210+
wrapper.find('#jumpToStepInvalid').simulate('click');
211+
});
212+
wrapper.update();
213+
214+
expect(state).toEqual({
215+
activeStepIndex: 0,
216+
crossroads: undefined,
217+
currentStep: { fields: [], name: 'step1', nextStep: 'step2', title: 'step1' },
218+
isDynamic: true,
219+
maxStepIndex: 1,
220+
navSchema,
221+
prevSteps: ['step1', 'step2']
222+
});
223+
});
224+
225+
it('setPrevSteps - resets state according to the current path', async () => {
226+
await act(async () => {
227+
wrapper = mount(
228+
<FormRenderer
229+
{...rendererProps}
230+
schema={{
231+
fields: [
232+
{
233+
component: componentTypes.WIZARD,
234+
name: 'wizard',
235+
fields,
236+
initialState: {
237+
prevSteps: ['step1', 'step2', 'step3']
238+
}
239+
}
240+
]
241+
}}
242+
/>
243+
);
244+
});
245+
wrapper.update();
246+
247+
expect(state.prevSteps).toEqual(['step1', 'step2', 'step3']);
248+
249+
await act(async () => {
250+
wrapper.find('#setPrevSteps').simulate('click');
251+
});
252+
wrapper.update();
253+
254+
expect(state).toEqual({
255+
activeStepIndex: 0,
256+
crossroads: undefined,
257+
currentStep: { fields: [], name: 'step1', nextStep: 'step2', title: 'step1' },
258+
isDynamic: true,
259+
maxStepIndex: 0,
260+
navSchema,
261+
prevSteps: []
262+
});
263+
});
264+
265+
it('submits sends only visited values', async () => {
266+
const DummyTextField = (props) => {
267+
const { input } = useFieldApi(props);
268+
return <input {...input} />;
269+
};
270+
271+
const submitSpy = jest.fn();
272+
273+
await act(async () => {
274+
wrapper = mount(
275+
<FormRenderer
276+
{...rendererProps}
277+
componentMapper={{
278+
...rendererProps.componentMapper,
279+
[componentTypes.TEXT_FIELD]: DummyTextField
280+
}}
281+
onSubmit={(values) => submitSpy(values)}
282+
schema={{
283+
fields: [
284+
{
285+
component: componentTypes.WIZARD,
286+
name: 'wizard',
287+
fields: [
288+
{
289+
name: 'step1',
290+
nextStep: {
291+
when: 'value1',
292+
stepMapper: {
293+
x: 'step2',
294+
y: 'step3'
295+
}
296+
},
297+
fields: [{ component: componentTypes.TEXT_FIELD, name: 'value1', initialValue: 'x' }]
298+
},
299+
{
300+
name: 'step2',
301+
fields: [{ component: componentTypes.TEXT_FIELD, name: 'value2', initialValue: 'x-value2' }]
302+
},
303+
{
304+
name: 'step3',
305+
fields: [{ component: componentTypes.TEXT_FIELD, name: 'value3', initialValue: 'x-value3' }]
306+
}
307+
]
308+
}
309+
]
310+
}}
311+
/>
312+
);
313+
});
314+
wrapper.update();
315+
316+
await act(async () => {
317+
wrapper.find('#handleNext').simulate('click');
318+
});
319+
wrapper.update();
320+
await act(async () => {
321+
wrapper.find('#handleSubmit').simulate('click');
322+
});
323+
wrapper.update();
324+
325+
expect(submitSpy).toHaveBeenCalledWith({ value1: 'x', value2: 'x-value2' });
326+
submitSpy.mockClear();
327+
328+
await act(async () => {
329+
wrapper.find('#handlePrev').simulate('click');
330+
});
331+
wrapper.update();
332+
333+
await act(async () => {
334+
wrapper.find('input').instance().value = 'y';
335+
wrapper.find('input').simulate('change');
336+
});
337+
wrapper.update();
338+
339+
await act(async () => {
340+
wrapper.find('#handleNext').simulate('click');
341+
});
342+
wrapper.update();
343+
await act(async () => {
344+
wrapper.find('#handleSubmit').simulate('click');
345+
});
346+
wrapper.update();
347+
348+
expect(submitSpy).toHaveBeenCalledWith({ value1: 'y', value3: 'x-value3' });
349+
});
350+
});

0 commit comments

Comments
 (0)