@planning-inspectorate/dynamic-forms 1.14.0 → 1.14.1

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 (45) hide show
  1. package/.prettierignore +2 -1
  2. package/README.md +9 -1
  3. package/package.json +7 -2
  4. package/src/components/address/question.js +1 -1
  5. package/src/components/address/question.test.js +3 -3
  6. package/src/components/multi-field-input/index.njk +2 -2
  7. package/src/components/multi-field-input/question.js +5 -1
  8. package/src/components/radio/index.njk +2 -2
  9. package/src/components/text-entry-redact/question.test.js +9 -9
  10. package/src/controller.test.js +2 -1
  11. package/src/index.js +8 -2
  12. package/src/lib/session-answer-store.test.js +1 -1
  13. package/src/questions/question-props.d.ts +5 -24
  14. package/src/questions/question.test.js +1 -1
  15. package/src/section.js +3 -0
  16. package/src/validator/validator.js +4 -1
  17. package/test/check-your-answers.test.js +69 -0
  18. package/test/journey.js +41 -0
  19. package/test/journey.test.js +21 -0
  20. package/test/questions.js +189 -0
  21. package/test/questions.test.js +246 -0
  22. package/test/snapshots/add-insurance.html +44 -0
  23. package/test/snapshots/check-your-answers-not-started.html +201 -0
  24. package/test/snapshots/check-your-answers-with-answers.html +201 -0
  25. package/test/snapshots/companions.html +51 -0
  26. package/test/snapshots/departure-date.html +57 -0
  27. package/test/snapshots/holiday-activities.html +49 -0
  28. package/test/snapshots/holiday-arrival.html +101 -0
  29. package/test/snapshots/holiday-description.html +33 -0
  30. package/test/snapshots/holiday-destination.html +56 -0
  31. package/test/snapshots/holiday-period.html +102 -0
  32. package/test/snapshots/holiday-snack.html +33 -0
  33. package/test/snapshots/hotel-address.html +65 -0
  34. package/test/snapshots/luggage-weight-units.html +75 -0
  35. package/test/snapshots/nights.html +28 -0
  36. package/test/snapshots/secret-wish.html +173 -0
  37. package/test/snapshots/travel-class.html +52 -0
  38. package/test/snapshots/travel-insurance-type.html +56 -0
  39. package/test/utils/app.js +41 -0
  40. package/test/utils/nunjucks.js +20 -0
  41. package/test/utils/test-server.js +167 -0
  42. package/test/utils/test-server.test.js +75 -0
  43. package/{src/lib/test-utils.js → test/utils/utils.js} +15 -16
  44. package/test/views/layout-check-your-answers.njk +1 -0
  45. /package/{src/lib/test-layout.njk → test/views/layout-question.njk} +0 -0
