@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
@@ -7,20 +7,26 @@ exports.default = void 0;
7
7
 
8
8
  var _validateComponent = _interopRequireDefault(require("./validateComponent"));
9
9
 
10
+ var _validateDate = _interopRequireDefault(require("./validateDate"));
11
+
10
12
  var _validateEmail = _interopRequireDefault(require("./validateEmail"));
11
13
 
12
14
  var _validatePage = _interopRequireDefault(require("./validatePage"));
13
15
 
14
16
  var _validateRequired = _interopRequireDefault(require("./validateRequired"));
15
17
 
18
+ var _validateTime = _interopRequireDefault(require("./validateTime"));
19
+
16
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
21
 
18
22
  // Local imports
19
23
  var Validate = {
20
24
  component: _validateComponent.default,
21
25
  email: _validateEmail.default,
26
+ date: _validateDate.default,
22
27
  page: _validatePage.default,
23
- required: _validateRequired.default
28
+ required: _validateRequired.default,
29
+ time: _validateTime.default
24
30
  };
25
31
  var _default = Validate;
26
32
  exports.default = _default;
@@ -9,31 +9,51 @@ var _models = require("../../models");
9
9
 
10
10
  var _showComponent = _interopRequireDefault(require("../Component/showComponent"));
11
11
 
12
+ var _additional = _interopRequireDefault(require("./additional"));
13
+
14
+ var _validateDate2 = _interopRequireDefault(require("./validateDate"));
15
+
12
16
  var _validateEmail = _interopRequireDefault(require("./validateEmail"));
13
17
 
14
18
  var _validateRequired = _interopRequireDefault(require("./validateRequired"));
15
19
 
16
- var _validateDate2 = _interopRequireDefault(require("./validateDate"));
17
-
18
20
  var _validateTime2 = _interopRequireDefault(require("./validateTime"));
19
21
 
20
- var _additional = _interopRequireDefault(require("./additional"));
21
-
22
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
23
 
24
24
  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
25
25
 
26
+ var validateContainer = function validateContainer(container, formData) {
27
+ var errors = [];
28
+
29
+ if (Array.isArray(container.components)) {
30
+ var fd = formData && container.fieldId ? formData[container.fieldId] : formData;
31
+ container.components.forEach(function (component) {
32
+ errors.push(validateComponent(component, fd));
33
+ });
34
+ }
35
+
36
+ return errors.filter(function (e) {
37
+ return !!e;
38
+ });
39
+ };
26
40
  /**
27
41
  * Validates a single component.
28
42
  * @param {object} component The component to validate.
29
43
  * @param {object} formData The data to use that holds this component's value.
30
44
  * @returns The first encountered error with the component.
31
45
  */
