@planning-inspectorate/data-model 1.16.1 → 1.18.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.
@@ -0,0 +1,243 @@
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 = 'appeal-has.schema.json';
8
+
9
+ const appealHas = {
10
+ caseId: null,
11
+ caseReference: 'mollit dolore dolor non culpa',
12
+ submissionId: null,
13
+ caseStatus: 'ready_to_start',
14
+ caseType: 'ZP',
15
+ caseProcedure: 'inquiry',
16
+ lpaCode: 'nulla',
17
+ caseOfficerId: null,
18
+ inspectorId: 'mollit in ullamco Excepteur commodo',
19
+ allocationLevel: 'D',
20
+ allocationBand: 1,
21
+ caseSpecialisms: ['et culpa elit labore', 'minim Lorem'],
22
+ caseSubmittedDate: '1954-03-03T08:10:46.0Z',
23
+ caseCreatedDate: '1945-04-11T07:49:09.0Z',
24
+ caseUpdatedDate: '1943-02-10T21:16:10.0Z',
25
+ caseValidDate: '1902-04-09T20:34:25.0Z',
26
+ caseValidationDate: null,
27
+ caseValidationOutcome: 'invalid',
28
+ caseValidationInvalidDetails: null,
29
+ caseValidationIncompleteDetails: [
30
+ 'occaecat dolor labore ut ipsum',
31
+ 'eiusmod ullamco pariatur aliqua esse',
32
+ 'eiusmod Ut officia',
33
+ 'aute',
34
+ 'do minim sint labore aliquip'
35
+ ],
36
+ caseExtensionDate: null,
37
+ caseStartedDate: null,
38
+ casePublishedDate: null,
39
+ linkedCaseStatus: null,
40
+ leadCaseReference: null,
41
+ lpaQuestionnaireDueDate: null,
42
+ lpaQuestionnaireSubmittedDate: null,
43
+ lpaQuestionnaireCreatedDate: '1916-11-15T14:22:37.0Z',
44
+ lpaQuestionnairePublishedDate: '1895-10-01T01:14:29.0Z',
45
+ lpaQuestionnaireValidationOutcome: 'incomplete',
46
+ lpaQuestionnaireValidationOutcomeDate: '1927-05-30T20:34:18.0Z',
47
+ lpaQuestionnaireValidationDetails: ['dolore cillum in anim adipisicing'],
48
+ lpaStatement: 'Ut ipsum et',
49
+ caseWithdrawnDate: '1926-02-11T13:40:53.0Z',
50
+ caseTransferredDate: '1923-01-28T02:09:32.0Z',
51
+ transferredCaseClosedDate: '1893-02-13T14:37:27.0Z',
52
+ caseDecisionOutcomeDate: '1920-07-08T09:20:22.0Z',
53
+ caseDecisionPublishedDate: null,
54
+ caseDecisionOutcome: 'dismissed',
55
+ caseCompletedDate: '1895-12-07T15:44:32.0Z',
56
+ enforcementNotice: null,
57
+ applicationReference: 'eu',
58
+ applicationDate: '1949-08-25T15:11:02.0Z',
59
+ applicationDecision: 'refused',
60
+ applicationDecisionDate: '1952-08-09T01:03:51.0Z',
61
+ caseSubmissionDueDate: '1942-02-09T21:03:07.0Z',
62
+ siteAddressLine1: 'ullamco',
63
+ siteAddressLine2: null,
64
+ siteAddressTown: 'dolor reprehenderit ut',
65
+ siteAddressCounty: 'dolore eu exercitation enim',
66
+ siteAddressPostcode: 'est',
67
+ siteAccessDetails: [
68
+ 'Ut',
69
+ 'eiusmod magna aliqua ipsum',
70
+ 'sit non ut amet aliqua',
71
+ 'id consectetur cupidatat',
72
+ 'incididunt ut Lorem eu'
73
+ ],
74
+ siteSafetyDetails: null,
75
+ siteAreaSquareMetres: 74995933.47978675,
76
+ floorSpaceSquareMetres: null,
77
+ isCorrectAppealType: null,
78
+ isGreenBelt: true,
79
+ inConservationArea: null,
80
+ affectsScheduledMonument: true,
81
+ hasProtectedSpecies: true,
82
+ isAonbNationalLandscape: null,
83
+ isSiteOnHighwayLand: null,
84
+ designatedSitesNames: null,
85
+ hasInfrastructureLevy: false,
86
+ isInfrastructureLevyFormallyAdopted: false,
87
+ infrastructureLevyAdoptedDate: null,
88
+ infrastructureLevyExpectedDate: null,
89
+ lpaProcedurePreference: null,
90
+ lpaProcedurePreferenceDetails: null,
91
+ lpaProcedurePreferenceDuration: -42778389.82228377,
92
+ caseworkReason: 'elit reprehenderit',
93
+ importantInformation: null,
94
+ jurisdiction: null,
95
+ redeterminedIndicator: null,
96
+ dateCostsReportDespatched: '1918-01-30T08:43:51.0Z',
97
+ dateNotRecoveredOrDerecovered: '1950-02-18T19:15:57.0Z',
98
+ dateRecovered: '1962-01-16T13:45:38.0Z',
99
+ originalCaseDecisionDate: null,
100
+ targetDate: null,
101
+ ownsAllLand: true,
102
+ ownsSomeLand: null,
103
+ knowsOtherOwners: 'Some',
104
+ knowsAllOwners: null,
105
+ advertisedAppeal: null,
106
+ notificationMethod: null,
107
+ ownersInformed: null,
108
+ originalDevelopmentDescription: null,
109
+ changedDevelopmentDescription: null,
110
+ newConditionDetails: 'tempor anim adipisicing',
111
+ nearbyCaseReferences: null,
112
+ neighbouringSiteAddresses: [
113
+ {
114
+ neighbouringSiteAddressLine1: 'eu veniam',
115
+ neighbouringSiteAddressLine2: null,
116
+ neighbouringSiteAddressTown: 'pariatur dolore',
117
+ neighbouringSiteAddressCounty: 'fugiat minim anim aliqua aliquip',
118
+ neighbouringSiteAddressPostcode: 'ex anim',
119
+ neighbouringSiteAccessDetails: null,
120
+ neighbouringSiteSafetyDetails: 'veniam in sunt'
121
+ },
122
+ {
123
+ neighbouringSiteAddressLine1: 'et adipisicing dolore',
124
+ neighbouringSiteAddressLine2: null,
125
+ neighbouringSiteAddressTown: 'cupidatat dolore',
126
+ neighbouringSiteAddressCounty: null,
127
+ neighbouringSiteAddressPostcode: 'cupidatat voluptate esse ad amet',
128
+ neighbouringSiteAccessDetails: 'labore',
129
+ neighbouringSiteSafetyDetails: 'deserunt fugiat'
130
+ },
131
+ {
132
+ neighbouringSiteAddressLine1: 'esse in pariatur mollit',
133
+ neighbouringSiteAddressLine2: 'ad aliquip in',
134
+ neighbouringSiteAddressTown: 'ullamco',
135
+ neighbouringSiteAddressCounty: 'ut aute',
136
+ neighbouringSiteAddressPostcode: 'Lorem nostrud ipsum aliquip',
137
+ neighbouringSiteAccessDetails: 'dolore irure nisi',
138
+ neighbouringSiteSafetyDetails: 'ex'
139
+ },
140
+ {
141
+ neighbouringSiteAddressLine1: 'est pariatur Lorem minim in',
142
+ neighbouringSiteAddressLine2: 'Ut',
143
+ neighbouringSiteAddressTown: 'eiusmod minim nostrud Excepteur nulla',
144
+ neighbouringSiteAddressCounty: 'officia',
145
+ neighbouringSiteAddressPostcode: 'non deserunt',
146
+ neighbouringSiteAccessDetails: null,
147
+ neighbouringSiteSafetyDetails: 'culpa occaecat'
148
+ },
149
+ {
150
+ neighbouringSiteAddressLine1: 'minim cillum eu tempor et',
151
+ neighbouringSiteAddressLine2: 'non adipisicing nisi in dolore',
152
+ neighbouringSiteAddressTown: 'irure in',
153
+ neighbouringSiteAddressCounty: null,
154
+ neighbouringSiteAddressPostcode: 'commodo in et Excepteur',
155
+ neighbouringSiteAccessDetails: null,
156
+ neighbouringSiteSafetyDetails: 'ex pariatur enim ipsum voluptate'
157
+ }
158
+ ],
159
+ reasonForNeighbourVisits: null,
160
+ affectedListedBuildingNumbers: ['Excepteur', 'in consequat sit', 'esse sunt velit culpa', 'voluptate esse'],
161
+ appellantCostsAppliedFor: null,
162
+ lpaCostsAppliedFor: null,
163
+ typeOfPlanningApplication: 'householder-planning',
164
+ siteGridReferenceEasting: '357144',
165
+ siteGridReferenceNorthing: '400534',
166
+ hasLandownersPermission: null,
167
+ isAdvertInPosition: false,
168
+ isSiteInAreaOfSpecialControlAdverts: false,
169
+ wasApplicationRefusedDueToHighwayOrTraffic: null,
170
+ didAppellantSubmitCompletePhotosAndPlans: null,
171
+ advertType: null
172
+ };
173
+
174
+ describe(schema, () => {
175
+ const schemas = loadAllSchemasSync();
176
+ const flatSchemas = Object.values(schemas).reduce((a, c) => ({ ...a, ...c }), {});
177
+ const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
178
+ addFormats(ajv);
179
+
180
+ it('should allow valid schema', () => {
181
+ const test = structuredClone(appealHas);
182
+
183
+ const validationResult = ajv.validate(schema, test);
184
+ assert.strictEqual(validationResult, true);
185
+ });
186
+
187
+ it('should enforce eastings-northings pattern', () => {
188
+ const invalidPatterns = [
189
+ { easting: 'abc123', northing: '400534', description: 'easting with letters' },
190
+ { easting: '1234567', northing: '400534', description: 'easting too long' },
191
+ { easting: '12345', northing: '400534', description: 'easting too short' },
192
+ { easting: '357144', northing: 'xyz123', description: 'northing with letters' },
193
+ { easting: '357144', northing: '1234567', description: 'northing too long' },
194
+ { easting: '357144', northing: '12345', description: 'northing too short' },
195
+ { easting: '', northing: '400534', description: 'empty easting' },
196
+ { easting: '357144', northing: '', description: 'empty northing' }
197
+ ];
198
+
199
+ for (const pattern of invalidPatterns) {
200
+ const test = structuredClone(appealHas);
201
+ test.siteGridReferenceEasting = pattern.easting;
202
+ test.siteGridReferenceNorthing = pattern.northing;
203
+
204
+ const validationResult = ajv.validate(schema, test);
205
+ assert.strictEqual(validationResult, false, `Expected validation to fail for ${pattern.description}`);
206
+ }
207
+ });
208
+
209
+ it('should allow only eastings-northings', () => {
210
+ const test = structuredClone(appealHas);
211
+ test.siteAddressPostcode = undefined;
212
+ test.siteAddressLine1 = null;
213
+ test.siteAddressTown = null;
214
+ const validationResult = ajv.validate(schema, test);
215
+ assert.strictEqual(validationResult, true);
216
+ });
217
+
218
+ it('should allow only site address', () => {
219
+ const test = structuredClone(appealHas);
220
+ test.siteGridReferenceEasting = undefined;
221
+ test.siteGridReferenceNorthing = null;
222
+ const validationResult = ajv.validate(schema, test);
223
+ assert.strictEqual(validationResult, true);
224
+ });
225
+
226
+ it('should enforce either site address or easting-northing', () => {
227
+ const test = structuredClone(appealHas);
228
+ test.siteAddressPostcode = undefined;
229
+ test.siteAddressLine1 = null;
230
+ test.siteAddressTown = null;
231
+ test.siteGridReferenceEasting = undefined;
232
+ test.siteGridReferenceNorthing = null;
233
+ const validationResult = ajv.validate(schema, test);
234
+ assert.strictEqual(validationResult, false);
235
+ });
236
+
237
+ it('should allow additional props', () => {
238
+ const test = structuredClone(appealHas);
239
+ test.test = 1; // additional unknown prop allowed
240
+ const validationResult = ajv.validate(schema, test);
241
+ assert.strictEqual(validationResult, true);
242
+ });
243
+ });
@@ -0,0 +1,227 @@
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 = 'appeal-s78.schema.json';
8
+
9
+ const appealS78 = {
10
+ caseId: 96989394,
11
+ caseReference: 'exercitation dolore',
12
+ submissionId: null,
13
+ caseStatus: 'transferred',
14
+ caseType: 'D',
15
+ caseProcedure: 'inquiry',
16
+ lpaCode: 'pariatur cillum non',
17
+ caseOfficerId: null,
18
+ inspectorId: 'amet magna dolor in labore',
19
+ allocationLevel: null,
20
+ allocationBand: null,
21
+ caseSpecialisms: ['laboris est proident minim', 'qui sunt ut', 'consectetur Lorem do sunt aliquip'],
22
+ caseSubmittedDate: '1907-08-17T13:18:33.0Z',
23
+ caseCreatedDate: '1906-08-08T04:49:02.0Z',
24
+ caseUpdatedDate: '1945-02-11T12:49:58.0Z',
25
+ caseValidDate: null,
26
+ caseValidationDate: null,
27
+ caseValidationOutcome: 'invalid',
28
+ caseValidationInvalidDetails: null,
29
+ caseValidationIncompleteDetails: null,
30
+ caseExtensionDate: null,
31
+ caseStartedDate: '1905-07-12T15:31:22.0Z',
32
+ casePublishedDate: null,
33
+ linkedCaseStatus: 'lead',
34
+ leadCaseReference: null,
35
+ lpaQuestionnaireDueDate: null,
36
+ lpaQuestionnaireSubmittedDate: null,
37
+ lpaQuestionnaireCreatedDate: '1956-11-08T15:53:10.0Z',
38
+ lpaQuestionnairePublishedDate: '1951-09-03T07:25:19.0Z',
39
+ lpaQuestionnaireValidationOutcome: null,
40
+ lpaQuestionnaireValidationOutcomeDate: null,
41
+ lpaQuestionnaireValidationDetails: ['cupidatat dolore in', 'officia in nostrud non', 'eu amet velit labore aute'],
42
+ lpaStatement: 'ipsum consectetur labore pariatur',
43
+ caseWithdrawnDate: '1941-07-27T04:17:40.0Z',
44
+ caseTransferredDate: null,
45
+ transferredCaseClosedDate: null,
46
+ caseDecisionOutcomeDate: '1916-07-25T07:02:27.0Z',
47
+ caseDecisionPublishedDate: null,
48
+ caseDecisionOutcome: 'invalid',
49
+ caseCompletedDate: '1921-06-04T06:12:04.0Z',
50
+ enforcementNotice: null,
51
+ applicationReference: 'consequat ullamco in aute amet',
52
+ applicationDate: '1910-07-16T04:24:14.0Z',
53
+ applicationDecision: 'not_received',
54
+ applicationDecisionDate: null,
55
+ caseSubmissionDueDate: null,
56
+ siteAddressLine1: 'dolore mollit',
57
+ siteAddressLine2: null,
58
+ siteAddressTown: 'in',
59
+ siteAddressCounty: 'ut incididunt velit in',
60
+ siteAddressPostcode: 'ut',
61
+ siteAccessDetails: ['ullamco', 'elit in', 'velit officia pariatur mollit', 'nostrud ex culpa'],
62
+ siteSafetyDetails: null,
63
+ siteAreaSquareMetres: 69381079.34849802,
64
+ floorSpaceSquareMetres: null,
65
+ isCorrectAppealType: null,
66
+ isGreenBelt: false,
67
+ inConservationArea: null,
68
+ ownsAllLand: null,
69
+ ownsSomeLand: null,
70
+ knowsOtherOwners: null,
71
+ knowsAllOwners: null,
72
+ advertisedAppeal: true,
73
+ notificationMethod: ['notice'],
74
+ ownersInformed: null,
75
+ originalDevelopmentDescription: 'est',
76
+ changedDevelopmentDescription: null,
77
+ newConditionDetails: null,
78
+ nearbyCaseReferences: ['veniam voluptate incididunt Excepteur'],
79
+ neighbouringSiteAddresses: [
80
+ {
81
+ neighbouringSiteAddressLine1: 'laborum',
82
+ neighbouringSiteAddressLine2: null,
83
+ neighbouringSiteAddressTown: 'aute ipsum dolore',
84
+ neighbouringSiteAddressCounty: null,
85
+ neighbouringSiteAddressPostcode: 'dolor ipsum anim fugiat',
86
+ neighbouringSiteAccessDetails: 'reprehenderit mollit Duis exercitation',
87
+ neighbouringSiteSafetyDetails: null
88
+ }
89
+ ],
90
+ reasonForNeighbourVisits: null,
91
+ affectedListedBuildingNumbers: ['tempor adipisicing in'],
92
+ changedListedBuildingNumbers: null,
93
+ preserveGrantLoan: true,
94
+ consultHistoricEngland: false,
95
+ appellantCostsAppliedFor: null,
96
+ lpaCostsAppliedFor: null,
97
+ agriculturalHolding: null,
98
+ tenantAgriculturalHolding: null,
99
+ otherTenantsAgriculturalHolding: null,
100
+ informedTenantsAgriculturalHolding: true,
101
+ appellantProcedurePreference: 'hearing',
102
+ appellantProcedurePreferenceDetails: null,
103
+ appellantProcedurePreferenceDuration: null,
104
+ appellantProcedurePreferenceWitnessCount: null,
105
+ statusPlanningObligation: 'cillum proident fugiat ex quis',
106
+ affectsScheduledMonument: true,
107
+ hasProtectedSpecies: true,
108
+ isAonbNationalLandscape: null,
109
+ designatedSitesNames: null,
110
+ isGypsyOrTravellerSite: false,
111
+ isPublicRightOfWay: true,
112
+ eiaEnvironmentalImpactSchedule: 'schedule-1',
113
+ eiaDevelopmentDescription: 'agriculture-aquaculture',
114
+ eiaSensitiveAreaDetails: 'dolore non anim ut deserunt',
115
+ eiaColumnTwoThreshold: null,
116
+ eiaScreeningOpinion: true,
117
+ eiaRequiresEnvironmentalStatement: null,
118
+ eiaCompletedEnvironmentalStatement: null,
119
+ hasStatutoryConsultees: true,
120
+ consultedBodiesDetails: null,
121
+ hasInfrastructureLevy: null,
122
+ isInfrastructureLevyFormallyAdopted: null,
123
+ infrastructureLevyAdoptedDate: null,
124
+ infrastructureLevyExpectedDate: null,
125
+ lpaProcedurePreference: null,
126
+ lpaProcedurePreferenceDetails: null,
127
+ lpaProcedurePreferenceDuration: 43495666.11228904,
128
+ caseworkReason: 'sit ipsum',
129
+ importantInformation: null,
130
+ jurisdiction: null,
131
+ redeterminedIndicator: null,
132
+ dateCostsReportDespatched: '1951-10-17T06:20:56.0Z',
133
+ dateNotRecoveredOrDerecovered: '1965-01-28T14:22:43.0Z',
134
+ dateRecovered: null,
135
+ originalCaseDecisionDate: '1969-03-09T16:29:08.0Z',
136
+ targetDate: null,
137
+ appellantCommentsSubmittedDate: '1907-11-20T13:42:48.0Z',
138
+ appellantStatementSubmittedDate: null,
139
+ appellantProofsSubmittedDate: '1940-11-26T21:04:12.0Z',
140
+ finalCommentsDueDate: '1945-08-08T17:44:32.0Z',
141
+ interestedPartyRepsDueDate: null,
142
+ lpaCommentsSubmittedDate: '1941-03-28T08:08:45.0Z',
143
+ lpaProofsSubmittedDate: '1949-02-17T05:01:26.0Z',
144
+ lpaStatementSubmittedDate: null,
145
+ proofsOfEvidenceDueDate: '1945-06-24T01:14:05.0Z',
146
+ siteNoticesSentDate: '1904-03-09T08:52:39.0Z',
147
+ statementDueDate: null,
148
+ numberOfResidencesNetChange: 59800248.893144846,
149
+ siteGridReferenceEasting: '357144',
150
+ siteGridReferenceNorthing: '400534',
151
+ siteViewableFromRoad: null,
152
+ siteWithinSSSI: null,
153
+ typeOfPlanningApplication: 'full-appeal',
154
+ developmentType: 'other-minor',
155
+ statementOfCommonGroundDueDate: '1919-10-16T12:35:55.0Z',
156
+ planningObligationDueDate: '1899-04-25T22:23:18.0Z'
157
+ };
158
+
159
+ describe(schema, () => {
160
+ const schemas = loadAllSchemasSync();
161
+ const flatSchemas = Object.values(schemas).reduce((a, c) => ({ ...a, ...c }), {});
162
+ const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
163
+ addFormats(ajv);
164
+
165
+ it('should allow valid schema', () => {
166
+ const test = structuredClone(appealS78);
167
+ const validationResult = ajv.validate(schema, test);
168
+ assert.strictEqual(validationResult, true);
169
+ });
170
+
171
+ it('should enforce eastings-northings pattern', () => {
172
+ const invalidPatterns = [
173
+ { easting: 'abc123', northing: '400534', description: 'easting with letters' },
174
+ { easting: '1234567', northing: '400534', description: 'easting too long' },
175
+ { easting: '12345', northing: '400534', description: 'easting too short' },
176
+ { easting: '357144', northing: 'xyz123', description: 'northing with letters' },
177
+ { easting: '357144', northing: '1234567', description: 'northing too long' },
178
+ { easting: '357144', northing: '12345', description: 'northing too short' },
179
+ { easting: '', northing: '400534', description: 'empty easting' },
180
+ { easting: '357144', northing: '', description: 'empty northing' }
181
+ ];
182
+
183
+ for (const pattern of invalidPatterns) {
184
+ const test = structuredClone(appealS78);
185
+ test.siteGridReferenceEasting = pattern.easting;
186
+ test.siteGridReferenceNorthing = pattern.northing;
187
+
188
+ const validationResult = ajv.validate(schema, test);
189
+ assert.strictEqual(validationResult, false, `Expected validation to fail for ${pattern.description}`);
190
+ }
191
+ });
192
+
193
+ it('should allow only eastings-northings', () => {
194
+ const test = structuredClone(appealS78);
195
+ test.siteAddressPostcode = undefined;
196
+ test.siteAddressLine1 = null;
197
+ test.siteAddressTown = null;
198
+ const validationResult = ajv.validate(schema, test);
199
+ assert.strictEqual(validationResult, true);
200
+ });
201
+
202
+ it('should allow only site address', () => {
203
+ const test = structuredClone(appealS78);
204
+ test.siteGridReferenceEasting = undefined;
205
+ test.siteGridReferenceNorthing = null;
206
+ const validationResult = ajv.validate(schema, test);
207
+ assert.strictEqual(validationResult, true);
208
+ });
209
+
210
+ it('should enforce either site address or easting-northing', () => {
211
+ const test = structuredClone(appealS78);
212
+ test.siteAddressPostcode = undefined;
213
+ test.siteAddressLine1 = null;
214
+ test.siteAddressTown = null;
215
+ test.siteGridReferenceEasting = undefined;
216
+ test.siteGridReferenceNorthing = null;
217
+ const validationResult = ajv.validate(schema, test);
218
+ assert.strictEqual(validationResult, false);
219
+ });
220
+
221
+ it('should allow additional props', () => {
222
+ const test = structuredClone(appealS78);
223
+ test.test = 1; // additional unknown prop allowed
224
+ const validationResult = ajv.validate(schema, test);
225
+ assert.strictEqual(validationResult, true);
226
+ });
227
+ });
@@ -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
+ });