@@ -0,0 +1,246 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'assert';
3
+ import { createApp } from './utils/app.js';
4
+ import { TestServer } from './utils/test-server.js';
5
+ import { getQuestions, questionsInOrder } from './questions.js';
6
+ import { buildGetJourney } from '../src/middleware/build-get-journey.js';
7
+ import { createJourney, JOURNEY_ID } from './journey.js';
8
+ import { buildGetJourneyResponseFromSession, saveDataToSession } from '../src/lib/session-answer-store.js';
9
+ import validate from '../src/validator/validator.js';
10
+ import { validationErrorHandler } from '../src/validator/validation-error-handler.js';
11
+ import { buildSave, list, question } from '../src/controller.js';
12
+ import path from 'path';
13
+ import { COMPONENT_TYPES } from '../src/index.js';
14
+ import { escapeForRegExp, snapshotsDir } from './utils/utils.js';
15
+ import { BOOLEAN_OPTIONS } from '../src/components/boolean/question.js';
16
+
17
+ /**
18
+ * @param {import('node:test').TestContext} ctx
19
+ * @returns {Promise<TestServer>}
20
+ */
21
+ export async function createAppWithQuestions(ctx) {
22
+ const app = createApp();
23
+ const questions = getQuestions();
24
+ const getJourney = buildGetJourney((req, journeyResponse) => createJourney(questions, journeyResponse));
25
+ const getJourneyResponse = buildGetJourneyResponseFromSession(JOURNEY_ID);
26
+
27
+ // app.use((req, res, next) => {
28
+ // console.log(req.method, req.url, req.session);
29
+ // next();
30
+ // });
31
+
32
+ app.get('/:section/:question', getJourneyResponse, getJourney, question);
33
+
34
+ app.post(
35
+ '/:section/:question',
36
+ getJourneyResponse,
37
+ getJourney,
38
+ validate,
39
+ validationErrorHandler,
40
+ buildSave(saveDataToSession)
41
+ );
42
+
43
+ app.get('/check-your-answers', getJourneyResponse, getJourney, (req, res) => list(req, res, '', {}));
44
+
45
+ app.use((error, req, res, next) => {
46
+ if (error) {
47
+ console.error('Internal Server Error:', error);
48
+ }
49
+ next();
50
+ });
51
+
52
+ app.use((req, res) => {
53
+ res.status(404);
54
+ });
55
+
56
+ const server = new TestServer(app, { rememberCookies: true });
57
+ await server.start();
58
+ ctx.after(async () => await server.stop());
59
+ return server;
60
+ }
61
+
62
+ describe('question pages', () => {
63
+ it('should have a test for each question type', () => {
64
+ const questionsByType = new Map();
65
+ for (const q of questionsInOrder) {
66
+ if (!questionsByType.has(q.type)) {
67
+ questionsByType.set(q.type, []);
68
+ }
69
+ questionsByType.get(q.type).push(q);
70
+ }
71
+ for (const [k, v] of Object.entries(COMPONENT_TYPES)) {
72
+ const questions = questionsByType.get(v);
73
+ if (!questions || questions.length === 0) {
74
+ throw new Error(`no test questions for ${k}`);
75
+ }
76
+ }
77
+ });
78
+
79
+ for (let i = 0; i < questionsInOrder.length; i++) {
80
+ const q = questionsInOrder[i];
81
+
82
+ it(`should render question: ${q.url}`, async (ctx) => {
83
+ const testServer = await createAppWithQuestions(ctx);
84
+
85
+ const response = await testServer.get('/questions/' + q.url, {
86
+ redirect: 'manual'
87
+ });
88
+ assert.strictEqual(response.status, 200);
89
+ const text = await response.text();
90
+ // be sure to escape parentheses in the question text for the regex
91
+ assert.match(text, new RegExp(escapeForRegExp(q.question), 'i'));
92
+ assert.match(text, /<form action="" method="post"/i);
93
+ if (q.options) {
94
+ for (const option of q.options) {
95
+ if (q.type === COMPONENT_TYPES.SELECT) {
96
+ assert.match(
97
+ text,
98
+ new RegExp(`<option[^>]*value="${option.value}"[^>]*>\\s*${option.text}\\s*</option>`, 'i')
99
+ );
100
+ } else {
101
+ assert.match(text, new RegExp(`<input[^>]*value="${option.value}"[^>]*>`));
102
+ assert.match(text, new RegExp(`<label[^>]*>\\s*${option.text}\\s*</label>`, 'i'));
103
+ }
104
+ }
105
+ }
106
+ ctx.assert.fileSnapshot(text, path.join(snapshotsDir(), q.url + '.html'), {
107
+ serializers: [(v) => v]
108
+ });
109
+ });
110
+
111
+ it(`should POST valid data for question: ${q.url} and redirect to next`, async (ctx) => {
112
+ const testServer = await createAppWithQuestions(ctx);
113
+ const payload = mockAnswerBody(q);
114
+ const response = await testServer.post(`/questions/${q.url}`, payload, { redirect: 'manual' });
115
+ if (![302, 303].includes(response.status)) {
116
+ const text = await response.text();
117
+ console.log(`Response for ${q.url}:\n`, text);
118
+ }
119
+ // Should redirect (302 or 303)
120
+ assert.ok([302, 303].includes(response.status), `Expected redirect, got ${response.status}`);
121
+ // Should redirect to the next question (if there is one)
122
+ const location = response.headers.get('location');
123
+ const nextQ = questionsInOrder[i + 1];
124
+ if (nextQ) {
125
+ assert.strictEqual(location, `questions/${nextQ.url}`);
126
+ } else {
127
+ assert.strictEqual(location, 'check-your-answers');
128
+ }
129
+ });
130
+ }
131
+ });
132
+
133
+ /**
134
+ * Build a valid payload for a question.
135
+ * @param {import('../src/questions/question-props.js').QuestionProps} q
136
+ * @returns {Object}
137
+ */
138
+ export function mockAnswerBody(q) {
139
+ switch (q.type) {
140
+ case COMPONENT_TYPES.BOOLEAN:
141
+ return { [q.fieldName]: BOOLEAN_OPTIONS.YES };
142
+ case COMPONENT_TYPES.CHECKBOX:
143
+ return { [q.fieldName]: [q.options[0].value] };
144
+ case COMPONENT_TYPES.RADIO:
145
+ case COMPONENT_TYPES.SELECT:
146
+ return { [q.fieldName]: q.options[0].value };
147
+ case COMPONENT_TYPES.NUMBER:
148
+ return { [q.fieldName]: 1 };
149
+ case COMPONENT_TYPES.DATE:
150
+ return {
151
+ [q.fieldName + '_day']: 1,
152
+ [q.fieldName + '_month']: 1,
153
+ [q.fieldName + '_year']: 2025
154
+ };
155
+ case COMPONENT_TYPES.DATE_PERIOD:
156
+ return {
157
+ [q.fieldName + '_start_day']: 1,
158
+ [q.fieldName + '_start_month']: 1,
159
+ [q.fieldName + '_start_year']: 2025,
160
+ [q.fieldName + '_end_day']: 2,
161
+ [q.fieldName + '_end_month']: 1,
162
+ [q.fieldName + '_end_year']: 2025
163
+ };
164
+ case COMPONENT_TYPES.DATE_TIME:
165
+ return {
166
+ [q.fieldName + '_day']: 1,
167
+ [q.fieldName + '_month']: 1,
168
+ [q.fieldName + '_year']: 2025,
169
+ [q.fieldName + '_hour']: 10,
170
+ [q.fieldName + '_minutes']: 45,
171
+ [q.fieldName + '_period']: 'am'
172
+ };
173
+ case COMPONENT_TYPES.TEXT_ENTRY:
174
+ case COMPONENT_TYPES.SINGLE_LINE_INPUT:
175
+ return { [q.fieldName]: 'test' };
176
+ case COMPONENT_TYPES.TEXT_ENTRY_REDACT:
177
+ return { [q.fieldName]: 'secret' };
178
+ case COMPONENT_TYPES.MULTI_FIELD_INPUT: {
179
+ const res = {};
180
+ for (const field of q.inputFields) {
181
+ res[field.fieldName] = mockAnswer(field);
182
+ }
183
+ return res;
184
+ }
185
+ case COMPONENT_TYPES.ADDRESS:
186
+ return {
187
+ [q.fieldName + '_addressLine1']: '1 Test St',
188
+ [q.fieldName + '_townCity']: 'Testville',
189
+ [q.fieldName + '_postcode']: 'TE5 5ST'
190
+ };
191
+ case COMPONENT_TYPES.UNIT_OPTION:
192
+ return {
193
+ [q.fieldName]: 'kg',
194
+ [q.options[0].conditional.fieldName]: 10
195
+ };
196
+ default:
197
+ return { [q.fieldName]: 'test' };
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Build a valid & formatted answer for a question.
203
+ * @param {import('../src/questions/question-props.js').QuestionProps} q
204
+ * @returns {Object}
205
+ */
206
+ export function mockAnswer(q) {
207
+ switch (q.type) {
208
+ case COMPONENT_TYPES.BOOLEAN:
209
+ return BOOLEAN_OPTIONS.YES;
210
+ case COMPONENT_TYPES.CHECKBOX:
211
+ return q.options[0].text;
212
+ case COMPONENT_TYPES.RADIO:
213
+ case COMPONENT_TYPES.SELECT:
214
+ return q.options[0].text;
215
+ case COMPONENT_TYPES.NUMBER:
216
+ return 1;
217
+ case COMPONENT_TYPES.DATE:
218
+ return '1 January 2025';
219
+ case COMPONENT_TYPES.DATE_PERIOD:
220
+ return 'Start: 00:00 1 January 2025<br>End: 00:00 2 January 2025';
221
+ case COMPONENT_TYPES.DATE_TIME:
222
+ return '1 January 2025<br>10:45am';
223
+ case COMPONENT_TYPES.TEXT_ENTRY:
224
+ case COMPONENT_TYPES.SINGLE_LINE_INPUT:
225
+ return 'test';
226
+ case COMPONENT_TYPES.TEXT_ENTRY_REDACT:
227
+ return 'secret';
228
+ case COMPONENT_TYPES.MULTI_FIELD_INPUT:
229
+ if (q.inputFields) {
230
+ let res = '';
231
+ for (const field of q.inputFields) {
232
+ res += mockAnswer(field) + '<br>';
233
+ }
234
+ return res;
235
+ }
236
+ break;
237
+ case COMPONENT_TYPES.ADDRESS: {
238
+ const answer = mockAnswerBody(q);
239
+ return Object.values(answer).filter(Boolean).join('<br>');
240
+ }
241
+ case COMPONENT_TYPES.UNIT_OPTION:
242
+ return '10 kg';
243
+ default:
244
+ return 'test';
245
+ }
246
+ }
@@ -0,0 +1,44 @@
1
+ <div class="govuk-grid-row">
2
+ <div class="govuk-grid-column-two-thirds">
3
+ </div>
4
+ </div>
5
+
6
+
7
+ <div class="govuk-grid-row">
8
+ <div class="govuk-grid-column-two-thirds">
9
+ <form action="" method="post" novalidate>
10
+ <input type="hidden" name="_csrf" value="">
11
+ <div class="govuk-form-group">
12
+ <fieldset class="govuk-fieldset" aria-describedby="addInsurance-hint">
13
+ <legend class="govuk-fieldset__legend govuk-fieldset__legend--l">
14
+ <h1 class="govuk-fieldset__heading">
15
+ Do you want to add travel insurance to your holiday?
16
+ </h1>
17
+ </legend>
18
+ <div id="addInsurance-hint" class="govuk-hint">
19
+
20
+ </div>
21
+ <div class="govuk-radios govuk-radios" data-module="govuk-radios">
22
+ <div class="govuk-radios__item">
23
+ <input class="govuk-radios__input" id="addInsurance" name="addInsurance" type="radio" value="yes" data-cy="answer-yes">
24
+ <label class="govuk-label govuk-radios__label" for="addInsurance">
25
+ Yes
26
+ </label>
27
+ </div>
28
+ <div class="govuk-radios__item">
29
+ <input class="govuk-radios__input" id="addInsurance-2" name="addInsurance" type="radio" value="no" data-cy="answer-no">
30
+ <label class="govuk-label govuk-radios__label" for="addInsurance-2">
31
+ No
32
+ </label>
33
+ </div>
34
+ </div>
35
+ </fieldset>
36
+ </div>
37
+
38
+
39
+ <button type="submit" class="govuk-button" data-module="govuk-button" data-cy="button-save-and-continue">
40
+ Continue
41
+ </button>
42
+ </form>
43
+ </div>
44
+ </div>
@@ -0,0 +1,201 @@
1
+
2
+ <style >
3
+ .app-task-list {
4
+ padding-left: 0;
5
+ }
6
+ .app-task-list>li {
7
+ position: relative;
8
+ list-style-type: none;
9
+
10
+ }
11
+ .app-task-list__section .govuk-tag {
12
+ position: absolute;
13
+ top: 3px;
14
+ right: 0;
15
+ }
16
+ .app-task-list .govuk-summary-list {
17
+ border-top: 1px solid #b1b4b6;
18
+ }
19
+ </style>
20
+
21
+ <div class="govuk-grid-row">
22
+ <div class="govuk-grid-column-full">
23
+ <dl class="govuk-summary-list">
24
+ <div class="govuk-summary-list__row">
25
+ <dt class="govuk-summary-list__key">
26
+ Holiday Activities
27
+ </dt>
28
+ <dd class="govuk-summary-list__value">
29
+ Not started
30
+ </dd>
31
+ <dd class="govuk-summary-list__actions">
32
+ <a class="govuk-link" href="questions/holiday-activities">Answer<span class="govuk-visually-hidden"> Which activities do you want to do on holiday?</span></a>
33
+ </dd>
34
+ </div>
35
+ <div class="govuk-summary-list__row">
36
+ <dt class="govuk-summary-list__key">
37
+ Travel Insurance
38
+ </dt>
39
+ <dd class="govuk-summary-list__value">
40
+ Not started
41
+ </dd>
42
+ <dd class="govuk-summary-list__actions">
43
+ <a class="govuk-link" href="questions/add-insurance">Answer<span class="govuk-visually-hidden"> Do you want to add travel insurance to your holiday?</span></a>
44
+ </dd>
45
+ </div>
46
+ <div class="govuk-summary-list__row">
47
+ <dt class="govuk-summary-list__key">
48
+ Travel Insurance Type
49
+ </dt>
50
+ <dd class="govuk-summary-list__value">
51
+ Not started
52
+ </dd>
53
+ <dd class="govuk-summary-list__actions">
54
+ <a class="govuk-link" href="questions/travel-insurance-type">Answer<span class="govuk-visually-hidden"> Which type of travel insurance would you like?</span></a>
55
+ </dd>
56
+ </div>
57
+ <div class="govuk-summary-list__row">
58
+ <dt class="govuk-summary-list__key">
59
+ Holiday Destination
60
+ </dt>
61
+ <dd class="govuk-summary-list__value">
62
+ Not started
63
+ </dd>
64
+ <dd class="govuk-summary-list__actions">
65
+ <a class="govuk-link" href="questions/holiday-destination">Answer<span class="govuk-visually-hidden"> Where would you like to go on holiday?</span></a>
66
+ </dd>
67
+ </div>
68
+ <div class="govuk-summary-list__row">
69
+ <dt class="govuk-summary-list__key">
70
+ Departure Date
71
+ </dt>
72
+ <dd class="govuk-summary-list__value">
73
+ Not started
74
+ </dd>
75
+ <dd class="govuk-summary-list__actions">
76
+ <a class="govuk-link" href="questions/departure-date">Answer<span class="govuk-visually-hidden"> When do you want to start your holiday?</span></a>
77
+ </dd>
78
+ </div>
79
+ <div class="govuk-summary-list__row">
80
+ <dt class="govuk-summary-list__key">
81
+ Holiday Period
82
+ </dt>
83
+ <dd class="govuk-summary-list__value">
84
+ Not started
85
+ </dd>
86
+ <dd class="govuk-summary-list__actions">
87
+ <a class="govuk-link" href="questions/holiday-period">Answer<span class="govuk-visually-hidden"> What is the period of your holiday?</span></a>
88
+ </dd>
89
+ </div>
90
+ <div class="govuk-summary-list__row">
91
+ <dt class="govuk-summary-list__key">
92
+ Holiday Description
93
+ </dt>
94
+ <dd class="govuk-summary-list__value">
95
+ Not started
96
+ </dd>
97
+ <dd class="govuk-summary-list__actions">
98
+ <a class="govuk-link" href="questions/holiday-description">Answer<span class="govuk-visually-hidden"> Describe your ideal holiday.</span></a>
99
+ </dd>
100
+ </div>
101
+ <div class="govuk-summary-list__row">
102
+ <dt class="govuk-summary-list__key">
103
+ Secret Holiday Wish
104
+ </dt>
105
+ <dd class="govuk-summary-list__value">
106
+ Not started
107
+ </dd>
108
+ <dd class="govuk-summary-list__actions">
109
+ <a class="govuk-link" href="questions/secret-wish">Answer<span class="govuk-visually-hidden"> Share a secret wish for your holiday (will be redacted).</span></a>
110
+ </dd>
111
+ </div>
112
+ <div class="govuk-summary-list__row">
113
+ <dt class="govuk-summary-list__key">
114
+ Travel Class
115
+ </dt>
116
+ <dd class="govuk-summary-list__value">
117
+ Not started
118
+ </dd>
119
+ <dd class="govuk-summary-list__actions">
120
+ <a class="govuk-link" href="questions/travel-class">Answer<span class="govuk-visually-hidden"> Which class do you want to travel in?</span></a>
121
+ </dd>
122
+ </div>
123
+ <div class="govuk-summary-list__row">
124
+ <dt class="govuk-summary-list__key">
125
+ Holiday Arrival
126
+ </dt>
127
+ <dd class="govuk-summary-list__value">
128
+ Not started
129
+ </dd>
130
+ <dd class="govuk-summary-list__actions">
131
+ <a class="govuk-link" href="questions/holiday-arrival">Answer<span class="govuk-visually-hidden"> When would you like to arrive at your destination?</span></a>
132
+ </dd>
133
+ </div>
134
+ <div class="govuk-summary-list__row">
135
+ <dt class="govuk-summary-list__key">
136
+ Favourite Holiday Snack
137
+ </dt>
138
+ <dd class="govuk-summary-list__value">
139
+ Not started
140
+ </dd>
141
+ <dd class="govuk-summary-list__actions">
142
+ <a class="govuk-link" href="questions/holiday-snack">Answer<span class="govuk-visually-hidden"> What is your favourite snack to eat on holiday?</span></a>
143
+ </dd>
144
+ </div>
145
+ <div class="govuk-summary-list__row">
146
+ <dt class="govuk-summary-list__key">
147
+ Travel Companions
148
+ </dt>
149
+ <dd class="govuk-summary-list__value">
150
+ Not started
151
+ </dd>
152
+ <dd class="govuk-summary-list__actions">
153
+ <a class="govuk-link" href="questions/companions">Answer<span class="govuk-visually-hidden"> Enter the names and ages of your travel companions.</span></a>
154
+ </dd>
155
+ </div>
156
+ <div class="govuk-summary-list__row">
157
+ <dt class="govuk-summary-list__key">
158
+ Number of Nights
159
+ </dt>
160
+ <dd class="govuk-summary-list__value">
161
+ Not started
162
+ </dd>
163
+ <dd class="govuk-summary-list__actions">
164
+ <a class="govuk-link" href="questions/nights">Answer<span class="govuk-visually-hidden"> How many nights will you stay on holiday?</span></a>
165
+ </dd>
166
+ </div>
167
+ <div class="govuk-summary-list__row">
168
+ <dt class="govuk-summary-list__key">
169
+ Hotel Address
170
+ </dt>
171
+ <dd class="govuk-summary-list__value">
172
+ Not started
173
+ </dd>
174
+ <dd class="govuk-summary-list__actions">
175
+ <a class="govuk-link" href="questions/hotel-address">Answer<span class="govuk-visually-hidden"> What is the address of your hotel?</span></a>
176
+ </dd>
177
+ </div>
178
+ <div class="govuk-summary-list__row">
179
+ <dt class="govuk-summary-list__key">
180
+ Luggage Weight
181
+ </dt>
182
+ <dd class="govuk-summary-list__value">
183
+ Not started
184
+ </dd>
185
+ <dd class="govuk-summary-list__actions">
186
+ <a class="govuk-link" href="questions/luggage-weight-units">Answer<span class="govuk-visually-hidden"> Select your luggage weight and unit.</span></a>
187
+ </dd>
188
+ </div>
189
+ </dl>
190
+
191
+ <form action method="post">
192
+ <input type="hidden" name="_csrf" value="">
193
+ <button type="submit" class="govuk-button" data-module="govuk-button">
194
+ Accept &amp; Submit
195
+ </button>
196
+ </form>
197
+
198
+ </div>
199
+ </div>
200
+
201
+
@@ -0,0 +1,201 @@
1
+
2
+ <style >
3
+ .app-task-list {
4
+ padding-left: 0;
5
+ }
6
+ .app-task-list>li {
7
+ position: relative;
8
+ list-style-type: none;
9
+
10
+ }
11
+ .app-task-list__section .govuk-tag {
12
+ position: absolute;
13
+ top: 3px;
14
+ right: 0;
15
+ }
16
+ .app-task-list .govuk-summary-list {
17
+ border-top: 1px solid #b1b4b6;
18
+ }
19
+ </style>
20
+
21
+ <div class="govuk-grid-row">
22
+ <div class="govuk-grid-column-full">
23
+ <dl class="govuk-summary-list">
24
+ <div class="govuk-summary-list__row">
25
+ <dt class="govuk-summary-list__key">
26
+ Holiday Activities
27
+ </dt>
28
+ <dd class="govuk-summary-list__value">
29
+ Swimming
30
+ </dd>
31
+ <dd class="govuk-summary-list__actions">
32
+ <a class="govuk-link" href="questions/holiday-activities">Change<span class="govuk-visually-hidden"> Which activities do you want to do on holiday?</span></a>
33
+ </dd>
34
+ </div>
35
+ <div class="govuk-summary-list__row">
36
+ <dt class="govuk-summary-list__key">
37
+ Travel Insurance
38
+ </dt>
39
+ <dd class="govuk-summary-list__value">
40
+ Yes
41
+ </dd>
42
+ <dd class="govuk-summary-list__actions">
43
+ <a class="govuk-link" href="questions/add-insurance">Change<span class="govuk-visually-hidden"> Do you want to add travel insurance to your holiday?</span></a>
44
+ </dd>
45
+ </div>
46
+ <div class="govuk-summary-list__row">
47
+ <dt class="govuk-summary-list__key">
48
+ Travel Insurance Type
49
+ </dt>
50
+ <dd class="govuk-summary-list__value">
51
+ Basic
52
+ </dd>
53
+ <dd class="govuk-summary-list__actions">
54
+ <a class="govuk-link" href="questions/travel-insurance-type">Change<span class="govuk-visually-hidden"> Which type of travel insurance would you like?</span></a>
55
+ </dd>
56
+ </div>
57
+ <div class="govuk-summary-list__row">
58
+ <dt class="govuk-summary-list__key">
59
+ Holiday Destination
60
+ </dt>
61
+ <dd class="govuk-summary-list__value">
62
+ Beach
63
+ </dd>
64
+ <dd class="govuk-summary-list__actions">
65
+ <a class="govuk-link" href="questions/holiday-destination">Change<span class="govuk-visually-hidden"> Where would you like to go on holiday?</span></a>
66
+ </dd>
67
+ </div>
68
+ <div class="govuk-summary-list__row">
69
+ <dt class="govuk-summary-list__key">
70
+ Departure Date
71
+ </dt>
72
+ <dd class="govuk-summary-list__value">
73
+ 1 January 2025
74
+ </dd>
75
+ <dd class="govuk-summary-list__actions">
76
+ <a class="govuk-link" href="questions/departure-date">Change<span class="govuk-visually-hidden"> When do you want to start your holiday?</span></a>
77
+ </dd>
78
+ </div>
79
+ <div class="govuk-summary-list__row">
80
+ <dt class="govuk-summary-list__key">
81
+ Holiday Period
82
+ </dt>
83
+ <dd class="govuk-summary-list__value">
84
+ Start: 00:00 1 January 2025<br>End: 00:00 2 January 2025
85
+ </dd>
86
+ <dd class="govuk-summary-list__actions">
87
+ <a class="govuk-link" href="questions/holiday-period">Change<span class="govuk-visually-hidden"> What is the period of your holiday?</span></a>
88
+ </dd>
89
+ </div>
90
+ <div class="govuk-summary-list__row">
91
+ <dt class="govuk-summary-list__key">
92
+ Holiday Description
93
+ </dt>
94
+ <dd class="govuk-summary-list__value">
95
+ Test
96
+ </dd>
97
+ <dd class="govuk-summary-list__actions">
98
+ <a class="govuk-link" href="questions/holiday-description">Change<span class="govuk-visually-hidden"> Describe your ideal holiday.</span></a>
99
+ </dd>
100
+ </div>
101
+ <div class="govuk-summary-list__row">
102
+ <dt class="govuk-summary-list__key">
103
+ Secret Holiday Wish
104
+ </dt>
105
+ <dd class="govuk-summary-list__value">
106
+ Secret
107
+ </dd>
108
+ <dd class="govuk-summary-list__actions">
109
+ <a class="govuk-link" href="questions/secret-wish">Change<span class="govuk-visually-hidden"> Share a secret wish for your holiday (will be redacted).</span></a>
110
+ </dd>
111
+ </div>
112
+ <div class="govuk-summary-list__row">
113
+ <dt class="govuk-summary-list__key">
114
+ Travel Class
115
+ </dt>
116
+ <dd class="govuk-summary-list__value">
117
+ Economy
118
+ </dd>
119
+ <dd class="govuk-summary-list__actions">
120
+ <a class="govuk-link" href="questions/travel-class">Change<span class="govuk-visually-hidden"> Which class do you want to travel in?</span></a>
121
+ </dd>
122
+ </div>
123
+ <div class="govuk-summary-list__row">
124
+ <dt class="govuk-summary-list__key">
125
+ Holiday Arrival
126
+ </dt>
127
+ <dd class="govuk-summary-list__value">
128
+ 1 January 2025<br>10:45am
129
+ </dd>
130
+ <dd class="govuk-summary-list__actions">
131
+ <a class="govuk-link" href="questions/holiday-arrival">Change<span class="govuk-visually-hidden"> When would you like to arrive at your destination?</span></a>
132
+ </dd>
133
+ </div>
134
+ <div class="govuk-summary-list__row">
135
+ <dt class="govuk-summary-list__key">
136
+ Favourite Holiday Snack
137
+ </dt>
138
+ <dd class="govuk-summary-list__value">
139
+ Test
140
+ </dd>
141
+ <dd class="govuk-summary-list__actions">
142
+ <a class="govuk-link" href="questions/holiday-snack">Change<span class="govuk-visually-hidden"> What is your favourite snack to eat on holiday?</span></a>
143
+ </dd>
144
+ </div>
145
+ <div class="govuk-summary-list__row">
146
+ <dt class="govuk-summary-list__key">
147
+ Travel Companions
148
+ </dt>
149
+ <dd class="govuk-summary-list__value">
150
+ test<br>1<br>
151
+ </dd>
152
+ <dd class="govuk-summary-list__actions">
153
+ <a class="govuk-link" href="questions/companions">Change<span class="govuk-visually-hidden"> Enter the names and ages of your travel companions.</span></a>
154
+ </dd>
155
+ </div>
156
+ <div class="govuk-summary-list__row">
157
+ <dt class="govuk-summary-list__key">
158
+ Number of Nights
159
+ </dt>
160
+ <dd class="govuk-summary-list__value">
161
+ 1
162
+ </dd>
163
+ <dd class="govuk-summary-list__actions">
164
+ <a class="govuk-link" href="questions/nights">Change<span class="govuk-visually-hidden"> How many nights will you stay on holiday?</span></a>
165
+ </dd>
166
+ </div>
167
+ <div class="govuk-summary-list__row">
168
+ <dt class="govuk-summary-list__key">
169
+ Hotel Address
170
+ </dt>
171
+ <dd class="govuk-summary-list__value">
172
+ 1 Test St<br>Testville<br>TE5 5ST
173
+ </dd>
174
+ <dd class="govuk-summary-list__actions">
175
+ <a class="govuk-link" href="questions/hotel-address">Change<span class="govuk-visually-hidden"> What is the address of your hotel?</span></a>
176
+ </dd>
177
+ </div>
178
+ <div class="govuk-summary-list__row">
179
+ <dt class="govuk-summary-list__key">
180
+ Luggage Weight
181
+ </dt>
182
+ <dd class="govuk-summary-list__value">
183
+ 10 kg
184
+ </dd>
185
+ <dd class="govuk-summary-list__actions">
186
+ <a class="govuk-link" href="questions/luggage-weight-units">Change<span class="govuk-visually-hidden"> Select your luggage weight and unit.</span></a>
187
+ </dd>
188
+ </div>
189
+ </dl>
190
+
191
+ <form action method="post">
192
+ <input type="hidden" name="_csrf" value="">
193
+ <button type="submit" class="govuk-button" data-module="govuk-button">
194
+ Accept &amp; Submit
195
+ </button>
196
+ </form>
197
+
198
+ </div>
199
+ </div>
200
+
201
+