46
+
47
+
32
48
  var validateComponent = function validateComponent(component, formData) {
33
49
  var error = undefined;
34
50
  var data = formData && _typeof(formData) === 'object' ? formData : {};
35
51
 
36
52
  if (component && (0, _showComponent.default)(component, formData)) {
53
+ if (component.type === _models.ComponentTypes.CONTAINER) {
54
+ return validateContainer(component, formData);
55
+ }
56
+
37
57
  var value = data[component.fieldId];
38
58
  delete component.propsInError;
39
59
 
@@ -45,7 +65,7 @@ var validateComponent = function validateComponent(component, formData) {
45
65
  error = (0, _validateEmail.default)(value, component.label);
46
66
  }
47
67
 
48
- if (!error && component.type === _models.ComponentTypes.DATE && value) {
68
+ if (!error && component.type === _models.ComponentTypes.DATE) {
49
69
  var _validateDate = (0, _validateDate2.default)(value),
50
70
  message = _validateDate.message,
51
71
  propsInError = _validateDate.propsInError;
@@ -54,7 +74,7 @@ var validateComponent = function validateComponent(component, formData) {
54
74
  error = message;
55
75
  }
56
76
 
57
- if (!error && component.type === _models.ComponentTypes.TIME && value) {
77
+ if (!error && component.type === _models.ComponentTypes.TIME) {
58
78
  var _validateTime = (0, _validateTime2.default)(value),
59
79
  _message = _validateTime.message,
60
80
  _propsInError = _validateTime.propsInError;
@@ -160,6 +160,50 @@ describe('utils', function () {
160
160
  });
161
161
  });
162
162
  });
163
+ describe('when the component is a container', function () {
164
+ it('should return an empty array when the container has an undefined components array', function () {
165
+ var ID = 'container';
166
+ var LABEL = 'field';
167
+ var CONTAINER = setup(ID, _models.ComponentTypes.CONTAINER, LABEL, false);
168
+ expect((0, _validateComponent.default)(CONTAINER, null)).toEqual([]);
169
+ });
170
+ it('should return an empty array when the container has no components', function () {
171
+ var ID = 'container';
172
+ var LABEL = 'field';
173
+ var CONTAINER = setup(ID, _models.ComponentTypes.CONTAINER, LABEL, false);
174
+ CONTAINER.components = [];
175
+ expect((0, _validateComponent.default)(CONTAINER, null)).toEqual([]);
176
+ });
177
+ it('should return an empty array when the container has only valid components', function () {
178
+ var EMAIL_ID = 'email';
179
+ var EMAIL_LABEL = 'Email';
180
+ var EMAIL = setup(EMAIL_ID, _models.ComponentTypes.EMAIL, EMAIL_LABEL, false);
181
+ var ID = 'container';
182
+ var LABEL = 'field';
183
+ var CONTAINER = setup(ID, _models.ComponentTypes.CONTAINER, LABEL, false);
184
+ CONTAINER.components = [EMAIL];
185
+
186
+ var DATA = _defineProperty({}, ID, _defineProperty({}, EMAIL_ID, 'alpha.bravo@digital.homeoffice.gov.uk'));
187
+
188
+ expect((0, _validateComponent.default)(CONTAINER, DATA)).toEqual([]);
189
+ });
190
+ it('should return an array containing an error when the container has an invalid component', function () {
191
+ var EMAIL_ID = 'email';
192
+ var EMAIL_LABEL = 'Email';
193
+ var EMAIL = setup(EMAIL_ID, _models.ComponentTypes.EMAIL, EMAIL_LABEL, false);
194
+ var ID = 'container';
195
+ var LABEL = 'field';
196
+ var CONTAINER = setup(ID, _models.ComponentTypes.CONTAINER, LABEL, false);
197
+ CONTAINER.components = [EMAIL];
198
+
199
+ var DATA = _defineProperty({}, ID, _defineProperty({}, EMAIL_ID, 'alpha.bravo@digital.homeoffice.com'));
200
+
201
+ expect((0, _validateComponent.default)(CONTAINER, DATA)).toEqual([{
202
+ id: EMAIL_ID,
203
+ error: "Enter ".concat(EMAIL_LABEL.toLowerCase(), " in the correct format, like jane.doe@homeoffice.gov.uk")
204
+ }]);
205
+ });
206
+ });
163
207
  });
164
208
  });
165
209
  });
@@ -51,11 +51,22 @@ exports.maxMonthDays = maxMonthDays;
51
51
  * Checks if a date passed is a valid date.
52
52
  * This will validate for 'leap years', missing components, invalid day, monnth or year components.
53
53
  * EXAMPLE USE : const { message, propsInError } = validateDate('2-11-2020')
54
+ *
55
+ * Note that an empty string is not considered invalid. You should use
56
+ * validateRequired (Validate.required) for that sort of validation.
57
+ *
54
58
  * @param {string} date date as a string
55
59
  * @returns an object with an error message and instructions for which parts of the date are in error
56
60
  * or undefined for both if the date is valid
57
61
  */
