@planning-inspectorate/dynamic-forms 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/manage-list/question.js +7 -0
- package/src/controller.js +4 -0
- package/src/controller.test.js +5 -1
- package/src/lib/session-answer-store.js +12 -3
- package/src/lib/session-answer-store.test.js +42 -0
- package/test/check-your-answers.test.js +19 -1
- package/test/questions.test.js +3 -3
package/package.json
CHANGED
|
@@ -86,6 +86,13 @@ export default class ManageListQuestion extends Question {
|
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
async getDataToSave(req, journeyResponse) {
|
|
90
|
+
let responseToSave = { answers: {} };
|
|
91
|
+
const data = journeyResponse.answers[this.fieldName];
|
|
92
|
+
responseToSave.answers[this.fieldName] = data || [];
|
|
93
|
+
return responseToSave;
|
|
94
|
+
}
|
|
95
|
+
|
|
89
96
|
formatAnswerForSummary(sectionSegment, journey, answer) {
|
|
90
97
|
let formattedAnswer = this.notStartedText;
|
|
91
98
|
if (answer && Array.isArray(answer)) {
|
package/src/controller.js
CHANGED
|
@@ -184,6 +184,8 @@ export async function question(req, res) {
|
|
|
184
184
|
* @property {import('express').Response} res
|
|
185
185
|
* @property {string} journeyId
|
|
186
186
|
* @property {string} referenceId
|
|
187
|
+
* @property {boolean} isManageListItem
|
|
188
|
+
* @property {string} [manageListQuestionFieldName]
|
|
187
189
|
* @property {Object<string, any>} data
|
|
188
190
|
*/
|
|
189
191
|
|
|
@@ -234,6 +236,8 @@ export function buildSave(saveData, redirectToTaskListOnSuccess) {
|
|
|
234
236
|
res,
|
|
235
237
|
journeyId: journeyResponse.journeyId,
|
|
236
238
|
referenceId: journeyResponse.referenceId,
|
|
239
|
+
isManageListItem: question.isInManageListSection,
|
|
240
|
+
manageListQuestionFieldName: manageListQuestion?.fieldName,
|
|
237
241
|
data
|
|
238
242
|
});
|
|
239
243
|
|
package/src/controller.test.js
CHANGED
|
@@ -386,6 +386,8 @@ describe('dynamic-form/controller', () => {
|
|
|
386
386
|
res,
|
|
387
387
|
journeyId: journeyParams.journeyId,
|
|
388
388
|
referenceId: journeyParams.referenceId,
|
|
389
|
+
isManageListItem: undefined,
|
|
390
|
+
manageListQuestionFieldName: undefined,
|
|
389
391
|
data: undefined
|
|
390
392
|
}
|
|
391
393
|
]);
|
|
@@ -443,7 +445,9 @@ describe('dynamic-form/controller', () => {
|
|
|
443
445
|
res,
|
|
444
446
|
journeyId: journeyParams.journeyId,
|
|
445
447
|
referenceId: journeyParams.referenceId,
|
|
446
|
-
data: undefined
|
|
448
|
+
data: undefined,
|
|
449
|
+
isManageListItem: undefined,
|
|
450
|
+
manageListQuestionFieldName: undefined
|
|
447
451
|
}
|
|
448
452
|
],
|
|
449
453
|
'save data args'
|
|
@@ -35,11 +35,12 @@ import { booleanToYesNoValue } from '../components/boolean/question.js';
|
|
|
35
35
|
*
|
|
36
36
|
*
|
|
37
37
|
* @param {Object} opts
|
|
38
|
-
* @param {string} [opts.reqParam]
|
|
38
|
+
* @param {string} [opts.reqParam]
|
|
39
|
+
* - optional request parameter to use as a key
|
|
39
40
|
* @returns {import('../controller').SaveDataFn}
|
|
40
41
|
*/
|
|
41
42
|
export function buildSaveDataToSession({ reqParam } = {}) {
|
|
42
|
-
return async ({ req, journeyId, data }) => {
|
|
43
|
+
return async ({ req, journeyId, data, isManageListItem, manageListQuestionFieldName }) => {
|
|
43
44
|
if (!req.session) {
|
|
44
45
|
throw new Error('request session required');
|
|
45
46
|
}
|
|
@@ -50,8 +51,16 @@ export function buildSaveDataToSession({ reqParam } = {}) {
|
|
|
50
51
|
// key by a further param
|
|
51
52
|
forms = forms[reqParamValue] || (forms[reqParamValue] = {});
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
+
let answers = forms[journeyId] || (forms[journeyId] = {});
|
|
55
|
+
if (isManageListItem) {
|
|
56
|
+
const answersList = answers[manageListQuestionFieldName] || (answers[manageListQuestionFieldName] = []);
|
|
57
|
+
answers = answersList.find((item) => item.id === req.params.manageListItemId);
|
|
54
58
|
|
|
59
|
+
if (!answers) {
|
|
60
|
+
answers = { id: req.params.manageListItemId };
|
|
61
|
+
answersList.push(answers);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
55
64
|
for (const [k, v] of Object.entries(data?.answers || {})) {
|
|
56
65
|
answers[k] = v;
|
|
57
66
|
}
|
|
@@ -80,6 +80,48 @@ describe('session-answer-store', () => {
|
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
});
|
|
83
|
+
it('should add a new managed list item when not present in the session', async () => {
|
|
84
|
+
const req = mockReq();
|
|
85
|
+
req.params = { manageListItemId: '12345' };
|
|
86
|
+
req.session = {};
|
|
87
|
+
const journeyId = 'j-1';
|
|
88
|
+
const data = { answers: { q1: 'a1' } };
|
|
89
|
+
const isManageListItem = true;
|
|
90
|
+
const manageListQuestionFieldName = 'myManagedList';
|
|
91
|
+
const saveDataToSession = buildSaveDataToSession();
|
|
92
|
+
await saveDataToSession({ req, journeyId, data, isManageListItem, manageListQuestionFieldName });
|
|
93
|
+
assert.deepStrictEqual(req.session, {
|
|
94
|
+
forms: {
|
|
95
|
+
'j-1': {
|
|
96
|
+
myManagedList: [{ id: '12345', q1: 'a1' }]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
it('should add to an existing managed list item using the id when present in the session', async () => {
|
|
102
|
+
const req = mockReq();
|
|
103
|
+
req.params = { manageListItemId: '12345' };
|
|
104
|
+
req.session = {
|
|
105
|
+
forms: {
|
|
106
|
+
'j-1': {
|
|
107
|
+
myManagedList: [{ id: '12345', q1: 'old value' }]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const journeyId = 'j-1';
|
|
112
|
+
const data = { answers: { q2: 'a1' } };
|
|
113
|
+
const isManageListItem = true;
|
|
114
|
+
const manageListQuestionFieldName = 'myManagedList';
|
|
115
|
+
const saveDataToSession = buildSaveDataToSession();
|
|
116
|
+
await saveDataToSession({ req, journeyId, data, isManageListItem, manageListQuestionFieldName });
|
|
117
|
+
assert.deepStrictEqual(req.session, {
|
|
118
|
+
forms: {
|
|
119
|
+
'j-1': {
|
|
120
|
+
myManagedList: [{ id: '12345', q1: 'old value', q2: 'a1' }]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
});
|
|
83
125
|
|
|
84
126
|
it('should overwrite existing data by reqParam & journeyId', async () => {
|
|
85
127
|
const req = mockReq();
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { describe, it } from 'node:test';
|
|
2
2
|
import assert from 'assert';
|
|
3
|
-
import { questionsInOrder } from './questions.js';
|
|
3
|
+
import { manageListQuestions, questionsInOrder } from './questions.js';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { escapeForRegExp, snapshotsDir } from './utils/utils.js';
|
|
6
6
|
import { createAppWithQuestions, mockAnswer, mockAnswerBody } from './questions.test.js';
|
|
7
|
+
import { COMPONENT_TYPES } from '#src/index.js';
|
|
7
8
|
|
|
8
9
|
describe('check-your-answers', () => {
|
|
9
10
|
it(`should render all question rows with no answers`, async (ctx) => {
|
|
@@ -39,6 +40,23 @@ describe('check-your-answers', () => {
|
|
|
39
40
|
|
|
40
41
|
// 'answer' each question
|
|
41
42
|
for (const q of questionsInOrder) {
|
|
43
|
+
// Save happens on subquestion for manage list questions
|
|
44
|
+
if (q.type === COMPONENT_TYPES.MANAGE_LIST) {
|
|
45
|
+
// Get the list of subquestions for this manage list question
|
|
46
|
+
const manageListQuestion = manageListQuestions.find(
|
|
47
|
+
(question) => question.manageListQuestion.fieldName === q.fieldName
|
|
48
|
+
);
|
|
49
|
+
const subQuestionAnswers = mockAnswerBody(q)[manageListQuestion.manageListQuestion.fieldName];
|
|
50
|
+
// Post to them individually
|
|
51
|
+
for (const answer of subQuestionAnswers) {
|
|
52
|
+
const id = answer.id;
|
|
53
|
+
for (const subQuestion of manageListQuestion.questions) {
|
|
54
|
+
const key = subQuestion.fieldName;
|
|
55
|
+
const body = { [key]: answer[key] };
|
|
56
|
+
await testServer.post(`/questions/${q.url}/add/${id}/${subQuestion.url}`, body, { redirect: 'manual' });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
42
60
|
await testServer.post(`/questions/${q.url}`, mockAnswerBody(q), { redirect: 'manual' });
|
|
43
61
|
}
|
|
44
62
|
|
package/test/questions.test.js
CHANGED
|
@@ -257,9 +257,9 @@ export function mockAnswerBody(q) {
|
|
|
257
257
|
// manage list questions not available here so just hard coded
|
|
258
258
|
return {
|
|
259
259
|
[q.fieldName]: [
|
|
260
|
-
{ travelCompanionName: 'Companion 1', travelCompanionEmail: '
|
|
261
|
-
{ travelCompanionName: 'Companion 2', travelCompanionEmail: '
|
|
262
|
-
{ travelCompanionName: 'Companion 3', travelCompanionEmail: '
|
|
260
|
+
{ id: '1234', travelCompanionName: 'Companion 1', travelCompanionEmail: 'companion-1@example.com' },
|
|
261
|
+
{ id: '4567', travelCompanionName: 'Companion 2', travelCompanionEmail: 'companion-2@example.com' },
|
|
262
|
+
{ id: '8901', travelCompanionName: 'Companion 3', travelCompanionEmail: 'companion-3@example.com' }
|
|
263
263
|
]
|
|
264
264
|
};
|
|
265
265
|
}
|