@ukhomeoffice/cop-react-form-renderer 3.7.0-alpha → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/models/ComponentTypes.js +2 -0
- package/dist/utils/Component/getComponent.js +13 -0
- package/dist/utils/Component/getComponentTests/getComponent.calculation.test.js +269 -0
- package/dist/utils/Component/isEditable.js +1 -1
- package/dist/utils/Condition/meetsCondition.js +5 -0
- package/dist/utils/Condition/meetsCondition.test.js +89 -0
- package/dist/utils/Data/applyFormula.js +121 -0
- package/dist/utils/Data/applyFormula.test.js +264 -0
- package/dist/utils/Data/index.js +3 -0
- package/dist/utils/Data/setupFormData.js +59 -2
- package/dist/utils/Data/setupFormData.test.js +60 -0
- package/package.json +2 -2
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var TYPE_AUTOCOMPLETE = 'autocomplete';
|
|
8
|
+
var TYPE_CALCULATION = 'calculation';
|
|
8
9
|
var TYPE_CHECKBOXES = 'checkboxes';
|
|
9
10
|
var TYPE_COLLECTION = 'collection';
|
|
10
11
|
var TYPE_CONTAINER = 'container';
|
|
@@ -24,6 +25,7 @@ var TYPE_TIME = 'time';
|
|
|
24
25
|
var TYPE_WARNING = 'warning';
|
|
25
26
|
var ComponentTypes = {
|
|
26
27
|
AUTOCOMPLETE: TYPE_AUTOCOMPLETE,
|
|
28
|
+
CALCULATION: TYPE_CALCULATION,
|
|
27
29
|
CHECKBOXES: TYPE_CHECKBOXES,
|
|
28
30
|
COLLECTION: TYPE_COLLECTION,
|
|
29
31
|
CONTAINER: TYPE_CONTAINER,
|
|
@@ -54,6 +54,16 @@ var getCheckboxes = function getCheckboxes(config) {
|
|
|
54
54
|
}));
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
+
var getCalculation = function getCalculation(config) {
|
|
58
|
+
var calculatedValue = _Data.default.applyFormula(config);
|
|
59
|
+
|
|
60
|
+
var attrs = (0, _cleanAttributes.default)(config, ['formula']);
|
|
61
|
+
return /*#__PURE__*/_react.default.createElement(_copReactComponents.TextInput, _extends({}, attrs, {
|
|
62
|
+
value: calculatedValue,
|
|
63
|
+
readOnly: true
|
|
64
|
+
}));
|
|
65
|
+
};
|
|
66
|
+
|
|
57
67
|
var getDate = function getDate(config) {
|
|
58
68
|
var attrs = (0, _cleanAttributes.default)(config);
|
|
59
69
|
return /*#__PURE__*/_react.default.createElement(_copReactComponents.DateInput, attrs);
|
|
@@ -184,6 +194,9 @@ var getComponentByType = function getComponentByType(config) {
|
|
|
184
194
|
case _models.ComponentTypes.DETAILS:
|
|
185
195
|
return getDetails(config);
|
|
186
196
|
|
|
197
|
+
case _models.ComponentTypes.CALCULATION:
|
|
198
|
+
return getCalculation(config);
|
|
199
|
+
|
|
187
200
|
default:
|
|
188
201
|
{
|
|
189
202
|
return null;
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = require("@testing-library/react");
|
|
4
|
+
|
|
5
|
+
var _models = require("../../../models");
|
|
6
|
+
|
|
7
|
+
var _getComponent = _interopRequireDefault(require("../getComponent"));
|
|
8
|
+
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
|
|
11
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
12
|
+
|
|
13
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
14
|
+
|
|
15
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
16
|
+
|
|
17
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
18
|
+
|
|
19
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
20
|
+
|
|
21
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
22
|
+
|
|
23
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
24
|
+
|
|
25
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
26
|
+
|
|
27
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
28
|
+
|
|
29
|
+
describe('utils.Component.get', function () {
|
|
30
|
+
var ID = 'test-id';
|
|
31
|
+
var FIELD_ID = 'field-id';
|
|
32
|
+
var LABEL = 'label';
|
|
33
|
+
var COMPONENT = {
|
|
34
|
+
type: _models.ComponentTypes.CALCULATION,
|
|
35
|
+
id: ID,
|
|
36
|
+
fieldId: FIELD_ID,
|
|
37
|
+
label: LABEL,
|
|
38
|
+
formData: {
|
|
39
|
+
totalPerson: '4',
|
|
40
|
+
personProcessed: '3'
|
|
41
|
+
},
|
|
42
|
+
'data-testid': ID
|
|
43
|
+
};
|
|
44
|
+
var error = jest.spyOn(console, 'error').mockImplementation(function () {});
|
|
45
|
+
afterAll(function () {
|
|
46
|
+
error.mockReset();
|
|
47
|
+
});
|
|
48
|
+
afterEach(function () {
|
|
49
|
+
error.mockClear();
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* Iteratively test collction of positive test data objects each containing:
|
|
53
|
+
* config: object containing formula config
|
|
54
|
+
* result: the calculated formula(s) output value.
|
|
55
|
+
*
|
|
56
|
+
* Test record structure:
|
|
57
|
+
* ----------------------
|
|
58
|
+
* {
|
|
59
|
+
* config: {
|
|
60
|
+
* formula: { ... }
|
|
61
|
+
* },
|
|
62
|
+
* result: ''
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
[{
|
|
68
|
+
config: {
|
|
69
|
+
formula: {
|
|
70
|
+
name: 'minus',
|
|
71
|
+
args: [{
|
|
72
|
+
field: 'totalPerson'
|
|
73
|
+
}, {
|
|
74
|
+
field: 'personProcessed'
|
|
75
|
+
}]
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
result: '1'
|
|
79
|
+
}, {
|
|
80
|
+
config: {
|
|
81
|
+
formula: {
|
|
82
|
+
name: 'plus',
|
|
83
|
+
args: [{
|
|
84
|
+
field: 'totalPerson'
|
|
85
|
+
}, {
|
|
86
|
+
field: 'personProcessed'
|
|
87
|
+
}]
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
result: '7'
|
|
91
|
+
}, {
|
|
92
|
+
config: {
|
|
93
|
+
formula: {
|
|
94
|
+
name: 'multiply',
|
|
95
|
+
args: [{
|
|
96
|
+
field: 'totalPerson'
|
|
97
|
+
}, {
|
|
98
|
+
field: 'personProcessed'
|
|
99
|
+
}]
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
result: '12'
|
|
103
|
+
}, {
|
|
104
|
+
config: {
|
|
105
|
+
formula: {
|
|
106
|
+
name: 'divide',
|
|
107
|
+
round: 2,
|
|
108
|
+
args: [{
|
|
109
|
+
field: 'totalPerson'
|
|
110
|
+
}, {
|
|
111
|
+
field: 'personProcessed'
|
|
112
|
+
}]
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
result: '1.33'
|
|
116
|
+
}, {
|
|
117
|
+
config: {
|
|
118
|
+
formula: {
|
|
119
|
+
name: 'multiply',
|
|
120
|
+
round: 2,
|
|
121
|
+
args: [{
|
|
122
|
+
formula: {
|
|
123
|
+
name: 'divide',
|
|
124
|
+
args: [{
|
|
125
|
+
field: 'totalPerson'
|
|
126
|
+
}, {
|
|
127
|
+
field: 'personProcessed'
|
|
128
|
+
}]
|
|
129
|
+
}
|
|
130
|
+
}, {
|
|
131
|
+
value: 200
|
|
132
|
+
}]
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
result: '266.67'
|
|
136
|
+
}].forEach(function (test) {
|
|
137
|
+
it("should render 'calculation' component with formula to given calculated value: ".concat(test.result), function () {
|
|
138
|
+
var _render = (0, _react.render)((0, _getComponent.default)(_objectSpread(_objectSpread({}, COMPONENT), test.config))),
|
|
139
|
+
container = _render.container;
|
|
140
|
+
|
|
141
|
+
var _getAllByTestId = (0, _react.getAllByTestId)(container, ID),
|
|
142
|
+
_getAllByTestId2 = _slicedToArray(_getAllByTestId, 2),
|
|
143
|
+
formGroup = _getAllByTestId2[0],
|
|
144
|
+
input = _getAllByTestId2[1];
|
|
145
|
+
|
|
146
|
+
expect(formGroup.tagName).toEqual('DIV');
|
|
147
|
+
expect(formGroup.classList).toContain('govuk-form-group');
|
|
148
|
+
var label = formGroup.childNodes[0];
|
|
149
|
+
expect(label.tagName).toEqual('LABEL');
|
|
150
|
+
expect(label.classList).toContain('govuk-label');
|
|
151
|
+
expect(label.textContent).toContain(LABEL);
|
|
152
|
+
expect(formGroup.classList).toContain('govuk-form-group');
|
|
153
|
+
expect(input.tagName).toEqual('INPUT');
|
|
154
|
+
expect(input.classList).toContain('govuk-input');
|
|
155
|
+
expect(input.id).toEqual(ID);
|
|
156
|
+
expect(input.getAttribute('readonly')).not.toBeNull();
|
|
157
|
+
expect(input.getAttribute('value')).toEqual(test.result);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
/**
|
|
161
|
+
* Iteratively test collction of negative test data objects each containing:
|
|
162
|
+
* config: object containing invalid formula config
|
|
163
|
+
* result: the error to match.
|
|
164
|
+
*
|
|
165
|
+
* Test record structure:
|
|
166
|
+
* ----------------------
|
|
167
|
+
* {
|
|
168
|
+
* config: {
|
|
169
|
+
* formula: { ... }
|
|
170
|
+
* },
|
|
171
|
+
* error: 'error_message'
|
|
172
|
+
* }
|
|
173
|
+
*
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
[{
|
|
177
|
+
error: "Missing 'formula' definition"
|
|
178
|
+
}, {
|
|
179
|
+
config: {
|
|
180
|
+
formula: {}
|
|
181
|
+
},
|
|
182
|
+
error: "Calculation formula 'name' cannot be empty"
|
|
183
|
+
}, {
|
|
184
|
+
config: {
|
|
185
|
+
formula: {
|
|
186
|
+
name: 'tictactoe',
|
|
187
|
+
args: [{
|
|
188
|
+
field: 'totalPerson'
|
|
189
|
+
}, {
|
|
190
|
+
field: 'personProcessed'
|
|
191
|
+
}]
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
error: "Unsupported operation 'tictactoe'"
|
|
195
|
+
}, {
|
|
196
|
+
config: {
|
|
197
|
+
formula: {
|
|
198
|
+
name: 'minus',
|
|
199
|
+
args: [{
|
|
200
|
+
field: 'totalPerson',
|
|
201
|
+
value: 100
|
|
202
|
+
}, {
|
|
203
|
+
field: 'personProcessed'
|
|
204
|
+
}]
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
error: 'Argument cannot have more than one reference'
|
|
208
|
+
}, {
|
|
209
|
+
config: {
|
|
210
|
+
formula: {
|
|
211
|
+
name: 'minus',
|
|
212
|
+
args: [{
|
|
213
|
+
newToken: 'totalPerson'
|
|
214
|
+
}, {
|
|
215
|
+
field: 'personProcessed'
|
|
216
|
+
}]
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
error: 'Only accept following as argument field: {field, value, or formula}'
|
|
220
|
+
}, {
|
|
221
|
+
config: {
|
|
222
|
+
formula: {
|
|
223
|
+
name: 'minus',
|
|
224
|
+
args: [{
|
|
225
|
+
field: 'totalPerson'
|
|
226
|
+
}]
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
error: 'Requires more than one argument for calculation'
|
|
230
|
+
}, {
|
|
231
|
+
config: {
|
|
232
|
+
formula: {
|
|
233
|
+
name: 'multiply',
|
|
234
|
+
round: 2,
|
|
235
|
+
args: [{
|
|
236
|
+
value: 200,
|
|
237
|
+
field: 'totalPerson'
|
|
238
|
+
}, {
|
|
239
|
+
value: 200
|
|
240
|
+
}]
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
error: 'Argument cannot have more than one reference'
|
|
244
|
+
}].forEach(function (test) {
|
|
245
|
+
it("should return an appropriately rendered calculation component with message ".concat(test.result), function () {
|
|
246
|
+
var _render2 = (0, _react.render)((0, _getComponent.default)(_objectSpread(_objectSpread({}, COMPONENT), test.config))),
|
|
247
|
+
container = _render2.container;
|
|
248
|
+
|
|
249
|
+
var _getAllByTestId3 = (0, _react.getAllByTestId)(container, ID),
|
|
250
|
+
_getAllByTestId4 = _slicedToArray(_getAllByTestId3, 2),
|
|
251
|
+
formGroup = _getAllByTestId4[0],
|
|
252
|
+
input = _getAllByTestId4[1];
|
|
253
|
+
|
|
254
|
+
expect(formGroup.tagName).toEqual('DIV');
|
|
255
|
+
expect(formGroup.classList).toContain('govuk-form-group');
|
|
256
|
+
var label = formGroup.childNodes[0];
|
|
257
|
+
expect(label.tagName).toEqual('LABEL');
|
|
258
|
+
expect(label.classList).toContain('govuk-label');
|
|
259
|
+
expect(label.textContent).toContain(LABEL);
|
|
260
|
+
expect(formGroup.classList).toContain('govuk-form-group');
|
|
261
|
+
expect(input.tagName).toEqual('INPUT');
|
|
262
|
+
expect(input.classList).toContain('govuk-input');
|
|
263
|
+
expect(input.id).toEqual(ID);
|
|
264
|
+
expect(input.getAttribute('readonly')).not.toBeNull();
|
|
265
|
+
expect(error).toBeCalledTimes(1);
|
|
266
|
+
expect(error).toBeCalledWith(test.error);
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
});
|
|
@@ -8,7 +8,7 @@ exports.default = exports.EDITABLE_TYPES = void 0;
|
|
|
8
8
|
var _models = require("../../models");
|
|
9
9
|
|
|
10
10
|
// Local imports
|
|
11
|
-
var EDITABLE_TYPES = [_models.ComponentTypes.AUTOCOMPLETE, _models.ComponentTypes.CHECKBOXES, _models.ComponentTypes.DATE, _models.ComponentTypes.EMAIL, _models.ComponentTypes.FILE, _models.ComponentTypes.PHONE_NUMBER, _models.ComponentTypes.RADIOS, _models.ComponentTypes.SELECT, _models.ComponentTypes.TEXT, _models.ComponentTypes.TEXT_AREA, _models.ComponentTypes.TIME];
|
|
11
|
+
var EDITABLE_TYPES = [_models.ComponentTypes.AUTOCOMPLETE, _models.ComponentTypes.CALCULATION, _models.ComponentTypes.CHECKBOXES, _models.ComponentTypes.DATE, _models.ComponentTypes.EMAIL, _models.ComponentTypes.FILE, _models.ComponentTypes.PHONE_NUMBER, _models.ComponentTypes.RADIOS, _models.ComponentTypes.SELECT, _models.ComponentTypes.TEXT, _models.ComponentTypes.TEXT_AREA, _models.ComponentTypes.TIME];
|
|
12
12
|
exports.EDITABLE_TYPES = EDITABLE_TYPES;
|
|
13
13
|
|
|
14
14
|
var isEditable = function isEditable(options) {
|
|
@@ -67,6 +67,11 @@ var meetsCondition = function meetsCondition(condition, value) {
|
|
|
67
67
|
return true;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
case 'contains':
|
|
71
|
+
{
|
|
72
|
+
return value === null || value === void 0 ? void 0 : value.toString().toLowerCase().includes(compare); // If no value is provided, the field cannot contain it, so it must fail the condition.
|
|
73
|
+
}
|
|
74
|
+
|
|
70
75
|
default:
|
|
71
76
|
return false;
|
|
72
77
|
}
|
|
@@ -261,6 +261,95 @@ describe('utils.Condition.meetsCondition', function () {
|
|
|
261
261
|
});
|
|
262
262
|
});
|
|
263
263
|
});
|
|
264
|
+
describe('operator contains', function () {
|
|
265
|
+
var op = 'contains'; // Should match...
|
|
266
|
+
|
|
267
|
+
it('should match a string that is in the field array', function () {
|
|
268
|
+
var FIELD = ['alpha', 'bravo', 'charlie'];
|
|
269
|
+
var VALUE = 'alpha';
|
|
270
|
+
var CONDITION = getCondition(op, VALUE);
|
|
271
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeTruthy();
|
|
272
|
+
});
|
|
273
|
+
it('should match a sub-string that is in the field array', function () {
|
|
274
|
+
var FIELD = ['alpha', 'bravo', 'charlie'];
|
|
275
|
+
var VALUE = 'alp';
|
|
276
|
+
var CONDITION = getCondition(op, VALUE);
|
|
277
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeTruthy();
|
|
278
|
+
});
|
|
279
|
+
it('should match a number that is in the field array', function () {
|
|
280
|
+
var FIELD = [1, 2, 3];
|
|
281
|
+
var VALUE = 1;
|
|
282
|
+
var CONDITION = getCondition(op, VALUE);
|
|
283
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeTruthy();
|
|
284
|
+
});
|
|
285
|
+
it('should match a sub-string that is in the field string', function () {
|
|
286
|
+
var FIELD = 'alphabravocharlie';
|
|
287
|
+
var VALUE = 'alpha';
|
|
288
|
+
var CONDITION = getCondition(op, VALUE);
|
|
289
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeTruthy();
|
|
290
|
+
});
|
|
291
|
+
it('should match a string that is in the field array regardless of case', function () {
|
|
292
|
+
var FIELD = ['Alpha', 'bravo', 'charlie'];
|
|
293
|
+
var VALUE = 'alpha';
|
|
294
|
+
var CONDITION = getCondition(op, VALUE);
|
|
295
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeTruthy();
|
|
296
|
+
}); // Should reject...
|
|
297
|
+
|
|
298
|
+
it('should reject a string that is missing from the field array', function () {
|
|
299
|
+
var FIELD = ['alpha', 'bravo', 'charlie'];
|
|
300
|
+
var VALUE = 'delta';
|
|
301
|
+
var CONDITION = getCondition(op, VALUE);
|
|
302
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeFalsy();
|
|
303
|
+
});
|
|
304
|
+
it('should reject a number that is missing from the field array', function () {
|
|
305
|
+
var FIELD = [1, 2, 3];
|
|
306
|
+
var VALUE = 4;
|
|
307
|
+
var CONDITION = getCondition(op, VALUE);
|
|
308
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeFalsy();
|
|
309
|
+
});
|
|
310
|
+
it('should reject a substring that is missing from the field string', function () {
|
|
311
|
+
var FIELD = 'alphabravocharlie';
|
|
312
|
+
var VALUE = 'delta';
|
|
313
|
+
var CONDITION = getCondition(op, VALUE);
|
|
314
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeFalsy();
|
|
315
|
+
});
|
|
316
|
+
it('should reject any value when the field is an empty Array', function () {
|
|
317
|
+
var FIELD = [];
|
|
318
|
+
var VALUE = 'alpha';
|
|
319
|
+
var CONDITION = getCondition(op, VALUE);
|
|
320
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeFalsy();
|
|
321
|
+
});
|
|
322
|
+
it('should reject any value when the field is an empty string', function () {
|
|
323
|
+
var FIELD = '';
|
|
324
|
+
var VALUE = 'alpha';
|
|
325
|
+
var CONDITION = getCondition(op, VALUE);
|
|
326
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeFalsy();
|
|
327
|
+
});
|
|
328
|
+
it('should reject any field when the value is null', function () {
|
|
329
|
+
var FIELD = ['alpha', 'bravo', 'charlie'];
|
|
330
|
+
var VALUE = null;
|
|
331
|
+
var CONDITION = getCondition(op, VALUE);
|
|
332
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeFalsy();
|
|
333
|
+
});
|
|
334
|
+
it('should reject any field when the value is undefined', function () {
|
|
335
|
+
var FIELD = ['alpha', 'bravo', 'charlie'];
|
|
336
|
+
var VALUE = undefined;
|
|
337
|
+
var CONDITION = getCondition(op, VALUE);
|
|
338
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeFalsy();
|
|
339
|
+
});
|
|
340
|
+
it('should reject any value when the field is null', function () {
|
|
341
|
+
var FIELD = null;
|
|
342
|
+
var VALUE = 'alpha';
|
|
343
|
+
var CONDITION = getCondition(op, VALUE);
|
|
344
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeFalsy();
|
|
345
|
+
});
|
|
346
|
+
it('should reject any value when the field is undefined', function () {
|
|
347
|
+
var FIELD = undefined;
|
|
348
|
+
var VALUE = 'alpha';
|
|
349
|
+
var CONDITION = getCondition(op, VALUE);
|
|
350
|
+
expect((0, _meetsCondition.default)(CONDITION, FIELD)).toBeFalsy();
|
|
351
|
+
});
|
|
352
|
+
});
|
|
264
353
|
describe('unknown operator', function () {
|
|
265
354
|
var op = 'definitely_not_a_real_operator';
|
|
266
355
|
it('should reject anything regardless of the value', function () {
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _copReactComponents = require("@ukhomeoffice/cop-react-components");
|
|
9
|
+
|
|
10
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
11
|
+
|
|
12
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
13
|
+
|
|
14
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
15
|
+
|
|
16
|
+
var applyFormula = function applyFormula(config) {
|
|
17
|
+
try {
|
|
18
|
+
var result = simplify(config);
|
|
19
|
+
return !result && result !== 0 ? '' : result;
|
|
20
|
+
} catch (err) {
|
|
21
|
+
console.error(err.message);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return '';
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
var simplify = function simplify(config) {
|
|
28
|
+
if (!config || !config.formula) {
|
|
29
|
+
throw new Error("Missing 'formula' definition");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
var _config$formula = _objectSpread({}, config.formula),
|
|
33
|
+
name = _config$formula.name;
|
|
34
|
+
|
|
35
|
+
switch (name) {
|
|
36
|
+
case 'multiply':
|
|
37
|
+
return reduceNumber(config, function (t, c) {
|
|
38
|
+
return t * c;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
case 'divide':
|
|
42
|
+
return reduceNumber(config, function (t, c) {
|
|
43
|
+
return t / c;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
case 'plus':
|
|
47
|
+
return reduceNumber(config, function (t, c) {
|
|
48
|
+
return t + c;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
case 'minus':
|
|
52
|
+
return reduceNumber(config, function (t, c) {
|
|
53
|
+
return t - c;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
default:
|
|
57
|
+
throw new Error(!name ? "Calculation formula 'name' cannot be empty" : "Unsupported operation '".concat(name, "'"));
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
var reduceNumber = function reduceNumber(config, reduction) {
|
|
62
|
+
var _config$formula2 = _objectSpread({}, config.formula),
|
|
63
|
+
args = _config$formula2.args;
|
|
64
|
+
|
|
65
|
+
if (args.length < 2) {
|
|
66
|
+
throw new Error('Requires more than one argument for calculation');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return round(args.map(function (a) {
|
|
70
|
+
return getValue(a, config.formData);
|
|
71
|
+
}).reduce(function (total, current, index) {
|
|
72
|
+
return index === 0 ? current : reduction(total, current);
|
|
73
|
+
}, 0), config);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
var round = function round(number, config) {
|
|
77
|
+
var round = config.formula.round;
|
|
78
|
+
if (!round && round !== 0 || !number) return number;
|
|
79
|
+
|
|
80
|
+
if (round === 0) {
|
|
81
|
+
return parseInt(number);
|
|
82
|
+
} else {
|
|
83
|
+
var precisionScale = Math.pow(10, round);
|
|
84
|
+
return Math.round((number + Number.EPSILON) * precisionScale) / precisionScale;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
var getValue = function getValue(arg, formData) {
|
|
89
|
+
var keys = Object.keys(arg);
|
|
90
|
+
|
|
91
|
+
if (keys.length === 1) {
|
|
92
|
+
var key = keys[0];
|
|
93
|
+
var val = arg[key];
|
|
94
|
+
|
|
95
|
+
switch (key) {
|
|
96
|
+
case 'field':
|
|
97
|
+
var fieldVal = fieldValue(val, formData);
|
|
98
|
+
return !fieldVal && fieldVal !== 0 ? NaN : parseFloat(fieldVal);
|
|
99
|
+
|
|
100
|
+
case 'value':
|
|
101
|
+
return parseFloat(val);
|
|
102
|
+
|
|
103
|
+
case 'formula':
|
|
104
|
+
return applyFormula(_objectSpread(_objectSpread({}, arg), {}, {
|
|
105
|
+
formData: formData
|
|
106
|
+
}));
|
|
107
|
+
|
|
108
|
+
default:
|
|
109
|
+
throw new Error('Only accept following as argument field: {field, value, or formula}');
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
throw new Error('Argument cannot have more than one reference');
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
var fieldValue = function fieldValue(field, data) {
|
|
117
|
+
return _copReactComponents.Utils.interpolateString('${' + field + '}', data);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
var _default = applyFormula;
|
|
121
|
+
exports.default = _default;
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _applyFormula = _interopRequireDefault(require("./applyFormula"));
|
|
4
|
+
|
|
5
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
6
|
+
|
|
7
|
+
// Local imports
|
|
8
|
+
describe('utils.Data.applyFormula', function () {
|
|
9
|
+
var error = jest.spyOn(console, 'error').mockImplementation(function () {});
|
|
10
|
+
afterAll(function () {
|
|
11
|
+
error.mockReset();
|
|
12
|
+
});
|
|
13
|
+
afterEach(function () {
|
|
14
|
+
error.mockClear();
|
|
15
|
+
});
|
|
16
|
+
it('should throw and handle exception for a null config', function () {
|
|
17
|
+
(0, _applyFormula.default)(null);
|
|
18
|
+
expect(error).toBeCalledWith("Missing 'formula' definition");
|
|
19
|
+
});
|
|
20
|
+
it("should throw and handle exception for config with missing 'formula'", function () {
|
|
21
|
+
(0, _applyFormula.default)({});
|
|
22
|
+
expect(error).toBeCalledWith("Missing 'formula' definition");
|
|
23
|
+
});
|
|
24
|
+
it("should throw and handle exception for config with 'formula' but missing 'name'", function () {
|
|
25
|
+
(0, _applyFormula.default)({
|
|
26
|
+
formula: {}
|
|
27
|
+
});
|
|
28
|
+
expect(error).toBeCalledWith("Calculation formula 'name' cannot be empty");
|
|
29
|
+
});
|
|
30
|
+
it("should throw and handle exception for config with 'formula' with unsupported operation 'name'", function () {
|
|
31
|
+
(0, _applyFormula.default)({
|
|
32
|
+
formula: {
|
|
33
|
+
name: "something"
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
expect(error).toBeCalledWith("Unsupported operation 'something'");
|
|
37
|
+
});
|
|
38
|
+
it("should throw and handle exception for 'formula' with wrong argument name", function () {
|
|
39
|
+
(0, _applyFormula.default)({
|
|
40
|
+
formula: {
|
|
41
|
+
name: 'plus',
|
|
42
|
+
args: [{
|
|
43
|
+
somthing: 1
|
|
44
|
+
}, {
|
|
45
|
+
somthing: 1
|
|
46
|
+
}]
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
expect(error).toBeCalledWith('Only accept following as argument field: {field, value, or formula}');
|
|
50
|
+
});
|
|
51
|
+
it("should throw and handle exception for 'formula' argument with more than one field", function () {
|
|
52
|
+
(0, _applyFormula.default)({
|
|
53
|
+
formula: {
|
|
54
|
+
name: 'plus',
|
|
55
|
+
args: [{
|
|
56
|
+
value: 1,
|
|
57
|
+
field: 'fieldA'
|
|
58
|
+
}, {
|
|
59
|
+
value: 1
|
|
60
|
+
}]
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
expect(error).toBeCalledWith('Argument cannot have more than one reference');
|
|
64
|
+
});
|
|
65
|
+
it("should throw and handle exception for 'formula' with single argument", function () {
|
|
66
|
+
(0, _applyFormula.default)({
|
|
67
|
+
formula: {
|
|
68
|
+
name: 'plus',
|
|
69
|
+
args: [{
|
|
70
|
+
value: 10
|
|
71
|
+
}]
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
expect(error).toBeCalledWith('Requires more than one argument for calculation');
|
|
75
|
+
});
|
|
76
|
+
var DATA = {
|
|
77
|
+
fieldA: '10',
|
|
78
|
+
fieldB: '20',
|
|
79
|
+
fieldC: 'abc',
|
|
80
|
+
fieldD: '0',
|
|
81
|
+
fieldE: '10'
|
|
82
|
+
};
|
|
83
|
+
[{
|
|
84
|
+
name: 'plus',
|
|
85
|
+
args: [{
|
|
86
|
+
field: 'fieldA'
|
|
87
|
+
}, {
|
|
88
|
+
field: 'fieldB'
|
|
89
|
+
}],
|
|
90
|
+
result: 30
|
|
91
|
+
}, {
|
|
92
|
+
name: 'minus',
|
|
93
|
+
args: [{
|
|
94
|
+
field: 'fieldB'
|
|
95
|
+
}, {
|
|
96
|
+
field: 'fieldA'
|
|
97
|
+
}],
|
|
98
|
+
result: 10
|
|
99
|
+
}, {
|
|
100
|
+
name: 'multiply',
|
|
101
|
+
args: [{
|
|
102
|
+
field: 'fieldA'
|
|
103
|
+
}, {
|
|
104
|
+
field: 'fieldB'
|
|
105
|
+
}],
|
|
106
|
+
result: 200
|
|
107
|
+
}, {
|
|
108
|
+
name: 'divide',
|
|
109
|
+
args: [{
|
|
110
|
+
field: 'fieldA'
|
|
111
|
+
}, {
|
|
112
|
+
field: 'fieldB'
|
|
113
|
+
}],
|
|
114
|
+
result: 0.5
|
|
115
|
+
}, {
|
|
116
|
+
name: 'divide',
|
|
117
|
+
args: [{
|
|
118
|
+
field: 'fieldA'
|
|
119
|
+
}, {
|
|
120
|
+
field: 'fieldD'
|
|
121
|
+
}],
|
|
122
|
+
result: Infinity
|
|
123
|
+
}, {
|
|
124
|
+
name: 'plus',
|
|
125
|
+
args: [{
|
|
126
|
+
field: 'fieldA'
|
|
127
|
+
}, {
|
|
128
|
+
field: 'fieldC'
|
|
129
|
+
}],
|
|
130
|
+
result: ''
|
|
131
|
+
}, {
|
|
132
|
+
name: 'multiply',
|
|
133
|
+
args: [{
|
|
134
|
+
field: 'fieldA'
|
|
135
|
+
}, {
|
|
136
|
+
field: 'fieldB'
|
|
137
|
+
}, {
|
|
138
|
+
field: 'fieldE'
|
|
139
|
+
}],
|
|
140
|
+
result: 2000
|
|
141
|
+
}].forEach(function (test) {
|
|
142
|
+
it("should calculate formula '".concat(test.name, "' correctly for field args to '").concat(test.result, "'"), function () {
|
|
143
|
+
var config = {
|
|
144
|
+
formData: DATA,
|
|
145
|
+
formula: {
|
|
146
|
+
name: test.name,
|
|
147
|
+
args: test.args
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
expect((0, _applyFormula.default)(config)).toEqual(test.result);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
[{
|
|
154
|
+
fieldA: '1',
|
|
155
|
+
fieldB: '3',
|
|
156
|
+
round: 5,
|
|
157
|
+
result: 0.33333
|
|
158
|
+
}, {
|
|
159
|
+
fieldA: '2',
|
|
160
|
+
fieldB: '3',
|
|
161
|
+
round: 5,
|
|
162
|
+
result: 0.66667
|
|
163
|
+
}, {
|
|
164
|
+
fieldA: '1',
|
|
165
|
+
fieldB: '3',
|
|
166
|
+
round: 4,
|
|
167
|
+
result: 0.3333
|
|
168
|
+
}, {
|
|
169
|
+
fieldA: '2',
|
|
170
|
+
fieldB: '3',
|
|
171
|
+
round: 4,
|
|
172
|
+
result: 0.6667
|
|
173
|
+
}, {
|
|
174
|
+
fieldA: '1',
|
|
175
|
+
fieldB: '3',
|
|
176
|
+
round: 3,
|
|
177
|
+
result: 0.333
|
|
178
|
+
}, {
|
|
179
|
+
fieldA: '2',
|
|
180
|
+
fieldB: '3',
|
|
181
|
+
round: 3,
|
|
182
|
+
result: 0.667
|
|
183
|
+
}, {
|
|
184
|
+
fieldA: '1',
|
|
185
|
+
fieldB: '3',
|
|
186
|
+
round: 2,
|
|
187
|
+
result: 0.33
|
|
188
|
+
}, {
|
|
189
|
+
fieldA: '2',
|
|
190
|
+
fieldB: '3',
|
|
191
|
+
round: 2,
|
|
192
|
+
result: 0.67
|
|
193
|
+
}, {
|
|
194
|
+
fieldA: '1',
|
|
195
|
+
fieldB: '3',
|
|
196
|
+
round: 1,
|
|
197
|
+
result: 0.3
|
|
198
|
+
}, {
|
|
199
|
+
fieldA: '2',
|
|
200
|
+
fieldB: '3',
|
|
201
|
+
round: 1,
|
|
202
|
+
result: 0.7
|
|
203
|
+
}, {
|
|
204
|
+
fieldA: '1',
|
|
205
|
+
fieldB: '3',
|
|
206
|
+
round: 0,
|
|
207
|
+
result: 0
|
|
208
|
+
}, {
|
|
209
|
+
fieldA: '2',
|
|
210
|
+
fieldB: '3',
|
|
211
|
+
round: 0,
|
|
212
|
+
result: 0
|
|
213
|
+
}, {
|
|
214
|
+
fieldA: 'L',
|
|
215
|
+
fieldB: 'G3',
|
|
216
|
+
round: 1,
|
|
217
|
+
result: ''
|
|
218
|
+
}].forEach(function (test) {
|
|
219
|
+
it("should calculdate and round result to precision ".concat(test.round), function () {
|
|
220
|
+
var config = {
|
|
221
|
+
formData: {
|
|
222
|
+
fieldA: test.fieldA,
|
|
223
|
+
fieldB: test.fieldB
|
|
224
|
+
},
|
|
225
|
+
formula: {
|
|
226
|
+
name: 'divide',
|
|
227
|
+
round: test.round,
|
|
228
|
+
args: [{
|
|
229
|
+
field: 'fieldA'
|
|
230
|
+
}, {
|
|
231
|
+
field: 'fieldB'
|
|
232
|
+
}]
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
expect((0, _applyFormula.default)(config)).toEqual(test.result);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
it("should calculate nested 'formula'", function () {
|
|
239
|
+
var config = {
|
|
240
|
+
formData: {
|
|
241
|
+
fieldA: '19',
|
|
242
|
+
fieldB: '66'
|
|
243
|
+
},
|
|
244
|
+
formula: {
|
|
245
|
+
name: 'multiply',
|
|
246
|
+
round: 2,
|
|
247
|
+
args: [{
|
|
248
|
+
formula: {
|
|
249
|
+
name: 'divide',
|
|
250
|
+
round: 4,
|
|
251
|
+
args: [{
|
|
252
|
+
field: 'fieldA'
|
|
253
|
+
}, {
|
|
254
|
+
field: 'fieldB'
|
|
255
|
+
}]
|
|
256
|
+
}
|
|
257
|
+
}, {
|
|
258
|
+
value: 100
|
|
259
|
+
}]
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
expect((0, _applyFormula.default)(config)).toEqual(28.79);
|
|
263
|
+
});
|
|
264
|
+
});
|
package/dist/utils/Data/index.js
CHANGED
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
+
var _applyFormula = _interopRequireDefault(require("./applyFormula"));
|
|
9
|
+
|
|
8
10
|
var _getAutocompleteSource = _interopRequireDefault(require("./getAutocompleteSource"));
|
|
9
11
|
|
|
10
12
|
var _getDataPath = _interopRequireDefault(require("./getDataPath"));
|
|
@@ -25,6 +27,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
25
27
|
|
|
26
28
|
// Local imports
|
|
27
29
|
var Data = {
|
|
30
|
+
applyFormula: _applyFormula.default,
|
|
28
31
|
getAutocompleteSource: _getAutocompleteSource.default,
|
|
29
32
|
getDataPath: _getDataPath.default,
|
|
30
33
|
getOptions: _getOptions.default,
|
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
+
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
9
|
+
|
|
8
10
|
var _getSourceData = _interopRequireDefault(require("./getSourceData"));
|
|
9
11
|
|
|
10
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -15,6 +17,56 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
15
17
|
|
|
16
18
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
17
19
|
|
|
20
|
+
var setDefaultDateValue = function setDefaultDateValue(date, data) {
|
|
21
|
+
if (date.defaultValue === 'today') {
|
|
22
|
+
data[date.fieldId] = (0, _dayjs.default)().format('DD-MM-YYYY');
|
|
23
|
+
} else {
|
|
24
|
+
data[date.fieldId] = date.defaultValue;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* This currently will not work for collections or containers.
|
|
29
|
+
* If support is required it will need to be added.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
var setupDefaultValue = function setupDefaultValue(component, data) {
|
|
34
|
+
if (component.defaultValue && !data[component.fieldId]) {
|
|
35
|
+
switch (component.type) {
|
|
36
|
+
case 'date':
|
|
37
|
+
setDefaultDateValue(component, data);
|
|
38
|
+
break;
|
|
39
|
+
|
|
40
|
+
default:
|
|
41
|
+
data[component.fieldId] = component.defaultValue;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (component.defaultValue) {
|
|
46
|
+
// Some components will throw warnings when having
|
|
47
|
+
// both a 'value' and 'defaultValue' prop set.
|
|
48
|
+
// defaultValue is safe to delete once we've tried
|
|
49
|
+
// to use it.
|
|
50
|
+
delete component.defaultValue;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
var setupDefaultValuesForComponents = function setupDefaultValuesForComponents(components, data) {
|
|
55
|
+
components.forEach(function (component) {
|
|
56
|
+
return setupDefaultValue(component, data);
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
var setupPageDefaultValues = function setupPageDefaultValues(pages, data) {
|
|
61
|
+
pages.forEach(function (page) {
|
|
62
|
+
page.components.filter(function (c) {
|
|
63
|
+
return !c.use;
|
|
64
|
+
}).forEach(function (component) {
|
|
65
|
+
return setupDefaultValue(component, data);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
|
|
18
70
|
var setupComponentSourceData = function setupComponentSourceData(component, data) {
|
|
19
71
|
if (component.source) {
|
|
20
72
|
data[component.fieldId] = (0, _getSourceData.default)(data, component.source.field);
|
|
@@ -37,8 +89,11 @@ var setupPageSourceData = function setupPageSourceData(pages, data) {
|
|
|
37
89
|
});
|
|
38
90
|
};
|
|
39
91
|
/**
|
|
40
|
-
* This populates an object with data from
|
|
41
|
-
*
|
|
92
|
+
* This populates an object with data either from a specified default
|
|
93
|
+
* value or from a source field. If both are specified, data from a
|
|
94
|
+
* source field will take priority.
|
|
95
|
+
* Note that in the case of source fields, this doesn't currently
|
|
96
|
+
* support sequenced dependencies:
|
|
42
97
|
* 0: fieldA: source.field = fieldB
|
|
43
98
|
* 1: fieldB: source.field = fieldC
|
|
44
99
|
* 2: fieldC: 'value'
|
|
@@ -54,6 +109,8 @@ var setupPageSourceData = function setupPageSourceData(pages, data) {
|
|
|
54
109
|
var setupFormData = function setupFormData(pages, components, baseData) {
|
|
55
110
|
var data = _objectSpread({}, baseData);
|
|
56
111
|
|
|
112
|
+
setupDefaultValuesForComponents(components, data);
|
|
113
|
+
setupPageDefaultValues(pages, data);
|
|
57
114
|
setupSourceDataForComponents(components, data);
|
|
58
115
|
setupPageSourceData(pages, data);
|
|
59
116
|
return data;
|
|
@@ -211,6 +211,66 @@ describe('utils', function () {
|
|
|
211
211
|
delegateEmails: _userProfileData.default.userDetails.delegateEmails
|
|
212
212
|
}));
|
|
213
213
|
});
|
|
214
|
+
it('should handle a default value field', function () {
|
|
215
|
+
var PAGES = [];
|
|
216
|
+
var COMPONENTS = [{
|
|
217
|
+
fieldId: 'testField',
|
|
218
|
+
type: 'text',
|
|
219
|
+
defaultValue: 'VALUE'
|
|
220
|
+
}];
|
|
221
|
+
var DATA = {};
|
|
222
|
+
var RESULT = (0, _setupFormData.default)(PAGES, COMPONENTS, DATA);
|
|
223
|
+
expect(RESULT).toEqual({
|
|
224
|
+
testField: 'VALUE'
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
it('should ignore a default value when a value already exists in data', function () {
|
|
228
|
+
var PAGES = [];
|
|
229
|
+
var COMPONENTS = [{
|
|
230
|
+
fieldId: 'testField',
|
|
231
|
+
type: 'text',
|
|
232
|
+
defaultValue: 'VALUE'
|
|
233
|
+
}];
|
|
234
|
+
var DATA = {
|
|
235
|
+
testField: 'EXISTING_VALUE'
|
|
236
|
+
};
|
|
237
|
+
var RESULT = (0, _setupFormData.default)(PAGES, COMPONENTS, DATA);
|
|
238
|
+
expect(RESULT).toEqual({
|
|
239
|
+
testField: 'EXISTING_VALUE'
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
it('should handle default values within pages', function () {
|
|
243
|
+
var PAGES = [{
|
|
244
|
+
components: [{
|
|
245
|
+
fieldId: 'pageField',
|
|
246
|
+
type: 'text',
|
|
247
|
+
defaultValue: 'VALUE'
|
|
248
|
+
}]
|
|
249
|
+
}];
|
|
250
|
+
var COMPONENTS = [];
|
|
251
|
+
var DATA = {};
|
|
252
|
+
var RESULT = (0, _setupFormData.default)(PAGES, COMPONENTS, DATA);
|
|
253
|
+
expect(RESULT).toEqual({
|
|
254
|
+
pageField: 'VALUE'
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
it('should ignore default values within pages when a value already exists in data', function () {
|
|
258
|
+
var PAGES = [{
|
|
259
|
+
components: [{
|
|
260
|
+
fieldId: 'pageField',
|
|
261
|
+
type: 'text',
|
|
262
|
+
defaultValue: 'VALUE'
|
|
263
|
+
}]
|
|
264
|
+
}];
|
|
265
|
+
var COMPONENTS = [];
|
|
266
|
+
var DATA = {
|
|
267
|
+
pageField: 'EXISTING_VALUE'
|
|
268
|
+
};
|
|
269
|
+
var RESULT = (0, _setupFormData.default)(PAGES, COMPONENTS, DATA);
|
|
270
|
+
expect(RESULT).toEqual({
|
|
271
|
+
pageField: 'EXISTING_VALUE'
|
|
272
|
+
});
|
|
273
|
+
});
|
|
214
274
|
});
|
|
215
275
|
});
|
|
216
276
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ukhomeoffice/cop-react-form-renderer",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"clean": "rimraf dist",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"post-compile": "rimraf dist/*.test.* dist/**/*.test.* dist/**/*.stories.* dist/docs dist/assets"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@ukhomeoffice/cop-react-components": "1.
|
|
19
|
+
"@ukhomeoffice/cop-react-components": "1.10.0",
|
|
20
20
|
"axios": "^0.23.0",
|
|
21
21
|
"dayjs": "^1.11.0",
|
|
22
22
|
"govuk-frontend": "^3.13.0",
|