@planning-inspectorate/data-model 1.17.0 → 1.18.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.
- package/docs/appeal-has.md +22 -14
- package/docs/appeal-s78.md +22 -14
- package/docs/dart-response.md +7 -6
- package/package.json +1 -1
- package/pins_data_model/models/model_appeal_has.py +10 -34
- package/pins_data_model/models/model_appeal_s78.py +10 -34
- package/pins_data_model/models/model_dart_response.py +2 -2
- package/schemas/appeal-has.schema.json +11 -3
- package/schemas/appeal-s78.schema.json +11 -3
- package/schemas/commands/appeal-advert.submission.schema.json +23 -0
- package/schemas/commands/appeal-common-submission.schema.json +30 -8
- package/schemas/commands/appeal-has-submission.schema.json +0 -1
- package/schemas/commands/appeal-representation-submission.schema.json +1 -1
- package/schemas/commands/appeal-s78-submission.schema.json +0 -1
- package/schemas/commands/appellant-submission.schema.json +17 -6
- package/schemas/commands/lpa-questionnaire-has.schema.json +0 -1
- package/schemas/commands/lpa-questionnaire-s78.schema.json +0 -1
- package/schemas/commands/lpa-questionnaire.schema.json +14 -12
- package/schemas/dart-response.schema.json +3 -2
- package/src/schemas.d.ts +116 -512
- package/tests/appeals/commands/adverts-questionnaire.test.js +92 -0
- package/tests/appeals/commands/adverts-submission.test.js +188 -0
- package/tests/appeals/commands/has-questionnaire.test.js +3 -3
- package/tests/appeals/commands/has-submission.test.js +62 -1
- package/tests/appeals/commands/s78-questionnaire.test.js +8 -1
- package/tests/appeals/commands/s78-submission.test.js +60 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import Ajv from 'ajv';
|
|
4
|
+
import addFormats from 'ajv-formats';
|
|
5
|
+
import { loadAllSchemasSync } from '../../../src/index.js';
|
|
6
|
+
|
|
7
|
+
const schema = 'lpa-questionnaire.schema.json';
|
|
8
|
+
|
|
9
|
+
const document = {
|
|
10
|
+
documentId: 'deserunt sint aliqua adipisicing dolore',
|
|
11
|
+
filename: 'ut dolore',
|
|
12
|
+
originalFilename: 'Lorem amet fugiat adipisicing Excepteur',
|
|
13
|
+
size: -90476934,
|
|
14
|
+
mime: 'magna labore exercitation ut',
|
|
15
|
+
documentURI: 'ut reprehenderit',
|
|
16
|
+
dateCreated: '1933-04-03T03:24:38.0Z',
|
|
17
|
+
documentType: 'plansDrawings'
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const exampleAdvertQuestionnaireSchema = {
|
|
21
|
+
casedata: {
|
|
22
|
+
caseType: 'H',
|
|
23
|
+
caseReference: 'nisi incididunt cillum',
|
|
24
|
+
lpaQuestionnaireSubmittedDate: null,
|
|
25
|
+
lpaStatement: 'consequat ex',
|
|
26
|
+
siteAccessDetails: null,
|
|
27
|
+
siteSafetyDetails: null,
|
|
28
|
+
isCorrectAppealType: null,
|
|
29
|
+
isGreenBelt: null,
|
|
30
|
+
inConservationArea: null,
|
|
31
|
+
newConditionDetails: 'anim sint ut aute',
|
|
32
|
+
notificationMethod: null,
|
|
33
|
+
nearbyCaseReferences: null,
|
|
34
|
+
neighbouringSiteAddresses: [
|
|
35
|
+
{
|
|
36
|
+
neighbouringSiteAddressLine1: 'commodo dolore incididunt',
|
|
37
|
+
neighbouringSiteAddressLine2: 'est voluptate irure aliqua elit',
|
|
38
|
+
neighbouringSiteAddressTown: 'labore aliquip ex incididunt nulla',
|
|
39
|
+
neighbouringSiteAddressCounty: 'enim ut Duis ut ex',
|
|
40
|
+
neighbouringSiteAddressPostcode: 'pariatur',
|
|
41
|
+
neighbouringSiteAccessDetails: 'aliqua irure mollit consequat nisi',
|
|
42
|
+
neighbouringSiteSafetyDetails: null
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
affectedListedBuildingNumbers: [
|
|
46
|
+
'occaecat id aliquip dolore',
|
|
47
|
+
'magna',
|
|
48
|
+
'minim laboris fugiat id aliqua',
|
|
49
|
+
'ullamco quis',
|
|
50
|
+
'voluptate quis'
|
|
51
|
+
],
|
|
52
|
+
lpaCostsAppliedFor: null
|
|
53
|
+
},
|
|
54
|
+
documents: [document]
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
describe('HAS questionnaire command schema', () => {
|
|
58
|
+
const schemas = loadAllSchemasSync();
|
|
59
|
+
const flatSchemas = Object.values(schemas).reduce((a, c) => ({ ...a, ...c }), {});
|
|
60
|
+
const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
|
|
61
|
+
addFormats(ajv);
|
|
62
|
+
|
|
63
|
+
it('should allow valid schema for Advert', () => {
|
|
64
|
+
const validationResult = ajv.validate(schema, exampleAdvertQuestionnaireSchema);
|
|
65
|
+
assert.strictEqual(validationResult, true);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should allow valid schema for CAS Advert', () => {
|
|
69
|
+
const test = structuredClone(exampleAdvertQuestionnaireSchema);
|
|
70
|
+
test.casedata.caseType = 'ZA';
|
|
71
|
+
const validationResult = ajv.validate(schema, test);
|
|
72
|
+
assert.strictEqual(validationResult, true);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should reject missing caseReference', () => {
|
|
76
|
+
const test = structuredClone(exampleAdvertQuestionnaireSchema);
|
|
77
|
+
delete test.casedata.caseReference;
|
|
78
|
+
const validationResult = ajv.validate(schema, test);
|
|
79
|
+
assert.strictEqual(validationResult, false);
|
|
80
|
+
assert.strictEqual(
|
|
81
|
+
ajv.errors.some((x) => x.message === "must have required property 'caseReference'"),
|
|
82
|
+
true
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should allow additional props', () => {
|
|
87
|
+
const test = structuredClone(exampleAdvertQuestionnaireSchema);
|
|
88
|
+
test.test = 1;
|
|
89
|
+
const validationResult = ajv.validate(schema, test);
|
|
90
|
+
assert.strictEqual(validationResult, true);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import Ajv from 'ajv';
|
|
4
|
+
import addFormats from 'ajv-formats';
|
|
5
|
+
import { loadAllSchemasSync } from '../../../src/index.js';
|
|
6
|
+
|
|
7
|
+
const schema = 'appellant-submission.schema.json';
|
|
8
|
+
|
|
9
|
+
const user = {
|
|
10
|
+
salutation: 'nisi aute tempor Ut',
|
|
11
|
+
firstName: null,
|
|
12
|
+
lastName: null,
|
|
13
|
+
emailAddress: null,
|
|
14
|
+
telephoneNumber: 'irure',
|
|
15
|
+
organisation: null,
|
|
16
|
+
serviceUserType: 'Appellant'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const document = {
|
|
20
|
+
documentId: 'Lorem',
|
|
21
|
+
filename: 'sunt',
|
|
22
|
+
originalFilename: 'dolore fugiat',
|
|
23
|
+
size: 663667,
|
|
24
|
+
mime: 'consequat veniam ipsum ullamco sint',
|
|
25
|
+
documentURI: 'reprehenderit',
|
|
26
|
+
dateCreated: '1904-04-10T14:53:32.0Z',
|
|
27
|
+
documentType: 'appellantCaseWithdrawalLetter'
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const exampleAdvertSubmissionSchema = {
|
|
31
|
+
casedata: {
|
|
32
|
+
submissionId: '072a9b08-0266-a291-ecd0-bb0ded9d7350',
|
|
33
|
+
caseType: 'H',
|
|
34
|
+
caseProcedure: 'written',
|
|
35
|
+
lpaCode: 'in laborum pariatur cupidatat',
|
|
36
|
+
caseSubmittedDate: '1920-12-06T17:37:12.0Z',
|
|
37
|
+
enforcementNotice: false,
|
|
38
|
+
applicationReference: 'voluptate esse Excepteur veniam sunt',
|
|
39
|
+
applicationDate: '1921-01-26T02:05:56.0Z',
|
|
40
|
+
applicationDecision: 'not_received',
|
|
41
|
+
applicationDecisionDate: '1890-12-26T17:09:36.0Z',
|
|
42
|
+
caseSubmissionDueDate: null,
|
|
43
|
+
siteAddressLine1: 'exercitation incididunt laborum',
|
|
44
|
+
siteAddressLine2: 'in Ut voluptate ea',
|
|
45
|
+
siteAddressTown: 'Lorem amet consectetur',
|
|
46
|
+
siteAddressCounty: null,
|
|
47
|
+
siteAddressPostcode: 'sunt nulla aliquip labore',
|
|
48
|
+
siteGridReferenceEasting: '357144',
|
|
49
|
+
siteGridReferenceNorthing: '400534',
|
|
50
|
+
siteAccessDetails: null,
|
|
51
|
+
siteSafetyDetails: ['Duis laboris ex', 'sint Lorem cupidatat commodo'],
|
|
52
|
+
isGreenBelt: null,
|
|
53
|
+
siteAreaSquareMetres: -11383801.18983768,
|
|
54
|
+
floorSpaceSquareMetres: -69227017.16474937,
|
|
55
|
+
ownsAllLand: null,
|
|
56
|
+
ownsSomeLand: null,
|
|
57
|
+
knowsOtherOwners: null,
|
|
58
|
+
knowsAllOwners: null,
|
|
59
|
+
advertisedAppeal: true,
|
|
60
|
+
ownersInformed: null,
|
|
61
|
+
originalDevelopmentDescription: null,
|
|
62
|
+
changedDevelopmentDescription: false,
|
|
63
|
+
nearbyCaseReferences: [
|
|
64
|
+
'enim consectetur irure ad',
|
|
65
|
+
'irure ut',
|
|
66
|
+
'irure eiusmod minim Excepteur id',
|
|
67
|
+
'aliqua pariatur consectetur eiusmod'
|
|
68
|
+
],
|
|
69
|
+
neighbouringSiteAddresses: null,
|
|
70
|
+
appellantCostsAppliedFor: true,
|
|
71
|
+
hasLandownersPermission: true,
|
|
72
|
+
isAdvertInPosition: true,
|
|
73
|
+
isSiteOnHighwayLand: true
|
|
74
|
+
},
|
|
75
|
+
documents: [document],
|
|
76
|
+
users: [user]
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
describe('Advert submission command schema', () => {
|
|
80
|
+
const schemas = loadAllSchemasSync();
|
|
81
|
+
const flatSchemas = Object.values(schemas).reduce((a, c) => ({ ...a, ...c }), {});
|
|
82
|
+
const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
|
|
83
|
+
addFormats(ajv);
|
|
84
|
+
|
|
85
|
+
it('should allow valid schema for Advert', () => {
|
|
86
|
+
const validationResult = ajv.validate(schema, exampleAdvertSubmissionSchema);
|
|
87
|
+
assert.strictEqual(validationResult, true);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should allow valid schema for CAS Advert', () => {
|
|
91
|
+
const test = structuredClone(exampleAdvertSubmissionSchema);
|
|
92
|
+
test.casedata.caseType = 'ZA';
|
|
93
|
+
|
|
94
|
+
const validationResult = ajv.validate(schema, test);
|
|
95
|
+
|
|
96
|
+
assert.strictEqual(validationResult, true);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should enforce advert specific props', () => {
|
|
100
|
+
const test = structuredClone(exampleAdvertSubmissionSchema);
|
|
101
|
+
delete test.casedata.hasLandownersPermission;
|
|
102
|
+
delete test.casedata.isAdvertInPosition;
|
|
103
|
+
delete test.casedata.isSiteOnHighwayLand;
|
|
104
|
+
|
|
105
|
+
const validationResult = ajv.validate(schema, test);
|
|
106
|
+
|
|
107
|
+
assert.strictEqual(validationResult, false);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should enforce eastings-northings pattern', () => {
|
|
111
|
+
const invalidPatterns = [
|
|
112
|
+
{ easting: 'abc123', northing: '400534', description: 'easting with letters' },
|
|
113
|
+
{ easting: '1234567', northing: '400534', description: 'easting too long' },
|
|
114
|
+
{ easting: '12345', northing: '400534', description: 'easting too short' },
|
|
115
|
+
{ easting: '357144', northing: 'xyz123', description: 'northing with letters' },
|
|
116
|
+
{ easting: '357144', northing: '1234567', description: 'northing too long' },
|
|
117
|
+
{ easting: '357144', northing: '12345', description: 'northing too short' },
|
|
118
|
+
{ easting: '', northing: '400534', description: 'empty easting' },
|
|
119
|
+
{ easting: '357144', northing: '', description: 'empty northing' }
|
|
120
|
+
];
|
|
121
|
+
|
|
122
|
+
for (const pattern of invalidPatterns) {
|
|
123
|
+
const test = structuredClone(exampleAdvertSubmissionSchema);
|
|
124
|
+
test.casedata.siteGridReferenceEasting = pattern.easting;
|
|
125
|
+
test.casedata.siteGridReferenceNorthing = pattern.northing;
|
|
126
|
+
|
|
127
|
+
const validationResult = ajv.validate(schema, test);
|
|
128
|
+
assert.strictEqual(validationResult, false, `Expected validation to fail for ${pattern.description}`);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should allow only eastings-northings', () => {
|
|
133
|
+
const test = structuredClone(exampleAdvertSubmissionSchema);
|
|
134
|
+
test.casedata.siteAddressPostcode = undefined;
|
|
135
|
+
test.casedata.siteAddressLine1 = null;
|
|
136
|
+
test.casedata.siteAddressTown = null;
|
|
137
|
+
const validationResult = ajv.validate(schema, test);
|
|
138
|
+
assert.strictEqual(validationResult, true);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should allow only site address', () => {
|
|
142
|
+
const test = structuredClone(exampleAdvertSubmissionSchema);
|
|
143
|
+
test.casedata.siteGridReferenceEasting = undefined;
|
|
144
|
+
test.casedata.siteGridReferenceNorthing = null;
|
|
145
|
+
const validationResult = ajv.validate(schema, test);
|
|
146
|
+
assert.strictEqual(validationResult, true);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('should enforce either site address or easting-northing', () => {
|
|
150
|
+
const test = structuredClone(exampleAdvertSubmissionSchema);
|
|
151
|
+
test.casedata.siteAddressPostcode = undefined;
|
|
152
|
+
test.casedata.siteAddressLine1 = null;
|
|
153
|
+
test.casedata.siteAddressTown = null;
|
|
154
|
+
test.casedata.siteGridReferenceEasting = undefined;
|
|
155
|
+
test.casedata.siteGridReferenceNorthing = null;
|
|
156
|
+
const validationResult = ajv.validate(schema, test);
|
|
157
|
+
assert.strictEqual(validationResult, false);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should reject missing root property', () => {
|
|
161
|
+
const test = structuredClone(exampleAdvertSubmissionSchema);
|
|
162
|
+
delete test.casedata.caseType;
|
|
163
|
+
const validationResult = ajv.validate(schema, test);
|
|
164
|
+
assert.strictEqual(validationResult, false);
|
|
165
|
+
assert.strictEqual(
|
|
166
|
+
ajv.errors.some((x) => x.message === "must have required property 'caseType'"),
|
|
167
|
+
true
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should reject missing nested property', () => {
|
|
172
|
+
const test = structuredClone(exampleAdvertSubmissionSchema);
|
|
173
|
+
delete test.casedata.caseProcedure;
|
|
174
|
+
const validationResult = ajv.validate(schema, test);
|
|
175
|
+
assert.strictEqual(validationResult, false);
|
|
176
|
+
assert.strictEqual(
|
|
177
|
+
ajv.errors.some((x) => x.message === "must have required property 'caseProcedure'"),
|
|
178
|
+
true
|
|
179
|
+
);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('should allow additional props', () => {
|
|
183
|
+
const test = structuredClone(exampleAdvertSubmissionSchema);
|
|
184
|
+
test.test = 1;
|
|
185
|
+
const validationResult = ajv.validate(schema, test);
|
|
186
|
+
assert.strictEqual(validationResult, true);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
@@ -60,14 +60,14 @@ describe('HAS questionnaire command schema', () => {
|
|
|
60
60
|
const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
|
|
61
61
|
addFormats(ajv);
|
|
62
62
|
|
|
63
|
-
it('should allow valid HAS
|
|
63
|
+
it('should allow valid schema for HAS', () => {
|
|
64
64
|
const validationResult = ajv.validate(schema, exampleHasQuestionnaireSchema);
|
|
65
65
|
assert.strictEqual(validationResult, true);
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
it('should allow
|
|
68
|
+
it('should allow valid schema for CAS planning', () => {
|
|
69
69
|
const test = structuredClone(exampleHasQuestionnaireSchema);
|
|
70
|
-
|
|
70
|
+
test.casedata.caseType = 'ZP';
|
|
71
71
|
const validationResult = ajv.validate(schema, test);
|
|
72
72
|
assert.strictEqual(validationResult, true);
|
|
73
73
|
});
|
|
@@ -45,6 +45,8 @@ const exampleHasSubmissionSchema = {
|
|
|
45
45
|
siteAddressTown: 'Lorem amet consectetur',
|
|
46
46
|
siteAddressCounty: null,
|
|
47
47
|
siteAddressPostcode: 'sunt nulla aliquip labore',
|
|
48
|
+
siteGridReferenceEasting: '357144',
|
|
49
|
+
siteGridReferenceNorthing: '400534',
|
|
48
50
|
siteAccessDetails: null,
|
|
49
51
|
siteSafetyDetails: ['Duis laboris ex', 'sint Lorem cupidatat commodo'],
|
|
50
52
|
isGreenBelt: null,
|
|
@@ -77,11 +79,70 @@ describe('HAS submission command schema', () => {
|
|
|
77
79
|
const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
|
|
78
80
|
addFormats(ajv);
|
|
79
81
|
|
|
80
|
-
it('should allow valid HAS
|
|
82
|
+
it('should allow valid schema for HAS', () => {
|
|
81
83
|
const validationResult = ajv.validate(schema, exampleHasSubmissionSchema);
|
|
82
84
|
assert.strictEqual(validationResult, true);
|
|
83
85
|
});
|
|
84
86
|
|
|
87
|
+
it('should allow valid schema for CAS planning', () => {
|
|
88
|
+
const test = structuredClone(exampleHasSubmissionSchema);
|
|
89
|
+
test.casedata.caseType = 'ZP';
|
|
90
|
+
|
|
91
|
+
const validationResult = ajv.validate(schema, test);
|
|
92
|
+
|
|
93
|
+
assert.strictEqual(validationResult, true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should enforce eastings-northings pattern', () => {
|
|
97
|
+
const invalidPatterns = [
|
|
98
|
+
{ easting: 'abc123', northing: '400534', description: 'easting with letters' },
|
|
99
|
+
{ easting: '1234567', northing: '400534', description: 'easting too long' },
|
|
100
|
+
{ easting: '12345', northing: '400534', description: 'easting too short' },
|
|
101
|
+
{ easting: '357144', northing: 'xyz123', description: 'northing with letters' },
|
|
102
|
+
{ easting: '357144', northing: '1234567', description: 'northing too long' },
|
|
103
|
+
{ easting: '357144', northing: '12345', description: 'northing too short' },
|
|
104
|
+
{ easting: '', northing: '400534', description: 'empty easting' },
|
|
105
|
+
{ easting: '357144', northing: '', description: 'empty northing' }
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
for (const pattern of invalidPatterns) {
|
|
109
|
+
const test = structuredClone(exampleHasSubmissionSchema);
|
|
110
|
+
test.casedata.siteGridReferenceEasting = pattern.easting;
|
|
111
|
+
test.casedata.siteGridReferenceNorthing = pattern.northing;
|
|
112
|
+
|
|
113
|
+
const validationResult = ajv.validate(schema, test);
|
|
114
|
+
assert.strictEqual(validationResult, false, `Expected validation to fail for ${pattern.description}`);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should allow only eastings-northings', () => {
|
|
119
|
+
const test = structuredClone(exampleHasSubmissionSchema);
|
|
120
|
+
test.casedata.siteAddressPostcode = undefined;
|
|
121
|
+
test.casedata.siteAddressLine1 = null;
|
|
122
|
+
test.casedata.siteAddressTown = null;
|
|
123
|
+
const validationResult = ajv.validate(schema, test);
|
|
124
|
+
assert.strictEqual(validationResult, true);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should allow only site address', () => {
|
|
128
|
+
const test = structuredClone(exampleHasSubmissionSchema);
|
|
129
|
+
test.casedata.siteGridReferenceEasting = undefined;
|
|
130
|
+
test.casedata.siteGridReferenceNorthing = null;
|
|
131
|
+
const validationResult = ajv.validate(schema, test);
|
|
132
|
+
assert.strictEqual(validationResult, true);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should enforce either site address or easting-northing', () => {
|
|
136
|
+
const test = structuredClone(exampleHasSubmissionSchema);
|
|
137
|
+
test.casedata.siteAddressPostcode = undefined;
|
|
138
|
+
test.casedata.siteAddressLine1 = null;
|
|
139
|
+
test.casedata.siteAddressTown = null;
|
|
140
|
+
test.casedata.siteGridReferenceEasting = undefined;
|
|
141
|
+
test.casedata.siteGridReferenceNorthing = null;
|
|
142
|
+
const validationResult = ajv.validate(schema, test);
|
|
143
|
+
assert.strictEqual(validationResult, false);
|
|
144
|
+
});
|
|
145
|
+
|
|
85
146
|
it('should reject missing root property', () => {
|
|
86
147
|
const test = structuredClone(exampleHasSubmissionSchema);
|
|
87
148
|
delete test.casedata.caseType;
|
|
@@ -71,11 +71,18 @@ describe('S78 questionnaire command schema', () => {
|
|
|
71
71
|
const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
|
|
72
72
|
addFormats(ajv);
|
|
73
73
|
|
|
74
|
-
it('should allow valid
|
|
74
|
+
it('should allow valid schema for S78', () => {
|
|
75
75
|
const validationResult = ajv.validate(schema, exampleS78QuestionnaireSchema);
|
|
76
76
|
assert.strictEqual(validationResult, true);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
+
it('should allow valid schema for S20', () => {
|
|
80
|
+
const test = structuredClone(exampleS78QuestionnaireSchema);
|
|
81
|
+
test.casedata.caseType = 'Y';
|
|
82
|
+
const validationResult = ajv.validate(schema, test);
|
|
83
|
+
assert.strictEqual(validationResult, true);
|
|
84
|
+
});
|
|
85
|
+
|
|
79
86
|
it('should reject missing caseReference', () => {
|
|
80
87
|
const test = structuredClone(exampleS78QuestionnaireSchema);
|
|
81
88
|
delete test.casedata.caseReference;
|
|
@@ -45,6 +45,8 @@ const exampleS78SubmissionSchema = {
|
|
|
45
45
|
siteAddressTown: 'et',
|
|
46
46
|
siteAddressCounty: 'velit',
|
|
47
47
|
siteAddressPostcode: 'nisi minim laboris sed',
|
|
48
|
+
siteGridReferenceEasting: '357144',
|
|
49
|
+
siteGridReferenceNorthing: '400534',
|
|
48
50
|
siteAccessDetails: ['laborum', 'aute velit quis', 'dolor'],
|
|
49
51
|
siteSafetyDetails: ['velit aliqua', 'qui', 'tempor Duis ut dolore', 'anim Ut in ea', 'eiusmod laborum'],
|
|
50
52
|
neighbouringSiteAddresses: null,
|
|
@@ -83,11 +85,68 @@ describe('S78 submission command schema', () => {
|
|
|
83
85
|
const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
|
|
84
86
|
addFormats(ajv);
|
|
85
87
|
|
|
86
|
-
it('should allow valid S78
|
|
88
|
+
it('should allow valid schema for S78', () => {
|
|
87
89
|
const validationResult = ajv.validate(schema, exampleS78SubmissionSchema);
|
|
88
90
|
assert.strictEqual(validationResult, true);
|
|
89
91
|
});
|
|
90
92
|
|
|
93
|
+
it('should allow valid schema for S20', () => {
|
|
94
|
+
const test = structuredClone(exampleS78SubmissionSchema);
|
|
95
|
+
test.casedata.caseType = 'Y';
|
|
96
|
+
const validationResult = ajv.validate(schema, test);
|
|
97
|
+
assert.strictEqual(validationResult, true);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should enforce eastings-northings pattern', () => {
|
|
101
|
+
const invalidPatterns = [
|
|
102
|
+
{ easting: 'abc123', northing: '400534', description: 'easting with letters' },
|
|
103
|
+
{ easting: '1234567', northing: '400534', description: 'easting too long' },
|
|
104
|
+
{ easting: '12345', northing: '400534', description: 'easting too short' },
|
|
105
|
+
{ easting: '357144', northing: 'xyz123', description: 'northing with letters' },
|
|
106
|
+
{ easting: '357144', northing: '1234567', description: 'northing too long' },
|
|
107
|
+
{ easting: '357144', northing: '12345', description: 'northing too short' },
|
|
108
|
+
{ easting: '', northing: '400534', description: 'empty easting' },
|
|
109
|
+
{ easting: '357144', northing: '', description: 'empty northing' }
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
for (const pattern of invalidPatterns) {
|
|
113
|
+
const test = structuredClone(exampleS78SubmissionSchema);
|
|
114
|
+
test.casedata.siteGridReferenceEasting = pattern.easting;
|
|
115
|
+
test.casedata.siteGridReferenceNorthing = pattern.northing;
|
|
116
|
+
|
|
117
|
+
const validationResult = ajv.validate(schema, test);
|
|
118
|
+
assert.strictEqual(validationResult, false, `Expected validation to fail for ${pattern.description}`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should allow only eastings-northings', () => {
|
|
123
|
+
const test = structuredClone(exampleS78SubmissionSchema);
|
|
124
|
+
test.casedata.siteAddressPostcode = undefined;
|
|
125
|
+
test.casedata.siteAddressLine1 = null;
|
|
126
|
+
test.casedata.siteAddressTown = null;
|
|
127
|
+
const validationResult = ajv.validate(schema, test);
|
|
128
|
+
assert.strictEqual(validationResult, true);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should allow only site address', () => {
|
|
132
|
+
const test = structuredClone(exampleS78SubmissionSchema);
|
|
133
|
+
test.casedata.siteGridReferenceEasting = undefined;
|
|
134
|
+
test.casedata.siteGridReferenceNorthing = null;
|
|
135
|
+
const validationResult = ajv.validate(schema, test);
|
|
136
|
+
assert.strictEqual(validationResult, true);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should enforce either site address or easting-northing', () => {
|
|
140
|
+
const test = structuredClone(exampleS78SubmissionSchema);
|
|
141
|
+
test.casedata.siteAddressPostcode = undefined;
|
|
142
|
+
test.casedata.siteAddressLine1 = null;
|
|
143
|
+
test.casedata.siteAddressTown = null;
|
|
144
|
+
test.casedata.siteGridReferenceEasting = undefined;
|
|
145
|
+
test.casedata.siteGridReferenceNorthing = null;
|
|
146
|
+
const validationResult = ajv.validate(schema, test);
|
|
147
|
+
assert.strictEqual(validationResult, false);
|
|
148
|
+
});
|
|
149
|
+
|
|
91
150
|
it('should reject missing root property', () => {
|
|
92
151
|
const test = structuredClone(exampleS78SubmissionSchema);
|
|
93
152
|
delete test.casedata.caseType;
|