@ukhomeoffice/cop-react-form-renderer 2.5.0 → 2.6.1-beta

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.
Files changed (47) hide show
  1. package/dist/components/FormComponent/Container.test.js +250 -0
  2. package/dist/components/FormComponent/FormComponent.js +101 -22
  3. package/dist/components/FormPage/FormPage.js +2 -1
  4. package/dist/hooks/index.js +19 -1
  5. package/dist/models/ComponentTypes.js +2 -0
  6. package/dist/utils/CheckYourAnswers/getCYARowsForContainer.js +40 -0
  7. package/dist/utils/CheckYourAnswers/getCYARowsForContainer.test.js +257 -0
  8. package/dist/utils/CheckYourAnswers/getCYARowsForPage.js +9 -1
  9. package/dist/utils/CheckYourAnswers/getCYARowsForPage.test.js +44 -0
  10. package/dist/utils/CheckYourAnswers/showComponentCYA.js +6 -0
  11. package/dist/utils/Component/cleanAttributes.js +1 -1
  12. package/dist/utils/Component/showComponent.js +2 -20
  13. package/dist/utils/Condition/index.js +19 -0
  14. package/dist/utils/Condition/meetsAllConditions.js +40 -0
  15. package/dist/utils/Condition/meetsAllConditions.test.js +62 -0
  16. package/dist/utils/{meetsCondition.js → Condition/meetsCondition.js} +0 -0
  17. package/dist/utils/Condition/meetsCondition.test.js +302 -0
  18. package/dist/utils/Condition/setupConditions.js +47 -0
  19. package/dist/utils/Condition/setupConditions.test.js +35 -0
  20. package/dist/utils/Container/getEditableComponents.js +38 -0
  21. package/dist/utils/Container/getEditableComponents.test.js +157 -0
  22. package/dist/utils/Container/index.js +22 -0
  23. package/dist/utils/Container/setupNesting.js +45 -0
  24. package/dist/utils/Container/setupNesting.test.js +92 -0
  25. package/dist/utils/Container/showContainer.js +61 -0
  26. package/dist/utils/Container/showContainer.test.js +128 -0
  27. package/dist/utils/Data/getDataPath.js +90 -0
  28. package/dist/utils/Data/getDataPath.test.js +52 -0
  29. package/dist/utils/Data/index.js +3 -0
  30. package/dist/utils/FormPage/getFormPage.js +4 -2
  31. package/dist/utils/FormPage/getFormPage.test.js +18 -7
  32. package/dist/utils/FormPage/getFormPages.test.js +5 -2
  33. package/dist/utils/FormPage/index.js +0 -3
  34. package/dist/utils/FormPage/showFormPage.js +7 -27
  35. package/dist/utils/Hub/getFormHub.test.js +5 -2
  36. package/dist/utils/Validate/index.js +7 -1
  37. package/dist/utils/Validate/validateComponent.js +26 -6
  38. package/dist/utils/Validate/validateComponent.test.js +44 -0
  39. package/dist/utils/Validate/validateDate.js +11 -0
  40. package/dist/utils/Validate/validateDate.test.js +6 -0
  41. package/dist/utils/Validate/validatePage.js +6 -8
  42. package/dist/utils/Validate/validateTime.js +19 -0
  43. package/dist/utils/Validate/validateTime.test.js +6 -0
  44. package/dist/utils/index.js +6 -3
  45. package/package.json +9 -7
  46. package/dist/utils/FormPage/getEditableComponents.js +0 -28
  47. package/dist/utils/FormPage/getEditableComponents.test.js +0 -75
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+
3
+ var _models = require("../../models");
4
+
5
+ var _getCYARowsForContainer = _interopRequireDefault(require("./getCYARowsForContainer"));
6
+
7
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8
+
9
+ // Local imports
10
+ describe('utils.CheckYourAnswers.getCYARowsForContainer', function () {
11
+ var expectObjectLike = function expectObjectLike(received, expected) {
12
+ Object.keys(expected).forEach(function (key) {
13
+ expect(received[key]).toEqual(expected[key]);
14
+ });
15
+ };
16
+
17
+ it('should get an appropriate row for a container with a single readonly text component', function () {
18
+ var FORM_DATA = {
19
+ container: {
20
+ a: 'Bravo'
21
+ }
22
+ };
23
+ var PAGE = {
24
+ id: 'page',
25
+ formData: FORM_DATA,
26
+ cya_link: {}
27
+ };
28
+ var COMPONENT = {
29
+ type: 'text',
30
+ readonly: true,
31
+ id: 'a',
32
+ fieldId: 'a',
33
+ label: 'Alpha'
34
+ };
35
+ var CONTAINER = {
36
+ id: 'container',
37
+ fieldId: 'container',
38
+ type: _models.ComponentTypes.CONTAINER,
39
+ components: [COMPONENT],
40
+ value: FORM_DATA.container,
41
+ formData: FORM_DATA
42
+ };
43
+
44
+ var ON_ACTION = function ON_ACTION() {};
45
+
46
+ var ROWS = (0, _getCYARowsForContainer.default)(PAGE, CONTAINER, FORM_DATA.container, ON_ACTION);
47
+ expect(ROWS.length).toEqual(1);
48
+ ROWS.forEach(function (row, index) {
49
+ expectObjectLike(row, {
50
+ pageId: PAGE.id,
51
+ fieldId: CONTAINER.components[index].fieldId,
52
+ key: CONTAINER.components[index].label,
53
+ action: null,
54
+ component: COMPONENT,
55
+ value: 'Bravo'
56
+ });
57
+ });
58
+ });
59
+ it('should get appropriate rows for a container with two editable text components', function () {
60
+ var FORM_DATA = {
61
+ container: {
62
+ a: 'Alpha Charlie',
63
+ b: 'Bravo Charlie'
64
+ }
65
+ };
66
+ var PAGE = {
67
+ id: 'page',
68
+ formData: FORM_DATA,
69
+ cya_link: {}
70
+ };
71
+ var COMPONENT_A = {
72
+ type: 'text',
73
+ id: 'a',
74
+ fieldId: 'a',
75
+ label: 'Alpha'
76
+ };
77
+ var COMPONENT_B = {
78
+ type: 'text',
79
+ id: 'b',
80
+ fieldId: 'b',
81
+ label: 'Bravo'
82
+ };
83
+ var CONTAINER = {
84
+ id: 'container',
85
+ fieldId: 'container',
86
+ type: _models.ComponentTypes.CONTAINER,
87
+ components: [COMPONENT_A, COMPONENT_B],
88
+ value: FORM_DATA.container,
89
+ formData: FORM_DATA
90
+ };
91
+
92
+ var ON_ACTION = function ON_ACTION() {};
93
+
94
+ var ROWS = (0, _getCYARowsForContainer.default)(PAGE, CONTAINER, FORM_DATA.container, ON_ACTION);
95
+ expect(ROWS.length).toEqual(2);
96
+ ROWS.forEach(function (row, index) {
97
+ expectObjectLike(row, {
98
+ pageId: PAGE.id,
99
+ fieldId: CONTAINER.components[index].fieldId,
100
+ key: CONTAINER.components[index].label,
101
+ component: CONTAINER.components[index],
102
+ value: "".concat(CONTAINER.components[index].label, " Charlie")
103
+ });
104
+ expectObjectLike(row.action, {
105
+ onAction: ON_ACTION
106
+ });
107
+ });
108
+ });
109
+ it("should filter out any components that shouldn't be shown", function () {
110
+ var FORM_DATA = {
111
+ container: {
112
+ a: 'Alpha Charlie',
113
+ b: 'Bravo Charlie'
114
+ }
115
+ };
116
+ var PAGE = {
117
+ id: 'page',
118
+ formData: FORM_DATA,
119
+ cya_link: {}
120
+ };
121
+ var COMPONENT_A = {
122
+ type: 'text',
123
+ id: 'a',
124
+ fieldId: 'a',
125
+ label: 'Alpha'
126
+ };
127
+ var COMPONENT_B = {
128
+ type: 'text',
129
+ id: 'b',
130
+ fieldId: 'b',
131
+ label: 'Bravo'
132
+ };
133
+ var COMPONENT_C = {
134
+ type: 'heading',
135
+ content: 'Heading component'
136
+ };
137
+ var CONTAINER = {
138
+ id: 'container',
139
+ fieldId: 'container',
140
+ type: _models.ComponentTypes.CONTAINER,
141
+ components: [COMPONENT_A, COMPONENT_B, COMPONENT_C],
142
+ value: FORM_DATA.container,
143
+ formData: FORM_DATA
144
+ };
145
+
146
+ var ON_ACTION = function ON_ACTION() {};
147
+
148
+ var ROWS = (0, _getCYARowsForContainer.default)(PAGE, CONTAINER, FORM_DATA.container, ON_ACTION);
149
+ expect(ROWS.length).toEqual(2);
150
+ ROWS.forEach(function (row, index) {
151
+ expectObjectLike(row, {
152
+ pageId: PAGE.id,
153
+ fieldId: CONTAINER.components[index].fieldId,
154
+ key: CONTAINER.components[index].label,
155
+ component: CONTAINER.components[index],
156
+ value: "".concat(CONTAINER.components[index].label, " Charlie")
157
+ });
158
+ expectObjectLike(row.action, {
159
+ onAction: ON_ACTION
160
+ });
161
+ });
162
+ });
163
+ it('should get an appropriate row for a container with a single readonly text component inside a nested container', function () {
164
+ var FORM_DATA = {
165
+ container: {
166
+ nested: {
167
+ a: 'Bravo'
168
+ }
169
+ }
170
+ };
171
+ var PAGE = {
172
+ id: 'page',
173
+ formData: FORM_DATA,
174
+ cya_link: {}
175
+ };
176
+ var COMPONENT = {
177
+ type: 'text',
178
+ readonly: true,
179
+ id: 'a',
180
+ fieldId: 'a',
181
+ label: 'Alpha'
182
+ };
183
+ var NESTED_CONTAINER = {
184
+ id: 'nested',
185
+ fieldId: 'nested',
186
+ type: _models.ComponentTypes.CONTAINER,
187
+ components: [COMPONENT],
188
+ value: FORM_DATA.container.nested,
189
+ formData: FORM_DATA
190
+ };
191
+ var CONTAINER = {
192
+ id: 'container',
193
+ fieldId: 'container',
194
+ type: _models.ComponentTypes.CONTAINER,
195
+ components: [NESTED_CONTAINER],
196
+ value: FORM_DATA.container,
197
+ formData: FORM_DATA
198
+ };
199
+
200
+ var ON_ACTION = function ON_ACTION() {};
201
+
202
+ var ROWS = (0, _getCYARowsForContainer.default)(PAGE, CONTAINER, FORM_DATA.container, ON_ACTION);
203
+ expect(ROWS.length).toEqual(1);
204
+ ROWS.forEach(function (row, index) {
205
+ expectObjectLike(row, {
206
+ pageId: PAGE.id,
207
+ fieldId: NESTED_CONTAINER.components[index].fieldId,
208
+ key: NESTED_CONTAINER.components[index].label,
209
+ action: null,
210
+ component: COMPONENT,
211
+ value: 'Bravo'
212
+ });
213
+ });
214
+ });
215
+ it('should get an appropriate row for a container with a single readonly text component inside a nested container but no formData', function () {
216
+ var FORM_DATA = undefined;
217
+ var PAGE = {
218
+ id: 'page',
219
+ formData: FORM_DATA,
220
+ cya_link: {}
221
+ };
222
+ var COMPONENT = {
223
+ type: 'text',
224
+ readonly: true,
225
+ id: 'a',
226
+ fieldId: 'a',
227
+ label: 'Alpha'
228
+ };
229
+ var NESTED_CONTAINER = {
230
+ id: 'nested',
231
+ fieldId: 'nested',
232
+ type: _models.ComponentTypes.CONTAINER,
233
+ components: [COMPONENT]
234
+ };
235
+ var CONTAINER = {
236
+ id: 'container',
237
+ fieldId: 'container',
238
+ type: _models.ComponentTypes.CONTAINER,
239
+ components: [NESTED_CONTAINER]
240
+ };
241
+
242
+ var ON_ACTION = function ON_ACTION() {};
243
+
244
+ var ROWS = (0, _getCYARowsForContainer.default)(PAGE, CONTAINER, undefined, ON_ACTION);
245
+ expect(ROWS.length).toEqual(1);
246
+ ROWS.forEach(function (row, index) {
247
+ expectObjectLike(row, {
248
+ pageId: PAGE.id,
249
+ fieldId: NESTED_CONTAINER.components[index].fieldId,
250
+ key: NESTED_CONTAINER.components[index].label,
251
+ action: null,
252
+ component: COMPONENT,
253
+ value: ''
254
+ });
255
+ });
256
+ });
257
+ });
@@ -5,10 +5,14 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
+ var _models = require("../../models");
9
+
8
10
  var _FormPage = _interopRequireDefault(require("../FormPage"));