58
62
  var validateDate = function validateDate(date) {
63
+ if (!date) {
64
+ return {
65
+ message: undefined,
66
+ propsInError: undefined
67
+ };
68
+ }
69
+
59
70
  var formattedDate = (0, _utils.formatString)(date);
60
71
 
61
72
  var _formattedDate$split = formattedDate.split('-'),
@@ -11,6 +11,12 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
11
11
  describe('utils', function () {
12
12
  describe('Validate', function () {
13
13
  describe('date', function () {
14
+ test('should return no error when the value is an empty string', function () {
15
+ expect((0, _validateDate.default)('', 'DD-MM-YYYY')).toEqual({
16
+ message: undefined,
17
+ propsInError: undefined
18
+ });
19
+ });
14
20
  test('should return undefined if a date string is valid', function () {
15
21
  var output = (0, _validateDate.default)('28-02-2024', 'DD-MM-YYYY');
16
22
  expect(output).toEqual({
@@ -18,17 +18,15 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
18
18
  * @returns An array containing all of the errors.
19
19
  */
20
20
  var validatePage = function validatePage(components, formData) {
21
- var errors = [];
22
-
23
21
  if (Array.isArray(components)) {
24
- components.forEach(function (component) {
25
- errors.push((0, _validateComponent.default)(component, formData));
26
- });
22
+ return components.reduce(function (errors, component) {
23
+ return errors.concat((0, _validateComponent.default)(component, formData));
24
+ }, []).filter(function (e) {
25
+ return !!e;
26
+ }).flat();
27
27
  }
28
28
 
29
- return errors.filter(function (e) {
30
- return !!e;
31
- });
29
+ return [];
32
30
  };
33
31
 
34
32
  var _default = validatePage;
@@ -19,7 +19,26 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
19
19
 
20
20
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
21
21
 
22
+ /**
23
+ * Checks if a time passed is a valid time.
24
+ * This will validate for missing components, invalid hour or minute components.
25
+ * EXAMPLE USE : const { message, propsInError } = validateTime('15:30')
26
+ *
27
+ * Note that an empty string is not considered invalid. You should use
28
+ * validateRequired (Validate.required) for that sort of validation.
29
+ *
30
+ * @param {string} time time as a string
31
+ * @returns an object with an error message and instructions for which parts of the time are in error
32
+ * or undefined for both if the time is valid
33
+ */
22
34
  var validateTime = function validateTime(time) {
35
+ if (!time) {
36
+ return {
37
+ message: undefined,
38
+ propsInError: undefined
39
+ };
40
+ }
41
+
23
42
  var formattedDate = (0, _utils.formattedTime)(time);
24
43
 
25
44
  var _formattedDate$split = formattedDate.split(':'),
@@ -7,6 +7,12 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
7
7
  describe('utils', function () {
8
8
  describe('Validate', function () {
9
9
  describe('time', function () {
10
+ test('should return no error when the value is an empty string', function () {
11
+ expect((0, _validateTime.default)('')).toEqual({
12
+ message: undefined,
13
+ propsInError: undefined
14
+ });
15
+ });
10
16
  test('should return undefined if a time string is valid', function () {
11
17
  var output = (0, _validateTime.default)('14:30');
12
18
  expect(output).toEqual({
@@ -11,6 +11,10 @@ var _CheckYourAnswers = _interopRequireDefault(require("./CheckYourAnswers"));
11
11
 
12
12
  var _Component = _interopRequireDefault(require("./Component"));
13
13
 
14
+ var _Condition = _interopRequireDefault(require("./Condition"));
15
+
16
+ var _Container = _interopRequireDefault(require("./Container"));
17
+
14
18
  var _Data = _interopRequireDefault(require("./Data"));
15
19
 
16
20
  var _Format = _interopRequireDefault(require("./Format"));
@@ -19,8 +23,6 @@ var _FormPage = _interopRequireDefault(require("./FormPage"));
19
23
 
20
24
  var _Hub = _interopRequireDefault(require("./Hub"));
21
25
 
22
- var _meetsCondition = _interopRequireDefault(require("./meetsCondition"));
23
-
24
26
  var _Validate = _interopRequireDefault(require("./Validate"));
25
27
 
26
28
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -34,11 +36,12 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
34
36
  var Utils = _objectSpread({
35
37
  CheckYourAnswers: _CheckYourAnswers.default,
36
38
  Component: _Component.default,
39
+ Container: _Container.default,
37
40
  Data: _Data.default,
38
41
  Format: _Format.default,
39
42
  FormPage: _FormPage.default,
40
43
  Hub: _Hub.default,
41
- meetsCondition: _meetsCondition.default,
44
+ Condition: _Condition.default,
42
45
  Validate: _Validate.default
43
46
  }, _copReactComponents.Utils);
44
47
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ukhomeoffice/cop-react-form-renderer",
3
- "version": "2.5.0",
3
+ "version": "2.6.1-beta",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "clean": "rimraf dist",
@@ -43,22 +43,24 @@
43
43
  "@testing-library/react-hooks": "^7.0.2",
44
44
  "@testing-library/user-event": "^12.1.10",
45
45
  "axios-mock-adapter": "^1.18.1",
46
+ "babel-loader": "8.1.0",
46
47
  "cross-env": "^7.0.3",
47
48
  "html-react-parser": "^0.10.5",
48
49
  "node-sass": "^6.0.1",
49
- "react": "^16.13.1",
50
- "react-dom": "^16.13.1",
50
+ "react": "^17.0.1",
51
+ "react-dom": "^17.0.1",
51
52
  "react-scripts": "4.0.3",
52
- "storybook-addon-mock": "^2.0.1"
53
+ "storybook-addon-mock": "^2.0.1",
54
+ "webpack": "4.44.2"
53
55
  },
54
56
  "peerDependencies": {
55
57
  "react": "^16.13.1",
56
58
  "react-dom": "^16.13.1",
57
59
  "react-scripts": "4.0.3"
58
60
  },
59
- "optionalDependencies": {
60
- "babel-loader": "8.1.0",
61
- "webpack": "4.44.2"
61
+ "optionalDependencies": {},
62
+ "resolutions": {
63
+ "immer": "9.0.6"
62
64
  },
63
65
  "main": "dist/index.js",
64
66
  "files": [
@@ -1,28 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _Component = _interopRequireDefault(require("../Component"));
9
-
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
-
12
- /**
13
- * Gets all the editable components on a page.
14
- * @param {object} page The page to consider.
15
- * @returns An array of ONLY the editable components on a page.
16
- */
17
- var getEditableComponents = function getEditableComponents(page) {
18
- if (page && Array.isArray(page.components)) {
19
- return page.components.filter(function (c) {
20
- return _Component.default.editable(c);
21
- });
22
- }
23
-
24
- return [];
25
- };
26
-
27
- var _default = getEditableComponents;
28
- exports.default = _default;
@@ -1,75 +0,0 @@
1
- "use strict";
2
-
3
- var _getEditableComponents = _interopRequireDefault(require("./getEditableComponents"));
4
-
5
- var _isEditable = require("../Component/isEditable");
6
-
7
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8
-
9
- describe('utils', function () {
10
- describe('FormPage', function () {
11
- describe('getEditableComponents', function () {
12
- var HTML = {
13
- type: 'html',
14
- tagName: 'p',
15
- content: 'Alpha'
16
- };
17
- var INSET_TEXT = {
18
- type: 'inset-text',
19
- content: 'Bravo'
20
- };
21
- var HEADING = {
22
- type: 'heading',
23
- size: 'm',
24
- content: 'Charlie'
25
- };
26
- it('should return an empty array for a null page', function () {
27
- expect((0, _getEditableComponents.default)(null)).toEqual([]);
28
- });
29
- it('should return an empty array for a page with no components', function () {
30
- expect((0, _getEditableComponents.default)({
31
- components: []
32
- })).toEqual([]);
33
- });
34
- it('should return an empty array for a page with only non-editable components', function () {
35
- var COMPONENTS = [HTML, INSET_TEXT, HEADING];
36
- expect((0, _getEditableComponents.default)({
37
- components: COMPONENTS
38
- })).toEqual([]);
39
- });
40
-
41
- _isEditable.EDITABLE_TYPES.forEach(function (type) {
42
- it("should return just the \"".concat(type, "\" component if it exists in the components but no non-editable ones"), function () {
43
- var EDITABLE = {
44
- type: type
45
- };
46
- var COMPONENTS = [HTML, EDITABLE, INSET_TEXT, HEADING];
47
- expect((0, _getEditableComponents.default)({
48
- components: COMPONENTS
49
- })).toEqual([EDITABLE]);
50
- });
51
- });
52
-
53
- it('should return all editable components and no non-editable ones', function () {
54
- var COMPONENTS = [HTML, INSET_TEXT, HEADING];
55
-
56
- _isEditable.EDITABLE_TYPES.forEach(function (type) {
57
- COMPONENTS.push({
58
- type: type
59
- });
60
- });
61
-
62
- var RESULT = (0, _getEditableComponents.default)({
63
- components: COMPONENTS
64
- });
65
- expect(RESULT.length).toEqual(_isEditable.EDITABLE_TYPES.length);
66
-
67
- _isEditable.EDITABLE_TYPES.forEach(function (type) {
68
- expect(RESULT).toContainEqual({
69
- type: type
70
- });
71
- });
72
- });
73
- });
74
- });
75
- });