@ukhomeoffice/cop-react-form-renderer 0.1.0-beta → 1.0.0-delta

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 (91) hide show
  1. package/dist/components/CheckYourAnswers/Answer.js +48 -0
  2. package/dist/components/CheckYourAnswers/Answer.test.js +94 -0
  3. package/dist/components/CheckYourAnswers/CheckYourAnswers.js +64 -19
  4. package/dist/components/CheckYourAnswers/CheckYourAnswers.scss +0 -7
  5. package/dist/components/CheckYourAnswers/CheckYourAnswers.stories.mdx +100 -0
  6. package/dist/components/CheckYourAnswers/CheckYourAnswers.test.js +317 -0
  7. package/dist/components/FormComponent/FormComponent.js +7 -7
  8. package/dist/components/FormComponent/FormComponent.stories.mdx +167 -0
  9. package/dist/components/FormComponent/FormComponent.test.js +137 -0
  10. package/dist/components/FormPage/FormPage.js +12 -11
  11. package/dist/components/FormPage/FormPage.stories.mdx +118 -0
  12. package/dist/components/FormPage/FormPage.test.js +255 -0
  13. package/dist/components/FormRenderer/FormRenderer.js +70 -58
  14. package/dist/components/FormRenderer/FormRenderer.stories.mdx +90 -0
  15. package/dist/components/FormRenderer/FormRenderer.test.js +469 -0
  16. package/dist/components/FormRenderer/handlers/cyaAction.js +28 -0
  17. package/dist/components/FormRenderer/handlers/getPageId.js +28 -0
  18. package/dist/components/FormRenderer/handlers/getPageId.test.js +61 -0
  19. package/dist/components/FormRenderer/handlers/handlers.test.js +97 -0
  20. package/dist/components/FormRenderer/handlers/index.js +23 -0
  21. package/dist/components/FormRenderer/handlers/navigate.js +28 -0
  22. package/dist/components/FormRenderer/handlers/submissionError.js +20 -0
  23. package/dist/components/FormRenderer/helpers/canActionProceed.js +35 -0
  24. package/dist/components/FormRenderer/helpers/canActionProceed.test.js +73 -0
  25. package/dist/components/FormRenderer/helpers/canCYASubmit.js +42 -0
  26. package/dist/components/FormRenderer/helpers/canCYASubmit.test.js +155 -0
  27. package/dist/components/FormRenderer/helpers/getCYA.js +31 -0
  28. package/dist/components/FormRenderer/helpers/getCYA.test.js +38 -0
  29. package/dist/components/FormRenderer/helpers/getFormState.js +32 -0
  30. package/dist/components/FormRenderer/helpers/getFormState.test.js +61 -0
  31. package/dist/components/FormRenderer/helpers/getNextPageId.js +65 -0
  32. package/dist/components/FormRenderer/helpers/getNextPageId.test.js +90 -0
  33. package/dist/components/FormRenderer/helpers/getPage.js +34 -0
  34. package/dist/components/FormRenderer/helpers/getPage.test.js +46 -0
  35. package/dist/components/FormRenderer/helpers/index.js +27 -0
  36. package/dist/components/PageActions/ActionButton.js +58 -0
  37. package/dist/components/PageActions/ActionButton.test.js +116 -0
  38. package/dist/components/PageActions/PageActions.js +18 -25
  39. package/dist/components/PageActions/PageActions.stories.mdx +74 -0
  40. package/dist/components/PageActions/PageActions.test.js +157 -0
  41. package/dist/components/SummaryList/RowAction.js +13 -22
  42. package/dist/components/SummaryList/RowAction.test.js +94 -0
  43. package/dist/components/SummaryList/SummaryList.js +6 -20
  44. package/dist/components/SummaryList/SummaryList.scss +7 -0
  45. package/dist/components/SummaryList/SummaryList.stories.mdx +36 -0
  46. package/dist/components/SummaryList/SummaryList.test.js +197 -0
  47. package/dist/components/SummaryList/helpers/getRowActionAttributes.js +27 -0
  48. package/dist/components/SummaryList/helpers/getRowActionAttributes.test.js +77 -0
  49. package/dist/components/SummaryList/helpers/index.js +15 -0
  50. package/dist/components/index.js +8 -0
  51. package/dist/hooks/useGetRequest.js +16 -1
  52. package/dist/hooks/useHooks.js +16 -5
  53. package/dist/index.js +3 -1
  54. package/dist/models/EventTypes.js +14 -0
  55. package/dist/models/FormPages.js +14 -0
  56. package/dist/models/PageAction.js +40 -0
  57. package/dist/models/index.js +24 -0
  58. package/dist/utils/CheckYourAnswers/getCYAAction.js +9 -0
  59. package/dist/utils/CheckYourAnswers/getCYARow.js +10 -0
  60. package/dist/utils/CheckYourAnswers/getCYARowsForPage.js +9 -0
  61. package/dist/utils/CheckYourAnswers/showComponentCYA.js +6 -5
  62. package/dist/utils/Component/getComponent.js +2 -2
  63. package/dist/utils/Component/getComponent.test.js +1 -1
  64. package/dist/utils/Data/setupFormData.js +3 -3
  65. package/dist/utils/Data/setupFormData.test.js +6 -6
  66. package/dist/utils/Data/setupRefDataUrlForComponent.test.js +4 -4
  67. package/dist/utils/FormPage/getFormPage.js +12 -1
  68. package/dist/utils/FormPage/getFormPage.test.js +178 -0
  69. package/dist/utils/FormPage/getFormPages.js +11 -6
  70. package/dist/utils/FormPage/getFormPages.test.js +95 -0
  71. package/dist/utils/FormPage/getParagraphFromText.js +6 -0
  72. package/dist/utils/FormPage/getParagraphFromText.test.js +29 -0
  73. package/dist/utils/FormPage/useComponent.js +9 -2
  74. package/dist/utils/FormPage/useComponent.test.js +82 -0
  75. package/dist/utils/Format/formatData.js +32 -0
  76. package/dist/utils/Format/formatData.test.js +46 -0
  77. package/dist/utils/Format/formatDataForComponent.js +41 -0
  78. package/dist/utils/Format/formatDataForComponent.test.js +161 -0
  79. package/dist/utils/Format/formatDataForForm.js +33 -0
  80. package/dist/utils/Format/formatDataForForm.test.js +78 -0
  81. package/dist/utils/Format/formatDataForPage.js +37 -0
  82. package/dist/utils/Format/formatDataForPage.test.js +96 -0
  83. package/dist/utils/Format/index.js +26 -0
  84. package/dist/utils/Hub/getFormHub.js +18 -4
  85. package/dist/utils/Hub/getFormHub.test.js +96 -0
  86. package/dist/utils/Hub/index.js +0 -3
  87. package/dist/utils/Validate/validatePage.test.js +1 -1
  88. package/dist/utils/index.js +3 -0
  89. package/package.json +13 -9
  90. package/dist/components/FormRenderer/helpers.js +0 -66
  91. package/dist/components/FormRenderer/helpers.test.js +0 -158
