Skip to content

Commit 3d00774

Browse files
committed
Add tests for common package
1 parent b26f3c7 commit 3d00774

File tree

6 files changed

+436
-39
lines changed

6 files changed

+436
-39
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { fnToString } from '../utils';
2+
3+
describe('utils', () => {
4+
describe('fnToString', () => {
5+
it('converts simple function to string', () => {
6+
function x(add, x) {
7+
return add + x;
8+
}
9+
10+
expect(fnToString(x)).toEqual('function x(add, x) { return add + x; }');
11+
});
12+
13+
it('no function', () => {
14+
expect(fnToString()).toEqual('');
15+
});
16+
});
17+
});
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import enterHandler from '../../wizard/enter-handler';
2+
3+
describe('enterHandler', () => {
4+
let e;
5+
let formOptions;
6+
let activeStep;
7+
let findCurrentStep;
8+
let handleNext;
9+
let handleSubmit;
10+
11+
const getRegisteredFields = () => [];
12+
13+
beforeEach(() => {
14+
e = { key: 'Enter', target: { type: 'input' }, preventDefault: jest.fn() };
15+
formOptions = { valid: true, getState: () => ({ validating: false }), getRegisteredFields };
16+
activeStep = 'activeStep';
17+
findCurrentStep = jest.fn().mockImplementation(() => ({
18+
nextStep: 'nextStep'
19+
}));
20+
handleNext = jest.fn();
21+
handleSubmit = jest.fn();
22+
});
23+
24+
it('pressed not enter', () => {
25+
e = { ...e, key: 'A' };
26+
27+
enterHandler(e, formOptions, activeStep, findCurrentStep, handleNext, handleSubmit);
28+
29+
expect(handleSubmit).not.toHaveBeenCalled();
30+
expect(handleNext).not.toHaveBeenCalled();
31+
});
32+
33+
it('pressed enter on button', () => {
34+
e = { ...e, target: { type: 'button' } };
35+
36+
enterHandler(e, formOptions, activeStep, findCurrentStep, handleNext, handleSubmit);
37+
38+
expect(handleSubmit).not.toHaveBeenCalled();
39+
expect(handleNext).not.toHaveBeenCalled();
40+
});
41+
42+
it('pressed enter with ctrl', () => {
43+
e = { ...e, ctrlKey: true };
44+
45+
enterHandler(e, formOptions, activeStep, findCurrentStep, handleNext, handleSubmit);
46+
47+
expect(handleSubmit).not.toHaveBeenCalled();
48+
expect(handleNext).not.toHaveBeenCalled();
49+
});
50+
51+
it('pressed enter with shift', () => {
52+
e = { ...e, shiftKey: true };
53+
54+
enterHandler(e, formOptions, activeStep, findCurrentStep, handleNext, handleSubmit);
55+
56+
expect(handleSubmit).not.toHaveBeenCalled();
57+
expect(handleNext).not.toHaveBeenCalled();
58+
});
59+
60+
it('pressed enter and submit', () => {
61+
findCurrentStep = jest.fn().mockImplementation(() => ({
62+
nextStep: undefined
63+
}));
64+
65+
enterHandler(e, formOptions, activeStep, findCurrentStep, handleNext, handleSubmit);
66+
67+
expect(handleSubmit).toHaveBeenCalled();
68+
expect(handleNext).not.toHaveBeenCalled();
69+
});
70+
71+
it('pressed enter and go to next step', () => {
72+
enterHandler(e, formOptions, activeStep, findCurrentStep, handleNext, handleSubmit);
73+
74+
expect(handleSubmit).not.toHaveBeenCalled();
75+
expect(handleNext).toHaveBeenCalledWith('nextStep', getRegisteredFields);
76+
});
77+
78+
it('pressed enter when not valid', () => {
79+
formOptions = { ...formOptions, valid: false };
80+
81+
enterHandler(e, formOptions, activeStep, findCurrentStep, handleNext, handleSubmit);
82+
83+
expect(handleSubmit).not.toHaveBeenCalled();
84+
expect(handleNext).not.toHaveBeenCalled();
85+
});
86+
87+
it('pressed enter when validating', () => {
88+
formOptions = { ...formOptions, getState: () => ({ validating: true }) };
89+
90+
enterHandler(e, formOptions, activeStep, findCurrentStep, handleNext, handleSubmit);
91+
92+
expect(handleSubmit).not.toHaveBeenCalled();
93+
expect(handleNext).not.toHaveBeenCalled();
94+
});
95+
96+
it('pressed enter with custom buttons', () => {
97+
findCurrentStep = jest.fn().mockImplementation(() => ({
98+
nextStep: undefined,
99+
buttons: 'something'
100+
}));
101+
102+
enterHandler(e, formOptions, activeStep, findCurrentStep, handleNext, handleSubmit);
103+
104+
expect(handleSubmit).not.toHaveBeenCalled();
105+
expect(handleNext).not.toHaveBeenCalled();
106+
});
107+
});
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
import reducer from '../../wizard/reducer';
2+
3+
describe('wizard reducer', () => {
4+
let fields;
5+
const getState = () => ({
6+
values: {
7+
field1: 'x',
8+
field2: 'step5'
9+
}
10+
});
11+
12+
beforeEach(() => {
13+
fields = [
14+
{
15+
name: 'step1',
16+
nextStep: 'step2',
17+
title: 'step1'
18+
},
19+
{
20+
name: 'step2',
21+
substepOf: { title: 'title', name: 'eaa' },
22+
nextStep: 'step3'
23+
},
24+
{
25+
name: 'step3',
26+
substepOf: 'eaa',
27+
nextStep: {
28+
when: 'field1',
29+
stepMapper: {
30+
x: 'step4'
31+
}
32+
}
33+
},
34+
{ name: 'step4', nextStep: ({ values }) => values.field2 },
35+
{ name: 'step5' }
36+
];
37+
});
38+
39+
describe('finishLoading', () => {
40+
it('creates schema', () => {
41+
const formOptions = { getState };
42+
43+
expect(reducer({}, { type: 'finishLoading', payload: { fields, formOptions } })).toEqual({
44+
loading: false,
45+
navSchema: [
46+
{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' },
47+
{ index: 1, name: 'step2', primary: true, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
48+
{ index: 2, name: 'step3', primary: false, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
49+
{ index: 3, name: 'step4', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined },
50+
{ index: 4, name: 'step5', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined }
51+
]
52+
});
53+
});
54+
});
55+
56+
describe('handleNext', () => {
57+
it('calls next when dynamic', () => {
58+
const state = {
59+
activeStepIndex: 1,
60+
activeStep: 'step2',
61+
prevSteps: ['step1'],
62+
registeredFields: { step1: ['field1'] },
63+
maxStepIndex: 1,
64+
isDynamic: true,
65+
navSchema: [{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' }]
66+
};
67+
const nextStep = 'step3';
68+
const formOptions = { getState, getRegisteredFields: () => ['field3'] };
69+
70+
expect(reducer(state, { type: 'handleNext', payload: { nextStep, formOptions, fields } })).toEqual({
71+
activeStep: 'step3',
72+
activeStepIndex: 2,
73+
isDynamic: true,
74+
maxStepIndex: 2,
75+
navSchema: [
76+
{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' },
77+
{ index: 1, name: 'step2', primary: true, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
78+
{ index: 2, name: 'step3', primary: false, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
79+
{ index: 3, name: 'step4', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined },
80+
{ index: 4, name: 'step5', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined }
81+
],
82+
prevSteps: ['step1', 'step2'],
83+
registeredFields: { step1: ['field1'] },
84+
registeredFieldsHistory: { step2: ['field3'] }
85+
});
86+
});
87+
88+
it('calls next when static', () => {
89+
const state = {
90+
activeStepIndex: 1,
91+
activeStep: 'step2',
92+
prevSteps: ['step1'],
93+
registeredFields: { step1: ['field1'] },
94+
maxStepIndex: 1,
95+
isDynamic: false,
96+
navSchema: [{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' }]
97+
};
98+
const nextStep = 'step3';
99+
const formOptions = { getState, getRegisteredFields: () => ['field3'] };
100+
101+
expect(reducer(state, { type: 'handleNext', payload: { nextStep, formOptions, fields } })).toEqual({
102+
activeStep: 'step3',
103+
activeStepIndex: 2,
104+
isDynamic: false,
105+
maxStepIndex: 2,
106+
navSchema: [{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' }],
107+
prevSteps: ['step1', 'step2'],
108+
registeredFields: { step1: ['field1'] },
109+
registeredFieldsHistory: { step2: ['field3'] }
110+
});
111+
});
112+
113+
it('calls next when going back from visited', () => {
114+
const state = {
115+
activeStepIndex: 0,
116+
activeStep: 'step1',
117+
prevSteps: ['step1', 'step2'],
118+
registeredFields: { step1: ['field1'] },
119+
maxStepIndex: 1,
120+
isDynamic: true,
121+
navSchema: [{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' }]
122+
};
123+
const nextStep = 'step2';
124+
const formOptions = { getState, getRegisteredFields: () => ['field3'] };
125+
126+
expect(reducer(state, { type: 'handleNext', payload: { nextStep, formOptions, fields } })).toEqual({
127+
activeStep: 'step2',
128+
activeStepIndex: 1,
129+
isDynamic: true,
130+
maxStepIndex: 1,
131+
navSchema: [
132+
{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' },
133+
{ index: 1, name: 'step2', primary: true, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
134+
{ index: 2, name: 'step3', primary: false, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
135+
{ index: 3, name: 'step4', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined },
136+
{ index: 4, name: 'step5', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined }
137+
],
138+
prevSteps: ['step1', 'step2'],
139+
registeredFields: { step1: ['field1'] },
140+
registeredFieldsHistory: { step1: ['field3'] }
141+
});
142+
});
143+
});
144+
145+
describe('jumpToStep', () => {
146+
let index;
147+
let valid;
148+
let crossroads;
149+
let formOptions;
150+
151+
beforeEach(() => {
152+
index = 1;
153+
valid = true;
154+
crossroads = [];
155+
formOptions = { getState };
156+
});
157+
158+
it('click on the same step', () => {
159+
expect(reducer({ activeStepIndex: 1 }, { type: 'jumpToStep', payload: { index, valid, fields, crossroads, formOptions } })).toEqual({
160+
activeStepIndex: 1
161+
});
162+
});
163+
164+
it('click on the step that is not visited yet', () => {
165+
index = 5;
166+
167+
expect(
168+
reducer(
169+
{ activeStepIndex: 2, isDynamic: false, prevSteps: ['step1', 'step2'], activeStep: 'step3' },
170+
{ type: 'jumpToStep', payload: { index, valid, fields, crossroads, formOptions } }
171+
)
172+
).toEqual({ activeStepIndex: 2, isDynamic: false, prevSteps: ['step1', 'step2'], activeStep: 'step3' });
173+
});
174+
175+
it('previous step', () => {
176+
expect(
177+
reducer(
178+
{ activeStepIndex: 2, isDynamic: false, prevSteps: ['step1', 'step2'], activeStep: 'step3' },
179+
{ type: 'jumpToStep', payload: { index, valid, fields, crossroads, formOptions } }
180+
)
181+
).toEqual({ activeStep: 'step2', activeStepIndex: 1, isDynamic: false, prevSteps: ['step1', 'step2', 'step3'] });
182+
});
183+
184+
it('previous step included in prevSteps', () => {
185+
expect(
186+
reducer(
187+
{ activeStepIndex: 2, isDynamic: false, prevSteps: ['step1', 'step2', 'step3'], activeStep: 'step3' },
188+
{ type: 'jumpToStep', payload: { index, valid, fields, crossroads, formOptions } }
189+
)
190+
).toEqual({ activeStep: 'step2', activeStepIndex: 1, isDynamic: false, prevSteps: ['step1', 'step2', 'step3'] });
191+
});
192+
193+
it('dynamic step', () => {
194+
crossroads = undefined;
195+
index = 2;
196+
expect(
197+
reducer(
198+
{ activeStepIndex: 4, maxStepIndex: 4, isDynamic: true, prevSteps: ['step1', 'step2', 'step3'], activeStep: 'step4' },
199+
{ type: 'jumpToStep', payload: { index, valid, fields, crossroads, formOptions } }
200+
)
201+
).toEqual({
202+
activeStep: 'step3',
203+
activeStepIndex: 2,
204+
isDynamic: true,
205+
maxStepIndex: 2,
206+
navSchema: [
207+
{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' },
208+
{ index: 1, name: 'step2', primary: true, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
209+
{ index: 2, name: 'step3', primary: false, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
210+
{ index: 3, name: 'step4', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined },
211+
{ index: 4, name: 'step5', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined }
212+
],
213+
prevSteps: ['step1', 'step2']
214+
});
215+
});
216+
217+
it('disable forward jumping', () => {
218+
index = 2;
219+
fields[index].disableForwardJumping = true;
220+
221+
expect(
222+
reducer(
223+
{ activeStepIndex: 4, maxStepIndex: 4, isDynamic: false, prevSteps: ['step1', 'step2', 'step3'], activeStep: 'step4' },
224+
{ type: 'jumpToStep', payload: { index, valid, fields, crossroads, formOptions } }
225+
)
226+
).toEqual({ activeStep: 'step3', activeStepIndex: 2, isDynamic: false, maxStepIndex: 2, prevSteps: ['step1', 'step2'] });
227+
});
228+
229+
it('invalid step', () => {
230+
valid = false;
231+
expect(
232+
reducer(
233+
{ activeStepIndex: 2, isDynamic: false, prevSteps: ['step1', 'step2'], activeStep: 'step3' },
234+
{ type: 'jumpToStep', payload: { index, valid, fields, crossroads, formOptions } }
235+
)
236+
).toEqual({ activeStep: 'step2', activeStepIndex: 1, isDynamic: false, maxStepIndex: 2, prevSteps: ['step1', 'step2', 'step3'] });
237+
});
238+
});
239+
240+
describe('setPrevSteps', () => {
241+
it('regenerate navSchema', () => {
242+
const formOptions = { getState };
243+
244+
expect(
245+
reducer(
246+
{ maxStepIndex: 2, activeStepIndex: 1, prevSteps: ['step1', 'step2', 'step3'] },
247+
{ type: 'setPrevSteps', payload: { formOptions, fields } }
248+
)
249+
).toEqual({
250+
activeStepIndex: 1,
251+
maxStepIndex: 1,
252+
navSchema: [
253+
{ index: 0, name: 'step1', primary: true, substepOf: undefined, substepOfTitle: undefined, title: 'step1' },
254+
{ index: 1, name: 'step2', primary: true, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
255+
{ index: 2, name: 'step3', primary: false, substepOf: 'eaa', substepOfTitle: 'title', title: undefined },
256+
{ index: 3, name: 'step4', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined },
257+
{ index: 4, name: 'step5', primary: true, substepOf: undefined, substepOfTitle: undefined, title: undefined }
258+
],
259+
prevSteps: ['step1']
260+
});
261+
});
262+
});
263+
264+
describe('default', () => {
265+
it('does nothing', () => {
266+
expect(reducer({ state: '123' }, { type: 'nonsense' })).toEqual({ state: '123' });
267+
});
268+
});
269+
});

0 commit comments

Comments
 (0)