9
11
 
10
12
  var _getCYARow = _interopRequireDefault(require("./getCYARow"));
11
13
 
14
+ var _getCYARowsForContainer = _interopRequireDefault(require("./getCYARowsForContainer"));
15
+
12
16
  var _showComponentCYA = _interopRequireDefault(require("./showComponentCYA"));
13
17
 
14
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -27,7 +31,11 @@ var getCYARowsForPage = function getCYARowsForPage(page, onAction) {
27
31
  if (_FormPage.default.show(page, page.formData)) {
28
32
  return page.components.filter(function (c) {
29
33
  return (0, _showComponentCYA.default)(c, page.formData);
30
- }).map(function (component) {
34
+ }).flatMap(function (component) {
35
+ if (component.type === _models.ComponentTypes.CONTAINER) {
36
+ return (0, _getCYARowsForContainer.default)(page, component, page.formData[component.fieldId], onAction);
37
+ }
38
+
31
39
  return (0, _getCYARow.default)(page, component, onAction);
32
40
  });
33
41
  }
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
 
3
+ var _models = require("../../models");
4
+
3
5
  var _getCYARowsForPage = _interopRequireDefault(require("./getCYARowsForPage"));
4
6
 
5
7
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -129,6 +131,48 @@ describe('utils', function () {
129
131
  });
130
132
  });