@@ -0,0 +1,90 @@
1
+ <!-- Global imports -->
2
+ import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
3
+ import { Details, Heading, Link } from '@ukhomeoffice/cop-react-components';
4
+ import withMock from 'storybook-addon-mock';
5
+
6
+ <!-- Local imports -->
7
+ import { addHook } from '../../hooks/useHooks';
8
+ import FormRenderer from './FormRenderer';
9
+
10
+ <!-- JSON documents -->
11
+ import CIVIL_SERVANT from '../../json/areYouACivilServant.json';
12
+ import GRADE from '../../json/grade.json';
13
+ import TEAMS from '../../json/team.json';
14
+ import USER_PROFILE_DATA from '../../json/userProfile.data.json';
15
+ import USER_PROFILE from '../../json/userProfile.json';
16
+ import SAVE_AND_CONTINUE from '../../json/saveAndContinue.json';
17
+
18
+ <Meta title="Components/Form renderer" id="D-FormRenderer" component={ FormRenderer } decorators={[withMock]} />
19
+
20
+ <Heading size="xl" caption="Components">Form renderer</Heading>
21
+
22
+ Renders a form with <Link href="https://ukhomeoffice.github.io/cop-react-components/?path=/docs/d-alert--default-story">COP React components</Link>,
23
+ on the basis of a <Link href="/?path=/docs/f-json-form">JSON</Link> that describes which elements are required.
24
+
25
+ <Canvas withToolbar>
26
+ <Story name="Default" parameters={{
27
+ mockData: [
28
+ {
29
+ url: `${USER_PROFILE_DATA.urls.refData}/areYouACivilServant`,
30
+ method: 'GET',
31
+ status: 200,
32
+ response: CIVIL_SERVANT
33
+ },
34
+ {
35
+ url: `${USER_PROFILE_DATA.urls.refData}/grade`,
36
+ method: 'GET',
37
+ status: 200,
38
+ response: GRADE
39
+ },
40
+ {
41
+ url: `${USER_PROFILE_DATA.urls.refData}/team`,
42
+ method: 'GET',
43
+ status: 200,
44
+ response: TEAMS
45
+ }
46
+ ]
47
+ }}>
48
+ {() => {
49
+ return (
50
+ <FormRenderer {...USER_PROFILE} data={USER_PROFILE_DATA} />
51
+ );
52
+ }}
53
+ </Story>
54
+ </Canvas>
55
+
56
+ <Details summary="Properties" className="no-indent">
57
+ <ArgsTable of={ FormRenderer } />
58
+ </Details>
59
+
60
+ ## Custom hooks
61
+
62
+ <Canvas>
63
+ <Story name="Save and continue">
64
+ {() => {
65
+ addHook('onRequest', (req) => {
66
+ // Do whatever you need to do to the request in here, such as adding an Authorization header.
67
+ console.log('onRequest hook called');
68
+ return req;
69
+ });
70
+ addHook('onFormLoad', () => {
71
+ console.log('onFormLoad called');
72
+ });
73
+ addHook('onPageChange', (pageId) => {
74
+ console.log('onPageChange called', pageId);
75
+ });
76
+
77
+ /**
78
+ * In whatever consumes this, do it as:
79
+ * intercepts.add('onSubmit', (...) => { ... })
80
+ */
81
+ addHook('onSubmit', (type, payload, onSuccess, onError) => {
82
+ console.log('onSubmit called of type', type, 'called, with the payload', payload);
83
+ onSuccess();
84
+ });
85
+ return (
86
+ <FormRenderer {...SAVE_AND_CONTINUE} data={{}} />
87
+ );
88
+ }}
89
+ </Story>
90
+ </Canvas>
@@ -0,0 +1,469 @@
1
+ "use strict";
2
+
3
+ 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); }
4
+
5
+ var _axios = _interopRequireDefault(require("axios"));
6
+
7
+ var _axiosMockAdapter = _interopRequireDefault(require("axios-mock-adapter"));
8
+
9
+ var _react = _interopRequireDefault(require("react"));
10
+
11
+ var _react2 = require("@testing-library/react");
12
+
13
+ var _reactDom = require("react-dom");
14
+
15
+ var _testUtils = require("react-dom/test-utils");
16
+
17
+ var _areYouACivilServant = _interopRequireDefault(require("../../json/areYouACivilServant.json"));
18
+
19
+ var _grade = _interopRequireDefault(require("../../json/grade.json"));
20
+
21
+ var _team = _interopRequireDefault(require("../../json/team.json"));
22
+
23
+ var _userProfileData = _interopRequireDefault(require("../../json/userProfile.data.json"));
24
+
25
+ var _userProfile = _interopRequireDefault(require("../../json/userProfile.json"));
26
+
27
+ var _FormRenderer = _interopRequireWildcard(require("./FormRenderer"));
28
+
29
+ var _CheckYourAnswers = require("../CheckYourAnswers/CheckYourAnswers");
30
+
31
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
32
+
33
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
34
+
35
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
36
+
37
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
38
+
39
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
40
+
41
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
42
+
43
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
44
+
45
+ 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."); }
46
+
47
+ 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); }
48
+
49
+ 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; }
50
+
51
+ 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; }
52
+
53
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
54
+
55
+ describe('components', function () {
56
+ describe('FormRenderer', function () {
57
+ var mockAxios = new _axiosMockAdapter.default(_axios.default);
58
+ var container = null;
59
+
60
+ var refDataUrl = function refDataUrl(suffix) {
61
+ return "".concat(_userProfileData.default.urls.refData, "/").concat(suffix);
62
+ };
63
+
64
+ beforeEach(function () {
65
+ container = document.createElement('div');
66
+ document.body.appendChild(container);
67
+ mockAxios.reset();
68
+ mockAxios.onGet(refDataUrl('areYouACivilServant')).reply(200, _areYouACivilServant.default);
69
+ mockAxios.onGet(refDataUrl('grade')).reply(200, _grade.default);
70
+ mockAxios.onGet(refDataUrl('team')).reply(200, _team.default);
71
+ });
72
+ afterEach(function () {
73
+ (0, _reactDom.unmountComponentAtNode)(container);
74
+ container.remove();
75
+ container = null;
76
+ });
77
+
78
+ var checkForm = function checkForm(container) {
79
+ var form = container.childNodes[0];
80
+ expect(form.tagName).toEqual('DIV');
81
+ expect(form.classList).toContain(_FormRenderer.DEFAULT_CLASS);
82
+ return form;
83
+ };
84
+
85
+ var getChangeLink = function getChangeLink(summaryList) {
86
+ var _summaryList$childNod = _slicedToArray(summaryList.childNodes[0].childNodes, 3),
87
+ actions = _summaryList$childNod[2];
88
+
89
+ return actions.childNodes[0];
90
+ };
91
+
92
+ var getContinueButton = function getContinueButton(page) {
93
+ return page.childNodes[page.childNodes.length - 1].childNodes[0].childNodes[0];
94
+ };
95
+
96
+ it('should start on the hub page correctly and display the title', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
97
+ var form, title, hub;
98
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
99
+ while (1) {
100
+ switch (_context2.prev = _context2.next) {
101
+ case 0:
102
+ _context2.next = 2;
103
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
104
+ return regeneratorRuntime.wrap(function _callee$(_context) {
105
+ while (1) {
106
+ switch (_context.prev = _context.next) {
107
+ case 0:
108
+ (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
109
+ data: _userProfileData.default
110
+ })), container);
111
+
112
+ case 1:
113
+ case "end":
114
+ return _context.stop();
115
+ }
116
+ }
117
+ }, _callee);
118
+ })));
119
+
120
+ case 2:
121
+ form = checkForm(container);
122
+ expect(form.childNodes.length).toEqual(2); // Title + Hub page (= CYA)
123
+
124
+ title = form.childNodes[0];
125
+ expect(title.tagName).toEqual('H1');
126
+ expect(title.textContent).toEqual(_userProfile.default.title);
127
+ hub = form.childNodes[1];
128
+ expect(hub.tagName).toEqual('DIV');
129
+ expect(hub.classList).toContain(_CheckYourAnswers.DEFAULT_CLASS);
130
+
131
+ case 10:
132
+ case "end":
133
+ return _context2.stop();
134
+ }
135
+ }
136
+ }, _callee2);
137
+ })));
138
+ it('should fire the onFormLoad method passed in the hooks', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
139
+ var onFormLoadCalled, ON_FORM_LOAD, HOOKS;
140
+ return regeneratorRuntime.wrap(function _callee4$(_context4) {
141
+ while (1) {
142
+ switch (_context4.prev = _context4.next) {
143
+ case 0:
144
+ onFormLoadCalled = false;
145
+
146
+ ON_FORM_LOAD = function ON_FORM_LOAD() {
147
+ onFormLoadCalled = true;
148
+ };
149
+
150
+ HOOKS = {
151
+ onFormLoad: ON_FORM_LOAD
152
+ };
153
+ _context4.next = 5;
154
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
155
+ return regeneratorRuntime.wrap(function _callee3$(_context3) {
156
+ while (1) {
157
+ switch (_context3.prev = _context3.next) {
158
+ case 0:
159
+ (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
160
+ data: _userProfileData.default,
161
+ hooks: HOOKS
162
+ })), container);
163
+
164
+ case 1:
165
+ case "end":
166
+ return _context3.stop();
167
+ }
168
+ }
169
+ }, _callee3);
170
+ })));
171
+
172
+ case 5:
173
+ expect(onFormLoadCalled).toBeTruthy();
174
+
175
+ case 6:
176
+ case "end":
177
+ return _context4.stop();
178
+ }
179
+ }
180
+ }, _callee4);
181
+ })));
182
+ it('should navigate to the first editable page', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {
183
+ var ON_PAGE_CHANGE_CALLS, ON_PAGE_CHANGE, HOOKS, form, hub, _hub$childNodes, civilServantList, link, page, pageHeading;
184
+
185
+ return regeneratorRuntime.wrap(function _callee6$(_context6) {
186
+ while (1) {
187
+ switch (_context6.prev = _context6.next) {
188
+ case 0:
189
+ ON_PAGE_CHANGE_CALLS = [];
190
+
191
+ ON_PAGE_CHANGE = function ON_PAGE_CHANGE(pageId) {
192
+ ON_PAGE_CHANGE_CALLS.push(pageId);
193
+ };
194
+
195
+ HOOKS = {
196
+ onPageChange: ON_PAGE_CHANGE
197
+ };
198
+ _context6.next = 5;
199
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {
200
+ return regeneratorRuntime.wrap(function _callee5$(_context5) {
201
+ while (1) {
202
+ switch (_context5.prev = _context5.next) {
203
+ case 0:
204
+ (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
205
+ data: _userProfileData.default,
206
+ hooks: HOOKS
207
+ })), container);
208
+
209
+ case 1:
210
+ case "end":
211
+ return _context5.stop();
212
+ }
213
+ }
214
+ }, _callee5);
215
+ })));
216
+
217
+ case 5:
218
+ form = checkForm(container);
219
+ hub = form.childNodes[1]; // Hub = CYA
220
+
221
+ _hub$childNodes = _slicedToArray(hub.childNodes, 3), civilServantList = _hub$childNodes[2];
222
+ link = getChangeLink(civilServantList);
223
+ expect(ON_PAGE_CHANGE_CALLS.length).toEqual(0);
224
+
225
+ _react2.fireEvent.click(link, {});
226
+
227
+ expect(ON_PAGE_CHANGE_CALLS.length).toEqual(1);
228
+ expect(ON_PAGE_CHANGE_CALLS[0]).toEqual(_userProfile.default.pages[1].id); // The form layout should have changed to the current page.
229
+
230
+ expect(form.childNodes.length).toEqual(1); // Just the page.
231
+
232
+ page = form.childNodes[0];
233
+ pageHeading = page.childNodes[0];
234
+ expect(pageHeading.tagName).toEqual('H1');
235
+ expect(pageHeading.textContent).toEqual(_userProfile.default.pages[1].title);
236
+
237
+ case 18:
238
+ case "end":
239
+ return _context6.stop();
240
+ }
241
+ }
242
+ }, _callee6);
243
+ })));
244
+ it('should handle a page submission', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8() {
245
+ var ON_SUBMIT_CALLS, ON_SUBMIT, HOOKS, form, hub, _hub$childNodes2, civilServantList, link, page, continueButton, title;
246
+
247
+ return regeneratorRuntime.wrap(function _callee8$(_context8) {
248
+ while (1) {
249
+ switch (_context8.prev = _context8.next) {
250
+ case 0:
251
+ ON_SUBMIT_CALLS = [];
252
+
253
+ ON_SUBMIT = function ON_SUBMIT(type, payload, onSuccess, onError) {
254
+ ON_SUBMIT_CALLS.push({
255
+ type: type,
256
+ payload: payload,
257
+ onSuccess: onSuccess,
258
+ onError: onError
259
+ });
260
+ onSuccess();
261
+ };
262
+
263
+ HOOKS = {
264
+ onSubmit: ON_SUBMIT
265
+ };
266
+ _context8.next = 5;
267
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7() {
268
+ return regeneratorRuntime.wrap(function _callee7$(_context7) {
269
+ while (1) {
270
+ switch (_context7.prev = _context7.next) {
271
+ case 0:
272
+ (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
273
+ data: _userProfileData.default,
274
+ hooks: HOOKS
275
+ })), container);
276
+
277
+ case 1:
278
+ case "end":
279
+ return _context7.stop();
280
+ }
281
+ }
282
+ }, _callee7);
283
+ })));
284
+
285
+ case 5:
286
+ form = checkForm(container); // Navigate to the "Are you a civil servant?" page.
287
+
288
+ hub = form.childNodes[1]; // Hub = CYA
289
+
290
+ _hub$childNodes2 = _slicedToArray(hub.childNodes, 3), civilServantList = _hub$childNodes2[2];
291
+ link = getChangeLink(civilServantList);
292
+
293
+ _react2.fireEvent.click(link, {}); // Should already be answered "Yes", so simply click "Continue".
294
+
295
+
296
+ page = form.childNodes[0];
297
+ continueButton = getContinueButton(page);
298
+ expect(ON_SUBMIT_CALLS.length).toEqual(0);
299
+
300
+ _react2.fireEvent.click(continueButton, {});
301
+
302
+ expect(ON_SUBMIT_CALLS.length).toEqual(1);
303
+ expect(ON_SUBMIT_CALLS[0].type).toEqual('submit');
304
+ expect(ON_SUBMIT_CALLS[0].payload.areYouACivilServant).toEqual('yes'); // And we should be back on the hub.
305
+
306
+ expect(form.childNodes.length).toEqual(2); // Title + Hub page (= CYA)
307
+
308
+ title = form.childNodes[0];
309
+ expect(title.tagName).toEqual('H1');
310
+ expect(title.textContent).toEqual(_userProfile.default.title);
311
+
312
+ case 21:
313
+ case "end":
314
+ return _context8.stop();
315
+ }
316
+ }
317
+ }, _callee8);
318
+ })));
319
+ it('should handle a page submission error', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee10() {
320
+ var ON_SUBMIT_CALLS, ON_SUBMIT, HOOKS, form, hub, _hub$childNodes3, civilServantList, link, page, continueButton, pageHeading;
321
+
322
+ return regeneratorRuntime.wrap(function _callee10$(_context10) {
323
+ while (1) {
324
+ switch (_context10.prev = _context10.next) {
325
+ case 0:
326
+ ON_SUBMIT_CALLS = [];
327
+
328
+ ON_SUBMIT = function ON_SUBMIT(type, payload, onSuccess, onError) {
329
+ ON_SUBMIT_CALLS.push({
330
+ type: type,
331
+ payload: payload,
332
+ onSuccess: onSuccess,
333
+ onError: onError
334
+ });
335
+ onError([{
336
+ id: 'unknown',
337
+ error: 'Something went wrong'
338
+ }]);
339
+ };
340
+
341
+ HOOKS = {
342
+ onSubmit: ON_SUBMIT
343
+ };
344
+ _context10.next = 5;
345
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee9() {
346
+ return regeneratorRuntime.wrap(function _callee9$(_context9) {
347
+ while (1) {
348
+ switch (_context9.prev = _context9.next) {
349
+ case 0:
350
+ (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
351
+ data: _userProfileData.default,
352
+ hooks: HOOKS
353
+ })), container);
354
+
355
+ case 1:
356
+ case "end":
357
+ return _context9.stop();
358
+ }
359
+ }
360
+ }, _callee9);
361
+ })));
362
+
363
+ case 5:
364
+ form = checkForm(container); // Navigate to the "Are you a civil servant?" page.
365
+
366
+ hub = form.childNodes[1]; // Hub = CYA
367
+
368
+ _hub$childNodes3 = _slicedToArray(hub.childNodes, 3), civilServantList = _hub$childNodes3[2];
369
+ link = getChangeLink(civilServantList);
370
+
371
+ _react2.fireEvent.click(link, {}); // Should already be answered "Yes", so simply click "Continue".
372
+
373
+
374
+ page = form.childNodes[0];
375
+ continueButton = getContinueButton(page);
376
+ expect(ON_SUBMIT_CALLS.length).toEqual(0);
377
+
378
+ _react2.fireEvent.click(continueButton, {});
379
+
380
+ expect(ON_SUBMIT_CALLS.length).toEqual(1);
381
+ expect(ON_SUBMIT_CALLS[0].type).toEqual('submit');
382
+ expect(ON_SUBMIT_CALLS[0].payload.areYouACivilServant).toEqual('yes'); // And we should be kept on the same page.
383
+
384
+ expect(form.childNodes.length).toEqual(1); // Just the page.
385
+
386
+ pageHeading = form.childNodes[0].childNodes[0];
387
+ expect(pageHeading.tagName).toEqual('H1');
388
+ expect(pageHeading.textContent).toEqual(_userProfile.default.pages[1].title);
389
+
390
+ case 21:
391
+ case "end":
392
+ return _context10.stop();
393
+ }
394
+ }
395
+ }, _callee10);
396
+ })));
397
+ it('should handle page navigation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee12() {
398
+ var ON_PAGE_CHANGE_CALLS, ON_PAGE_CHANGE, HOOKS, form, hub, _hub$childNodes4, lineManagerList, link, page, pageHeading, continueButton, newPageHeading;
399
+
400
+ return regeneratorRuntime.wrap(function _callee12$(_context12) {
401
+ while (1) {
402
+ switch (_context12.prev = _context12.next) {
403
+ case 0:
404
+ ON_PAGE_CHANGE_CALLS = [];
405
+
406
+ ON_PAGE_CHANGE = function ON_PAGE_CHANGE(pageId) {
407
+ ON_PAGE_CHANGE_CALLS.push(pageId);
408
+ };
409
+
410
+ HOOKS = {
411
+ onPageChange: ON_PAGE_CHANGE
412
+ };
413
+ _context12.next = 5;
414
+ return (0, _testUtils.act)( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee11() {
415
+ return regeneratorRuntime.wrap(function _callee11$(_context11) {
416
+ while (1) {
417
+ switch (_context11.prev = _context11.next) {
418
+ case 0:
419
+ (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(_FormRenderer.default, _extends({}, _userProfile.default, {
420
+ data: _userProfileData.default,
421
+ hooks: HOOKS
422
+ })), container);
423
+
424
+ case 1:
425
+ case "end":
426
+ return _context11.stop();
427
+ }
428
+ }
429
+ }, _callee11);
430
+ })));
431
+
432
+ case 5:
433
+ form = checkForm(container); // Navigate to the "Add or change a line manager" page.
434
+
435
+ hub = form.childNodes[1]; // Hub = CYA
436
+
437
+ _hub$childNodes4 = _slicedToArray(hub.childNodes, 6), lineManagerList = _hub$childNodes4[5];
438
+ link = getChangeLink(lineManagerList);
439
+ expect(ON_PAGE_CHANGE_CALLS.length).toEqual(0);
440
+
441
+ _react2.fireEvent.click(link, {});
442
+
443
+ expect(ON_PAGE_CHANGE_CALLS[0]).toEqual(_userProfile.default.pages[4].id); // Should be on the page explaining what changing the line manager means.
444
+
445
+ page = form.childNodes[0];
446
+ pageHeading = page.childNodes[0];
447
+ expect(pageHeading.tagName).toEqual('H1');
448
+ expect(pageHeading.textContent).toEqual(_userProfile.default.pages[4].title); // Now click on the "Continue" button on here.
449
+
450
+ continueButton = getContinueButton(page);
451
+ expect(ON_PAGE_CHANGE_CALLS.length).toEqual(1);
452
+
453
+ _react2.fireEvent.click(continueButton, {});
454
+
455
+ expect(ON_PAGE_CHANGE_CALLS.length).toEqual(2);
456
+ expect(ON_PAGE_CHANGE_CALLS[1]).toEqual(_userProfile.default.pages[5].id);
457
+ newPageHeading = form.childNodes[0].childNodes[0];
458
+ expect(newPageHeading.tagName).toEqual('H1');
459
+ expect(newPageHeading.textContent).toEqual(_userProfile.default.pages[5].title);
460
+
461
+ case 24:
462
+ case "end":
463
+ return _context12.stop();
464
+ }
465
+ }
466
+ }, _callee12);
467
+ })));
468
+ });
469
+ });
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _getPageId = _interopRequireDefault(require("./getPageId"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ /**
13
+ * Gets the pageId from the invoked CYA action and calls onChange if it is
14
+ * different to the currentPageId.
15
+ * @param {object} page The page on which the CYA action was invoked.
16
+ * @param {string} currentPageId The current pageId.
17
+ * @param {Function} onChange The handler to call if the pageId is different to the currentPageId.
18
+ */
19
+ var cyaAction = function cyaAction(page, currentPageId, onChange) {
20
+ var pageId = (0, _getPageId.default)(page.action, page.pageId);
21
+
22
+ if (pageId !== currentPageId) {
23
+ onChange(pageId);
24
+ }
25
+ };
26
+
27
+ var _default = cyaAction;
28
+ exports.default = _default;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ /**
9
+ * Gets the pageId from the invoked CYA action.
10
+ * @param {object} action The invoked action.
11
+ * @param {string} pageId The id of the page on which the action was invoked.
12
+ * @returns A page id.
13
+ */
14
+ var getPageId = function getPageId(action, pageId) {
15
+ if (action) {
16
+ // TODO: Improve how this is handled.
17
+ if (action.href) {
18
+ return action.href.split('/').pop();
19
+ } else if (action.url) {
20
+ return action.url.split('/').pop();
21
+ }
22
+ }
23
+
24
+ return pageId;
25
+ };
26
+
27
+ var _default = getPageId;
28
+ exports.default = _default;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ var _getPageId = _interopRequireDefault(require("./getPageId"));
4
+
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+
7
+ // Local imports
8
+ describe('components', function () {
9
+ describe('FormRenderer', function () {
10
+ describe('handlers', function () {
11
+ describe('getPageId', function () {
12
+ it('should return the pageId when the action is null', function () {
13
+ var PAGE_ID = 'alpha';
14
+ var ACTION = null;
15
+ expect((0, _getPageId.default)(ACTION, PAGE_ID)).toEqual(PAGE_ID);
16
+ });
17
+ it('should return the pageId when the action contains no href or url', function () {
18
+ var PAGE_ID = 'alpha';
19
+ var ACTION = {
20
+ id: 'bravo'
21
+ };
22
+ expect((0, _getPageId.default)(ACTION, PAGE_ID)).toEqual(PAGE_ID);
23
+ });
24
+ it('should return the final part of the href when provided', function () {
25
+ var LAST_PART = 'delta';
26
+ var HREF = "/bravo/charlie/".concat(LAST_PART);
27
+ var PAGE_ID = 'alpha';
28
+ var ACTION = {
29
+ href: HREF
30
+ };
31
+ expect((0, _getPageId.default)(ACTION, PAGE_ID)).toEqual(LAST_PART);
32
+ });
33
+ it('should return the final part of the url when provided', function () {
34
+ var LAST_PART = 'delta';
35
+ var URL = "/bravo/charlie/".concat(LAST_PART);
36
+ var PAGE_ID = 'alpha';
37
+ var ACTION = {
38
+ url: URL
39
+ };
40
+ expect((0, _getPageId.default)(ACTION, PAGE_ID)).toEqual(LAST_PART);
41
+ });
42
+ it('should return the whole href when it contains no backslashes', function () {
43
+ var HREF = 'delta';
44
+ var PAGE_ID = 'alpha';
45
+ var ACTION = {
46
+ href: HREF
47
+ };
48
+ expect((0, _getPageId.default)(ACTION, PAGE_ID)).toEqual(HREF);
49
+ });
50
+ it('should return the whole url when it contains no backslashes', function () {
51
+ var URL = 'delta';
52
+ var PAGE_ID = 'alpha';
53
+ var ACTION = {
54
+ url: URL
55
+ };
56
+ expect((0, _getPageId.default)(ACTION, PAGE_ID)).toEqual(URL);
57
+ });
58
+ });
59
+ });
60
+ });
61
+ });