@planning-inspectorate/dynamic-forms 2.0.1 → 2.0.3
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 +2 -2
- package/src/validator/address-validator.js +4 -4
- package/src/validator/address-validator.test.js +6 -2
- package/src/validator/coordinates-validator.js +6 -6
- package/src/validator/coordinates-validator.test.js +10 -14
- package/src/validator/date-validator.js +2 -2
- package/src/validator/date-validator.test.js +6 -6
- package/test/snapshots/add-insurance.html +19 -19
- package/test/snapshots/holiday-activities.html +25 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planning-inspectorate/dynamic-forms",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "This package is for building GDS forms using a configuration-based approach.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"url": "git+https://github.com/Planning-Inspectorate/dynamic-forms.git"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"commitlint": "commitlint --from=$(git cherry origin/main | head -n 1 | cut -c 3-)",
|
|
12
|
+
"commitlint": "commitlint --from=$(git rev-parse $(git cherry origin/main | head -n 1 | cut -c 3-)^1)",
|
|
13
13
|
"lint": "npx eslint .",
|
|
14
14
|
"format": "prettier --write .",
|
|
15
15
|
"format-check": "prettier --check .",
|
|
@@ -21,8 +21,8 @@ export const townCityMaxLength = 250;
|
|
|
21
21
|
export const townCityMinLength = 0;
|
|
22
22
|
export const countyMaxLength = 250;
|
|
23
23
|
export const countyMinLength = 0;
|
|
24
|
-
export const postcodeMaxLength =
|
|
25
|
-
export const postcodeMinLength =
|
|
24
|
+
export const postcodeMaxLength = 7;
|
|
25
|
+
export const postcodeMinLength = 5;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* enforces address fields are within allowed parameters
|
|
@@ -66,7 +66,7 @@ export default class AddressValidator extends BaseValidator {
|
|
|
66
66
|
if (!this.requiredFields?.addressLine1) {
|
|
67
67
|
validator.optional({ checkFalsy: true });
|
|
68
68
|
} else {
|
|
69
|
-
validator.notEmpty().withMessage(`Enter
|
|
69
|
+
validator.notEmpty().withMessage(`Enter address line 1, typically the building and street`);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
return validator
|
|
@@ -143,7 +143,7 @@ export default class AddressValidator extends BaseValidator {
|
|
|
143
143
|
return validator
|
|
144
144
|
.isLength({ min: postcodeMinLength, max: postcodeMaxLength })
|
|
145
145
|
.bail()
|
|
146
|
-
.withMessage(`Postcode must be
|
|
146
|
+
.withMessage(`Postcode must be between ${postcodeMinLength} and ${postcodeMaxLength} characters`)
|
|
147
147
|
.custom((postcode) => {
|
|
148
148
|
return validatePostcode(postcode);
|
|
149
149
|
});
|
|
@@ -6,6 +6,7 @@ import AddressValidator, {
|
|
|
6
6
|
addressLine1MaxLength,
|
|
7
7
|
addressLine2MaxLength,
|
|
8
8
|
postcodeMaxLength,
|
|
9
|
+
postcodeMinLength,
|
|
9
10
|
townCityMaxLength
|
|
10
11
|
} from './address-validator.js';
|
|
11
12
|
|
|
@@ -74,7 +75,7 @@ describe('AddressValidator', () => {
|
|
|
74
75
|
const errors = await _validationMappedErrors(req, question);
|
|
75
76
|
|
|
76
77
|
assert.strictEqual(Object.keys(errors).length, 5);
|
|
77
|
-
assert.strictEqual(errors.testField_addressLine1.msg, 'Enter
|
|
78
|
+
assert.strictEqual(errors.testField_addressLine1.msg, 'Enter address line 1, typically the building and street');
|
|
78
79
|
assert.strictEqual(errors.testField_addressLine2.msg, 'Enter an address line 2');
|
|
79
80
|
assert.strictEqual(errors.testField_townCity.msg, 'Enter a town or city');
|
|
80
81
|
assert.strictEqual(errors.testField_county.msg, 'Enter a county');
|
|
@@ -107,7 +108,10 @@ describe('AddressValidator', () => {
|
|
|
107
108
|
`Address line 2 must be ${addressLine2MaxLength} characters or less`
|
|
108
109
|
);
|
|
109
110
|
assert.strictEqual(errors.testField_townCity.msg, `Town or city must be ${townCityMaxLength} characters or less`);
|
|
110
|
-
assert.strictEqual(
|
|
111
|
+
assert.strictEqual(
|
|
112
|
+
errors.testField_postcode.msg,
|
|
113
|
+
`Postcode must be between ${postcodeMinLength} and ${postcodeMaxLength} characters`
|
|
114
|
+
);
|
|
111
115
|
});
|
|
112
116
|
});
|
|
113
117
|
|
|
@@ -24,22 +24,22 @@ export default class CoordinatesValidator extends BaseValidator {
|
|
|
24
24
|
body(this.northing.fieldName)
|
|
25
25
|
.optional({ checkFalsy: true })
|
|
26
26
|
.isNumeric()
|
|
27
|
-
.withMessage(`
|
|
27
|
+
.withMessage(`The ${this.northing.title} grid reference must be a number`)
|
|
28
28
|
.isLength({ min: requiredCoordinateLength, max: requiredCoordinateLength })
|
|
29
|
-
.withMessage(`
|
|
29
|
+
.withMessage(`The ${this.northing.title} grid reference must contain ${requiredCoordinateLength} digits`),
|
|
30
30
|
|
|
31
31
|
body(this.easting.fieldName)
|
|
32
32
|
.optional({ checkFalsy: true })
|
|
33
33
|
.isNumeric()
|
|
34
|
-
.withMessage(`
|
|
34
|
+
.withMessage(`The ${this.easting.title} grid reference must be a number`)
|
|
35
35
|
.isLength({ min: requiredCoordinateLength, max: requiredCoordinateLength })
|
|
36
|
-
.withMessage(`
|
|
36
|
+
.withMessage(`The ${this.easting.title} grid reference must contain ${requiredCoordinateLength} digits`),
|
|
37
37
|
|
|
38
38
|
// validate northing has been populated if value for easting provided
|
|
39
39
|
body(this.northing.fieldName).custom((_, { req }) => {
|
|
40
40
|
const { siteNorthing, siteEasting } = req.body;
|
|
41
41
|
if (!siteNorthing && siteEasting) {
|
|
42
|
-
throw new Error(`
|
|
42
|
+
throw new Error(`The ${this.northing.title} grid reference must contain 6 digits`);
|
|
43
43
|
}
|
|
44
44
|
return true;
|
|
45
45
|
}),
|
|
@@ -48,7 +48,7 @@ export default class CoordinatesValidator extends BaseValidator {
|
|
|
48
48
|
body(this.easting.fieldName).custom((_, { req }) => {
|
|
49
49
|
const { siteNorthing, siteEasting } = req.body;
|
|
50
50
|
if (siteNorthing && !siteEasting) {
|
|
51
|
-
throw new Error(`
|
|
51
|
+
throw new Error(`The ${this.easting.title} grid reference must contain 6 digits`);
|
|
52
52
|
}
|
|
53
53
|
return true;
|
|
54
54
|
})
|
|
@@ -30,13 +30,9 @@ describe('./src/dynamic-forms/validator/coordinates-validator.js', () => {
|
|
|
30
30
|
const coordinatesValidator = new CoordinatesValidator(northing, easting);
|
|
31
31
|
const errors = await _validationMappedErrors(req, coordinatesValidator);
|
|
32
32
|
assert.strictEqual(Object.keys(errors).length, 2);
|
|
33
|
-
assert.strictEqual(
|
|
34
|
-
|
|
35
|
-
`Please a numeric value for the Grid reference ${northing.title}`
|
|
36
|
-
);
|
|
37
|
-
assert.strictEqual(errors[easting.fieldName].msg, `Please a numeric value for the Grid reference ${easting.title}`);
|
|
33
|
+
assert.strictEqual(errors[northing.fieldName].msg, `The ${northing.title} grid reference must be a number`);
|
|
34
|
+
assert.strictEqual(errors[easting.fieldName].msg, `The ${easting.title} grid reference must be a number`);
|
|
38
35
|
});
|
|
39
|
-
|
|
40
36
|
it('should return an error message if coordinates are not the required length', async () => {
|
|
41
37
|
const req = {
|
|
42
38
|
body: {
|
|
@@ -49,8 +45,8 @@ describe('./src/dynamic-forms/validator/coordinates-validator.js', () => {
|
|
|
49
45
|
const errors = await _validationMappedErrors(req, coordinatesValidator);
|
|
50
46
|
|
|
51
47
|
assert.strictEqual(Object.keys(errors).length, 2);
|
|
52
|
-
assert.strictEqual(errors[northing.fieldName].msg, `
|
|
53
|
-
assert.strictEqual(errors[easting.fieldName].msg, `
|
|
48
|
+
assert.strictEqual(errors[northing.fieldName].msg, `The ${northing.title} grid reference must contain 6 digits`);
|
|
49
|
+
assert.strictEqual(errors[easting.fieldName].msg, `The ${easting.title} grid reference must contain 6 digits`);
|
|
54
50
|
});
|
|
55
51
|
|
|
56
52
|
it('should return an error message if northing is populated but easting is not', async () => {
|
|
@@ -65,7 +61,7 @@ describe('./src/dynamic-forms/validator/coordinates-validator.js', () => {
|
|
|
65
61
|
const errors = await _validationMappedErrors(req, coordinatesValidator);
|
|
66
62
|
|
|
67
63
|
assert.strictEqual(Object.keys(errors).length, 1);
|
|
68
|
-
assert.strictEqual(errors[easting.fieldName].msg, `
|
|
64
|
+
assert.strictEqual(errors[easting.fieldName].msg, `The ${easting.title} grid reference must contain 6 digits`);
|
|
69
65
|
});
|
|
70
66
|
|
|
71
67
|
it('should return an error message if easting is populated but northing is not', async () => {
|
|
@@ -80,7 +76,7 @@ describe('./src/dynamic-forms/validator/coordinates-validator.js', () => {
|
|
|
80
76
|
const errors = await _validationMappedErrors(req, coordinatesValidator);
|
|
81
77
|
|
|
82
78
|
assert.strictEqual(Object.keys(errors).length, 1);
|
|
83
|
-
assert.strictEqual(errors[northing.fieldName].msg, `
|
|
79
|
+
assert.strictEqual(errors[northing.fieldName].msg, `The ${northing.title} grid reference must contain 6 digits`);
|
|
84
80
|
});
|
|
85
81
|
|
|
86
82
|
it('should return an error message if northing is populated but not required length and easting is not populated', async () => {
|
|
@@ -95,8 +91,8 @@ describe('./src/dynamic-forms/validator/coordinates-validator.js', () => {
|
|
|
95
91
|
const errors = await _validationMappedErrors(req, coordinatesValidator);
|
|
96
92
|
|
|
97
93
|
assert.strictEqual(Object.keys(errors).length, 2);
|
|
98
|
-
assert.strictEqual(errors[northing.fieldName].msg, `
|
|
99
|
-
assert.strictEqual(errors[easting.fieldName].msg, `
|
|
94
|
+
assert.strictEqual(errors[northing.fieldName].msg, `The ${northing.title} grid reference must contain 6 digits`);
|
|
95
|
+
assert.strictEqual(errors[easting.fieldName].msg, `The ${easting.title} grid reference must contain 6 digits`);
|
|
100
96
|
});
|
|
101
97
|
|
|
102
98
|
it('should return an error message if easting is populated but not required length and northing is not populated', async () => {
|
|
@@ -111,8 +107,8 @@ describe('./src/dynamic-forms/validator/coordinates-validator.js', () => {
|
|
|
111
107
|
const errors = await _validationMappedErrors(req, coordinatesValidator);
|
|
112
108
|
|
|
113
109
|
assert.strictEqual(Object.keys(errors).length, 2);
|
|
114
|
-
assert.strictEqual(errors[northing.fieldName].msg, `
|
|
115
|
-
assert.strictEqual(errors[easting.fieldName].msg, `
|
|
110
|
+
assert.strictEqual(errors[northing.fieldName].msg, `The ${northing.title} grid reference must contain 6 digits`);
|
|
111
|
+
assert.strictEqual(errors[easting.fieldName].msg, `The ${easting.title} grid reference must contain 6 digits`);
|
|
116
112
|
});
|
|
117
113
|
});
|
|
118
114
|
|
|
@@ -184,8 +184,8 @@ export default class DateValidator extends BaseValidator {
|
|
|
184
184
|
noDayMonthErrorMessage: `${capitalisedInputLabel} must include a day and month`,
|
|
185
185
|
noDayYearErrorMessage: `${capitalisedInputLabel} must include a day and year`,
|
|
186
186
|
noMonthYearErrorMessage: `${capitalisedInputLabel} must include a month and year`,
|
|
187
|
-
invalidDateErrorMessage: `${capitalisedInputLabel} must be a real
|
|
188
|
-
invalidMonthErrorMessage: `${capitalisedInputLabel} month must be
|
|
187
|
+
invalidDateErrorMessage: `${capitalisedInputLabel} day must be a real day`,
|
|
188
|
+
invalidMonthErrorMessage: `${capitalisedInputLabel} month must be between 1 and 12`,
|
|
189
189
|
invalidYearErrorMessage: `${capitalisedInputLabel} year must include 4 numbers`,
|
|
190
190
|
futureDateErrorMessage: `${capitalisedInputLabel} must be today or in the past`,
|
|
191
191
|
pastDateErrorMessage: `${capitalisedInputLabel} must be today or in the future`
|
|
@@ -196,7 +196,7 @@ describe('./src/dynamic-forms/validator/date-validator.js', () => {
|
|
|
196
196
|
const errors = await _validationMappedErrors(req, question, 'the required date');
|
|
197
197
|
|
|
198
198
|
assert.strictEqual(Object.keys(errors).length, 1);
|
|
199
|
-
assert.strictEqual(errors[`${question.fieldName}_day`].msg, 'The required date must be a real
|
|
199
|
+
assert.strictEqual(errors[`${question.fieldName}_day`].msg, 'The required date day must be a real day');
|
|
200
200
|
});
|
|
201
201
|
|
|
202
202
|
it('throws error if invalid month provided', async () => {
|
|
@@ -215,7 +215,7 @@ describe('./src/dynamic-forms/validator/date-validator.js', () => {
|
|
|
215
215
|
const errors = await _validationMappedErrors(req, question, 'the required date');
|
|
216
216
|
|
|
217
217
|
assert.strictEqual(Object.keys(errors).length, 1);
|
|
218
|
-
assert.strictEqual(errors[`${question.fieldName}_month`].msg, 'The required date month must be
|
|
218
|
+
assert.strictEqual(errors[`${question.fieldName}_month`].msg, 'The required date month must be between 1 and 12');
|
|
219
219
|
});
|
|
220
220
|
|
|
221
221
|
it('throws error if invalid year provided', async () => {
|
|
@@ -336,8 +336,8 @@ describe('./src/dynamic-forms/validator/date-validator.js', () => {
|
|
|
336
336
|
const errors = await _validationMappedErrors(req, question, 'the required date');
|
|
337
337
|
|
|
338
338
|
assert.strictEqual(Object.keys(errors).length, 3);
|
|
339
|
-
assert.strictEqual(errors[`${question.fieldName}_day`].msg, 'The required date must be a real
|
|
340
|
-
assert.strictEqual(errors[`${question.fieldName}_month`].msg, 'The required date month must be
|
|
339
|
+
assert.strictEqual(errors[`${question.fieldName}_day`].msg, 'The required date day must be a real day');
|
|
340
|
+
assert.strictEqual(errors[`${question.fieldName}_month`].msg, 'The required date month must be between 1 and 12');
|
|
341
341
|
assert.strictEqual(errors[`${question.fieldName}_year`].msg, 'The required date year must include 4 numbers');
|
|
342
342
|
});
|
|
343
343
|
|
|
@@ -357,8 +357,8 @@ describe('./src/dynamic-forms/validator/date-validator.js', () => {
|
|
|
357
357
|
const errors = await _validationMappedErrors(req, question, 'the required date');
|
|
358
358
|
|
|
359
359
|
assert.strictEqual(Object.keys(errors).length, 3);
|
|
360
|
-
assert.strictEqual(errors[`${question.fieldName}_day`].msg, 'The required date must be a real
|
|
361
|
-
assert.strictEqual(errors[`${question.fieldName}_month`].msg, 'The required date month must be
|
|
360
|
+
assert.strictEqual(errors[`${question.fieldName}_day`].msg, 'The required date day must be a real day');
|
|
361
|
+
assert.strictEqual(errors[`${question.fieldName}_month`].msg, 'The required date month must be between 1 and 12');
|
|
362
362
|
assert.strictEqual(errors[`${question.fieldName}_year`].msg, 'The required date year must include 4 numbers');
|
|
363
363
|
});
|
|
364
364
|
|
|
@@ -3,26 +3,26 @@
|
|
|
3
3
|
<form action="" method="post" novalidate>
|
|
4
4
|
<div class="govuk-form-group">
|
|
5
5
|
<fieldset class="govuk-fieldset">
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
</div>
|
|
18
|
-
<div class="govuk-radios__item">
|
|
19
|
-
<input class="govuk-radios__input" id="addInsurance-2" name="addInsurance" type="radio" value="no" data-cy="answer-no">
|
|
20
|
-
<label class="govuk-label govuk-radios__label" for="addInsurance-2">
|
|
21
|
-
No
|
|
22
|
-
</label>
|
|
23
|
-
</div>
|
|
6
|
+
<legend class="govuk-fieldset__legend govuk-fieldset__legend--l">
|
|
7
|
+
<h1 class="govuk-fieldset__heading">
|
|
8
|
+
Do you want to add travel insurance to your holiday?
|
|
9
|
+
</h1>
|
|
10
|
+
</legend>
|
|
11
|
+
<div class="govuk-radios govuk-radios" data-module="govuk-radios">
|
|
12
|
+
<div class="govuk-radios__item">
|
|
13
|
+
<input class="govuk-radios__input" id="addInsurance" name="addInsurance" type="radio" value="yes" data-cy="answer-yes">
|
|
14
|
+
<label class="govuk-label govuk-radios__label" for="addInsurance">
|
|
15
|
+
Yes
|
|
16
|
+
</label>
|
|
24
17
|
</div>
|
|
25
|
-
|
|
18
|
+
<div class="govuk-radios__item">
|
|
19
|
+
<input class="govuk-radios__input" id="addInsurance-2" name="addInsurance" type="radio" value="no" data-cy="answer-no">
|
|
20
|
+
<label class="govuk-label govuk-radios__label" for="addInsurance-2">
|
|
21
|
+
No
|
|
22
|
+
</label>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</fieldset>
|
|
26
26
|
</div>
|
|
27
27
|
|
|
28
28
|
|
|
@@ -3,32 +3,32 @@
|
|
|
3
3
|
<form action="" method="post" novalidate>
|
|
4
4
|
<div class="govuk-form-group">
|
|
5
5
|
<fieldset class="govuk-fieldset">
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
</div>
|
|
18
|
-
<div class="govuk-checkboxes__item">
|
|
19
|
-
<input class="govuk-checkboxes__input" id="holidayActivities-2" name="holidayActivities" type="checkbox" value="hiking" data-cy="answer-hiking">
|
|
20
|
-
<label class="govuk-label govuk-checkboxes__label" for="holidayActivities-2">
|
|
21
|
-
Hiking
|
|
22
|
-
</label>
|
|
23
|
-
</div>
|
|
24
|
-
<div class="govuk-checkboxes__item">
|
|
25
|
-
<input class="govuk-checkboxes__input" id="holidayActivities-3" name="holidayActivities" type="checkbox" value="sightseeing" data-cy="answer-sightseeing">
|
|
26
|
-
<label class="govuk-label govuk-checkboxes__label" for="holidayActivities-3">
|
|
27
|
-
Sightseeing
|
|
28
|
-
</label>
|
|
29
|
-
</div>
|
|
6
|
+
<legend class="govuk-fieldset__legend govuk-fieldset__legend--l">
|
|
7
|
+
<h1 class="govuk-fieldset__heading">
|
|
8
|
+
Which activities do you want to do on holiday?
|
|
9
|
+
</h1>
|
|
10
|
+
</legend>
|
|
11
|
+
<div class="govuk-checkboxes govuk-checkboxes" data-module="govuk-checkboxes">
|
|
12
|
+
<div class="govuk-checkboxes__item">
|
|
13
|
+
<input class="govuk-checkboxes__input" id="holidayActivities" name="holidayActivities" type="checkbox" value="swimming" data-cy="answer-swimming">
|
|
14
|
+
<label class="govuk-label govuk-checkboxes__label" for="holidayActivities">
|
|
15
|
+
Swimming
|
|
16
|
+
</label>
|
|
30
17
|
</div>
|
|
31
|
-
|
|
18
|
+
<div class="govuk-checkboxes__item">
|
|
19
|
+
<input class="govuk-checkboxes__input" id="holidayActivities-2" name="holidayActivities" type="checkbox" value="hiking" data-cy="answer-hiking">
|
|
20
|
+
<label class="govuk-label govuk-checkboxes__label" for="holidayActivities-2">
|
|
21
|
+
Hiking
|
|
22
|
+
</label>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="govuk-checkboxes__item">
|
|
25
|
+
<input class="govuk-checkboxes__input" id="holidayActivities-3" name="holidayActivities" type="checkbox" value="sightseeing" data-cy="answer-sightseeing">
|
|
26
|
+
<label class="govuk-label govuk-checkboxes__label" for="holidayActivities-3">
|
|
27
|
+
Sightseeing
|
|
28
|
+
</label>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</fieldset>
|
|
32
32
|
</div>
|
|
33
33
|
|
|
34
34
|
<button type="submit" class="govuk-button" data-module="govuk-button" data-cy="button-save-and-continue">
|