131
133
  });
134
+ it('should get a appropriate row for a page with a single readonly text component inside of a container', function () {
135
+ var FORM_DATA = {
136
+ container: {
137
+ a: 'Bravo'
138
+ }
139
+ };
140
+ var COMPONENT = {
141
+ type: 'text',
142
+ readonly: true,
143
+ id: 'a',
144
+ fieldId: 'a',
145
+ label: 'Alpha'
146
+ };
147
+ var CONTAINER = {
148
+ id: 'container',
149
+ fieldId: 'container',
150
+ type: _models.ComponentTypes.CONTAINER,
151
+ components: [COMPONENT],
152
+ value: FORM_DATA.container,
153
+ formData: FORM_DATA
154
+ };
155
+ var PAGE = {
156
+ id: 'page',
157
+ components: [CONTAINER],
158
+ formData: FORM_DATA
159
+ };
160
+
161
+ var ON_ACTION = function ON_ACTION() {};
162
+
163
+ var ROWS = (0, _getCYARowsForPage.default)(PAGE, ON_ACTION);
164
+ expect(ROWS.length).toEqual(1);
165
+ ROWS.forEach(function (row, index) {
166
+ expectObjectLike(row, {
167
+ pageId: PAGE.id,
168
+ fieldId: CONTAINER.components[index].fieldId,
169
+ key: CONTAINER.components[index].label,
170
+ action: null,
171
+ component: COMPONENT,
172
+ value: 'Bravo'
173
+ });
174
+ });
175
+ });
132
176
  });
