Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

Commit 8b1f2b2

Browse files
committed
Adding validateErrorsFields() + unit tests
1 parent 54ca747 commit 8b1f2b2

File tree

2 files changed

+121
-3
lines changed

2 files changed

+121
-3
lines changed

src/actions/field-actions.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import _get from 'lodash/get';
22
import mapValues from 'lodash/mapValues';
33

44
import actionTypes from '../action-types';
5-
import { getValidity, getForm, isValid } from '../utils';
5+
import { getValidity, getForm, isValid, isInvalid } from '../utils';
66

77
const focus = model => ({
88
type: actionTypes.FOCUS,
@@ -159,17 +159,30 @@ const validateFields = (model, fieldValidators, options = {}) => (dispatch, getS
159159
if (validCB || invalidCB) {
160160
const form = getForm(getState(), model);
161161
const formValid = form ? form.valid : true;
162+
const fieldsValid = options.errors
163+
? !isInvalid(fieldsValidity)
164+
: isValid(fieldsValidity);
162165

163-
if (validCB && formValid && isValid(fieldsValidity)) {
166+
if (validCB && formValid && fieldsValid) {
164167
validCB();
165168
} else if (invalidCB) {
166169
invalidCB();
167170
}
168171
}
169172

170-
dispatch(setFieldsValidity(model, fieldsValidity));
173+
const fieldsValiditySetter = options.errors
174+
? setFieldsErrors
175+
: setFieldsValidity;
176+
177+
dispatch(fieldsValiditySetter(model, fieldsValidity));
171178
};
172179

180+
const validateErrorsFields = (model, fieldErrorsValidators, options = {}) =>
181+
validateFields(model, fieldErrorsValidators, {
182+
...options,
183+
errors: true,
184+
});
185+
173186
export default {
174187
asyncSetValidity,
175188
blur,
@@ -193,4 +206,5 @@ export default {
193206
validate,
194207
validateErrors,
195208
validateFields,
209+
validateErrorsFields,
196210
};

test/field-actions-spec.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,4 +1380,108 @@ describe('field actions', () => {
13801380
store.dispatch(action);
13811381
});
13821382
});
1383+
1384+
describe('validateErrorsFields() (thunk)', () => {
1385+
const mockStore = configureMockStore([thunk]);
1386+
1387+
it('should set the errors of multiple fields in the same form', (done) => {
1388+
const store = mockStore(
1389+
() => ({ test: { foo: 'invalid' } }),
1390+
[
1391+
{
1392+
fieldsValidity: {
1393+
'': 'form is invalid',
1394+
foo: 'foo is invalid',
1395+
foo_invalid: 'foo_invalid is invalid',
1396+
foo_valid: false,
1397+
with_keys: {
1398+
key_invalid: 'key_invalid is invalid',
1399+
key_valid: false,
1400+
},
1401+
},
1402+
model: 'test',
1403+
type: actionTypes.SET_FIELDS_VALIDITY,
1404+
options: {
1405+
errors: true,
1406+
},
1407+
},
1408+
],
1409+
done);
1410+
1411+
const action = actions.validateErrorsFields('test', {
1412+
'': (val) => val.foo === 'invalid' && 'form is invalid',
1413+
foo: (val) => val === 'invalid' && 'foo is invalid',
1414+
foo_valid: () => false,
1415+
foo_invalid: () => 'foo_invalid is invalid',
1416+
with_keys: {
1417+
key_valid: () => false,
1418+
key_invalid: () => 'key_invalid is invalid',
1419+
},
1420+
});
1421+
1422+
store.dispatch(action);
1423+
});
1424+
1425+
it('should call a callback if validation passes', (done) => {
1426+
const callback = sinon.spy((val) => val);
1427+
1428+
const validationOptions = {
1429+
onValid: callback,
1430+
};
1431+
1432+
const store = mockStore(
1433+
() => ({ test: { foo: 'valid' } }),
1434+
[{
1435+
model: 'test',
1436+
type: actionTypes.SET_FIELDS_VALIDITY,
1437+
fieldsValidity: {
1438+
foo: false, // false = not an error
1439+
},
1440+
options: {
1441+
errors: true,
1442+
},
1443+
}],
1444+
() => {
1445+
assert.isTrue(callback.calledOnce);
1446+
done();
1447+
});
1448+
1449+
const action = actions.validateErrorsFields('test', {
1450+
foo: (val) => val === 'invalid',
1451+
}, validationOptions);
1452+
1453+
store.dispatch(action);
1454+
});
1455+
1456+
it('should NOT call a callback if validation fails', (done) => {
1457+
const callback = sinon.spy((val) => val);
1458+
1459+
const validationOptions = {
1460+
onValid: callback,
1461+
};
1462+
1463+
const store = mockStore(
1464+
() => ({ test: { foo: 'invalid' } }),
1465+
[{
1466+
model: 'test',
1467+
type: actionTypes.SET_FIELDS_VALIDITY,
1468+
fieldsValidity: {
1469+
foo: true, // true = error
1470+
},
1471+
options: {
1472+
errors: true,
1473+
},
1474+
}],
1475+
() => {
1476+
assert.isTrue(callback.notCalled);
1477+
done();
1478+
});
1479+
1480+
const action = actions.validateErrorsFields('test', {
1481+
foo: (val) => val === 'invalid',
1482+
}, validationOptions);
1483+
1484+
store.dispatch(action);
1485+
});
1486+
});
13831487
});

0 commit comments

Comments
 (0)