133
177
  });
134
178
  });
@@ -9,6 +9,8 @@ var _models = require("../../models");
9
9
 
10
10
  var _Component = _interopRequireDefault(require("../Component"));
11
11
 
12
+ var _Container = _interopRequireDefault(require("../Container"));
13
+
12
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
15
 
14
16
  // Local imports
@@ -31,6 +33,10 @@ var showComponentCYA = function showComponentCYA(options, data) {
31
33
  return false;
32
34
  }
33
35
 
36
+ if (options.type === _models.ComponentTypes.CONTAINER) {
37
+ return _Container.default.show(options, data);
38
+ }
39
+
34
40
  return _Component.default.show(options, data);
35
41
  };
36
42
 
@@ -19,7 +19,7 @@ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToAr
19
19
 
20
20
  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; }
21
21
 
22
- var JSON_ONLY_PROPERTIES = ['source', 'use', 'show_when', 'options', 'additionalValidation'];
22
+ var JSON_ONLY_PROPERTIES = ['source', 'use', 'show_when', 'options', 'additionalValidation', 'full_path'];
23
23
  /**
24
24
  * This method removes and properties that are entirely specific to the JSON
25
25
  * configuration and that should not be used as HTML attributes.
@@ -5,9 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _Data = _interopRequireDefault(require("../Data"));
9
-
10
- var _meetsCondition = _interopRequireDefault(require("../meetsCondition"));
8
+ var _Condition = _interopRequireDefault(require("../Condition"));
11
9
 
12
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
11
 
@@ -21,23 +19,7 @@ var showComponent = function showComponent(component, data) {
21
19
  return false;
22
20
  }
23
21
 
24
- if (component.show_when) {
25
- if (Array.isArray(component.show_when)) {
26
- var allConditionsMet = true;
27
- component.show_when.forEach(function (condition) {
28
- var sourceDataValue = _Data.default.getSource(data, condition.field);
29
-
30
- allConditionsMet = allConditionsMet && (0, _meetsCondition.default)(condition, sourceDataValue);
31
- });
32
- return allConditionsMet;
33
- } else {
34
- var sourceDataValue = _Data.default.getSource(data, component.show_when.field);
35
-
36
- return (0, _meetsCondition.default)(component.show_when, sourceDataValue);
37
- }
38
- }
39
-
40
- return true;
22
+ return _Condition.default.meetsAll(component, data);
41
23
  };
42
24
 
43
25
  var _default = showComponent;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _meetsAllConditions = _interopRequireDefault(require("./meetsAllConditions"));
9
+
10
+ var _meetsCondition = _interopRequireDefault(require("./meetsCondition"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ var Condition = {
15
+ meetsAll: _meetsAllConditions.default,
16
+ met: _meetsCondition.default
17
+ };
18
+ var _default = Condition;
19
+ exports.default = _default;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _Data = _interopRequireDefault(require("../Data"));
9
+
10
+ var _meetsCondition = _interopRequireDefault(require("./meetsCondition"));
11
+
12
+ var _setupConditions = _interopRequireDefault(require("./setupConditions"));
13
+
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+
16
+ // Local imports
17
+
18
+ /**
19
+ * Evaluates all condition(s) on a page, container, or component.
20
+ * @param {object} options The container to consider.
21
+ * @param {object} data The top-level form data.
22
+ * @returns Boolean true if all conditions are met; false otherwise.
23
+ */
24
+ var meetsAllConditions = function meetsAllConditions(options, data) {
25
+ var conditions = (0, _setupConditions.default)(options);
26
+
27
+ if (conditions) {
28
+ var arr = Array.isArray(conditions) ? conditions : [conditions];
29
+ return arr.every(function (condition) {
30
+ var sourceDataValue = _Data.default.getSource(data, condition.field);
31
+
32
+ return (0, _meetsCondition.default)(condition, sourceDataValue);
33
+ });
34
+ }
35
+
36
+ return true;
37
+ };
38
+
39
+ var _default = meetsAllConditions;
40
+ exports.default = _default;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ var _meetsAllConditions = _interopRequireDefault(require("./meetsAllConditions"));
4
+
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+
7
+ // Local imports
8
+ describe('utils.Condition.meetsAllConditions', function () {
9
+ var DATA = {
10
+ alpha: 'bravo',
11
+ charlie: 'delta'
12
+ };
13
+ it('should evaluate to true when conditions are null', function () {
14
+ expect((0, _meetsAllConditions.default)(null, DATA)).toBeTruthy();
15
+ });
16
+ it('should evaluate to true when conditions are undefined', function () {
17
+ expect((0, _meetsAllConditions.default)(undefined, DATA)).toBeTruthy();
18
+ });
19
+ it('should evaluate to true when conditions is an empty array', function () {
20
+ expect((0, _meetsAllConditions.default)([], DATA)).toBeTruthy();
21
+ });
22
+ it('should evaluate to true when a single condition is met', function () {
23
+ var CONDITION = {
24
+ field: 'alpha',
25
+ op: 'eq',
26
+ value: 'bravo'
27
+ };
28
+ expect((0, _meetsAllConditions.default)(CONDITION, DATA)).toBeTruthy();
29
+ });
30
+ it('should evaluate to false when a single condition is not met', function () {
31
+ var CONDITION = {
32
+ field: 'alpha',
33
+ op: 'ne',
34
+ value: 'bravo'
35
+ };
36
+ expect((0, _meetsAllConditions.default)(CONDITION, DATA)).toBeFalsy();
37
+ });
38
+ it('should evaluate to true when all conditions are met', function () {
39
+ var CONDITIONS = [{
40
+ field: 'alpha',
41
+ op: 'eq',
42
+ value: 'bravo'
43
+ }, {
44
+ field: 'charlie',
45
+ op: 'eq',
46
+ value: 'delta'
47
+ }];
48
+ expect((0, _meetsAllConditions.default)(CONDITIONS, DATA)).toBeTruthy();
49
+ });
50
+ it('should evaluate to false when one of the conditions is not met', function () {
51
+ var CONDITIONS = [{
52
+ field: 'alpha',
53
+ op: 'eq',
54
+ value: 'bravo'
55
+ }, {
56
+ field: 'charlie',
57
+ op: 'eq',
58
+ value: 'echo'
59
+ }];
60
+ expect((0, _meetsAllConditions.default)(CONDITIONS, DATA)).toBeFalsy();
61
+ });
62
+ });