@planning-inspectorate/data-model 1.16.0 → 1.17.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/docs/README.md +2 -2
- package/docs/appeal-has.md +764 -86
- package/docs/appeal-s78.md +55 -133
- package/package.json +1 -1
- package/pins_data_model/models/model_appeal_has.py +647 -8
- package/pins_data_model/models/model_appeal_s78.py +604 -10
- package/schemas/appeal-has.schema.json +161 -9
- package/schemas/appeal-s78.schema.json +81 -125
- package/src/lib/gen-docs.js +4 -2
- package/src/schemas.d.ts +165 -18
- package/tests/appeals/appeal-has.test.js +243 -0
- package/tests/appeals/appeal-s78.test.js +227 -0
package/src/schemas.d.ts
CHANGED
|
@@ -301,9 +301,29 @@ export interface AppealEvent {
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
/**
|
|
304
|
-
* Schema defining the metadata for an appeal
|
|
304
|
+
* Group A - Schema defining the metadata for an appeal
|
|
305
305
|
*/
|
|
306
|
-
export
|
|
306
|
+
export type AppealHASCase = (
|
|
307
|
+
| {
|
|
308
|
+
siteGridReferenceEasting: {
|
|
309
|
+
[k: string]: unknown;
|
|
310
|
+
};
|
|
311
|
+
siteGridReferenceNorthing: {
|
|
312
|
+
[k: string]: unknown;
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
| {
|
|
316
|
+
siteAddressLine1: {
|
|
317
|
+
[k: string]: unknown;
|
|
318
|
+
};
|
|
319
|
+
siteAddressTown: {
|
|
320
|
+
[k: string]: unknown;
|
|
321
|
+
};
|
|
322
|
+
siteAddressPostcode: {
|
|
323
|
+
[k: string]: unknown;
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
) & {
|
|
307
327
|
/**
|
|
308
328
|
* Internal case identifier
|
|
309
329
|
*/
|
|
@@ -504,23 +524,23 @@ export interface AppealHASCase {
|
|
|
504
524
|
/**
|
|
505
525
|
* First line of address for the appeal site
|
|
506
526
|
*/
|
|
507
|
-
siteAddressLine1
|
|
527
|
+
siteAddressLine1?: string | null;
|
|
508
528
|
/**
|
|
509
529
|
* Second line of address for the appeal site
|
|
510
530
|
*/
|
|
511
|
-
siteAddressLine2
|
|
531
|
+
siteAddressLine2?: string | null;
|
|
512
532
|
/**
|
|
513
533
|
* Town / City of the site address
|
|
514
534
|
*/
|
|
515
|
-
siteAddressTown
|
|
535
|
+
siteAddressTown?: string | null;
|
|
516
536
|
/**
|
|
517
537
|
* County of the site address
|
|
518
538
|
*/
|
|
519
|
-
siteAddressCounty
|
|
539
|
+
siteAddressCounty?: string | null;
|
|
520
540
|
/**
|
|
521
541
|
* Postal code of the site address
|
|
522
542
|
*/
|
|
523
|
-
siteAddressPostcode
|
|
543
|
+
siteAddressPostcode?: string | null;
|
|
524
544
|
/**
|
|
525
545
|
* Provided information on site accessibility
|
|
526
546
|
*/
|
|
@@ -549,6 +569,90 @@ export interface AppealHASCase {
|
|
|
549
569
|
* Indicates if the site is in a conservation area
|
|
550
570
|
*/
|
|
551
571
|
inConservationArea: boolean | null;
|
|
572
|
+
/**
|
|
573
|
+
* Indicates if the development affects a scheduled monument
|
|
574
|
+
*/
|
|
575
|
+
affectsScheduledMonument?: boolean | null;
|
|
576
|
+
/**
|
|
577
|
+
* Indicates if the site hosts protected species
|
|
578
|
+
*/
|
|
579
|
+
hasProtectedSpecies?: boolean | null;
|
|
580
|
+
/**
|
|
581
|
+
* Indicates an area of outstanding beauty (National Landscape)
|
|
582
|
+
*/
|
|
583
|
+
isAonbNationalLandscape?: boolean | null;
|
|
584
|
+
/**
|
|
585
|
+
* Indicates if site is on highway land
|
|
586
|
+
*/
|
|
587
|
+
isSiteOnHighwayLand?: boolean | null;
|
|
588
|
+
/**
|
|
589
|
+
* The designated site names
|
|
590
|
+
*/
|
|
591
|
+
designatedSitesNames?: string[] | null;
|
|
592
|
+
/**
|
|
593
|
+
* Indicates the existence of an infrastructure levy
|
|
594
|
+
*/
|
|
595
|
+
hasInfrastructureLevy?: boolean | null;
|
|
596
|
+
/**
|
|
597
|
+
* Indicates if the infrastructure levy is formally adopted
|
|
598
|
+
*/
|
|
599
|
+
isInfrastructureLevyFormallyAdopted?: boolean | null;
|
|
600
|
+
/**
|
|
601
|
+
* The date of the infrastructure levy adoption
|
|
602
|
+
*/
|
|
603
|
+
infrastructureLevyAdoptedDate?: string | null;
|
|
604
|
+
/**
|
|
605
|
+
* The expected date of the infrastructure levy
|
|
606
|
+
*/
|
|
607
|
+
infrastructureLevyExpectedDate?: string | null;
|
|
608
|
+
/**
|
|
609
|
+
* The procedure preference indicated by the LPA
|
|
610
|
+
*/
|
|
611
|
+
lpaProcedurePreference?: 'written' | 'hearing' | 'inquiry' | null;
|
|
612
|
+
/**
|
|
613
|
+
* The procedure details preference indicated by the LPA
|
|
614
|
+
*/
|
|
615
|
+
lpaProcedurePreferenceDetails?: string | null;
|
|
616
|
+
/**
|
|
617
|
+
* The duration of enquiry indicated by the LPA
|
|
618
|
+
*/
|
|
619
|
+
lpaProcedurePreferenceDuration?: number | null;
|
|
620
|
+
/**
|
|
621
|
+
* TBC
|
|
622
|
+
*/
|
|
623
|
+
caseworkReason?: string | null;
|
|
624
|
+
/**
|
|
625
|
+
* Information relevant to case...
|
|
626
|
+
*/
|
|
627
|
+
importantInformation?: string | null;
|
|
628
|
+
/**
|
|
629
|
+
* Under whose jurisdiction the decision falls
|
|
630
|
+
*/
|
|
631
|
+
jurisdiction?: string | null;
|
|
632
|
+
/**
|
|
633
|
+
* Has the case been selected for redetermination
|
|
634
|
+
*/
|
|
635
|
+
redeterminedIndicator?: boolean | null;
|
|
636
|
+
/**
|
|
637
|
+
* The date that the costs report was sent
|
|
638
|
+
*/
|
|
639
|
+
dateCostsReportDespatched?: string | null;
|
|
640
|
+
/**
|
|
641
|
+
* The date that is TBC
|
|
642
|
+
*/
|
|
643
|
+
dateNotRecoveredOrDerecovered?: string | null;
|
|
644
|
+
/**
|
|
645
|
+
* The date that case was recovered
|
|
646
|
+
*/
|
|
647
|
+
dateRecovered?: string | null;
|
|
648
|
+
/**
|
|
649
|
+
* The original case decision date
|
|
650
|
+
*/
|
|
651
|
+
originalCaseDecisionDate?: string | null;
|
|
652
|
+
/**
|
|
653
|
+
* The target date for case completion
|
|
654
|
+
*/
|
|
655
|
+
targetDate?: string | null;
|
|
552
656
|
/**
|
|
553
657
|
* Indicates if the appellant has complete ownership of the site
|
|
554
658
|
*/
|
|
@@ -656,8 +760,31 @@ export interface AppealHASCase {
|
|
|
656
760
|
| 'minor-commercial-development'
|
|
657
761
|
| 'advertisement'
|
|
658
762
|
| null;
|
|
763
|
+
siteGridReferenceEasting?: string | null;
|
|
764
|
+
siteGridReferenceNorthing?: string | null;
|
|
765
|
+
/**
|
|
766
|
+
* Indicates if the appellant has land owners permission
|
|
767
|
+
*/
|
|
768
|
+
hasLandownersPermission?: boolean | null;
|
|
769
|
+
/**
|
|
770
|
+
* Indicates if the advert is already in position
|
|
771
|
+
*/
|
|
772
|
+
isAdvertInPosition?: boolean | null;
|
|
773
|
+
/**
|
|
774
|
+
* Indicates if the site is in an area of special control for adverts
|
|
775
|
+
*/
|
|
776
|
+
isSiteInAreaOfSpecialControlAdverts?: boolean | null;
|
|
777
|
+
/**
|
|
778
|
+
* Indicates if the application was refused because of highway or traffic public safety?
|
|
779
|
+
*/
|
|
780
|
+
wasApplicationRefusedDueToHighwayOrTraffic?: boolean | null;
|
|
781
|
+
/**
|
|
782
|
+
* Indicates if the appellant submitted complete and accurate photographs and plans
|
|
783
|
+
*/
|
|
784
|
+
didAppellantSubmitCompletePhotosAndPlans?: boolean | null;
|
|
785
|
+
advertType?: string | null;
|
|
659
786
|
[k: string]: unknown;
|
|
660
|
-
}
|
|
787
|
+
};
|
|
661
788
|
|
|
662
789
|
/**
|
|
663
790
|
* Schema defining the metadata for appeal representations, such as statements, third-party comments and final comments
|
|
@@ -746,9 +873,29 @@ export interface AppealRepresentation {
|
|
|
746
873
|
}
|
|
747
874
|
|
|
748
875
|
/**
|
|
749
|
-
* Schema defining the metadata for an appeal
|
|
876
|
+
* Group B - Schema defining the metadata for an appeal
|
|
750
877
|
*/
|
|
751
|
-
export
|
|
878
|
+
export type AppealS78Case = (
|
|
879
|
+
| {
|
|
880
|
+
siteGridReferenceEasting: {
|
|
881
|
+
[k: string]: unknown;
|
|
882
|
+
};
|
|
883
|
+
siteGridReferenceNorthing: {
|
|
884
|
+
[k: string]: unknown;
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
| {
|
|
888
|
+
siteAddressLine1: {
|
|
889
|
+
[k: string]: unknown;
|
|
890
|
+
};
|
|
891
|
+
siteAddressTown: {
|
|
892
|
+
[k: string]: unknown;
|
|
893
|
+
};
|
|
894
|
+
siteAddressPostcode: {
|
|
895
|
+
[k: string]: unknown;
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
) & {
|
|
752
899
|
/**
|
|
753
900
|
* Internal case identifier
|
|
754
901
|
*/
|
|
@@ -953,23 +1100,23 @@ export interface AppealS78Case {
|
|
|
953
1100
|
/**
|
|
954
1101
|
* First line of address for the appeal site
|
|
955
1102
|
*/
|
|
956
|
-
siteAddressLine1
|
|
1103
|
+
siteAddressLine1?: string | null;
|
|
957
1104
|
/**
|
|
958
1105
|
* Second line of address for the appeal site
|
|
959
1106
|
*/
|
|
960
|
-
siteAddressLine2
|
|
1107
|
+
siteAddressLine2?: string | null;
|
|
961
1108
|
/**
|
|
962
1109
|
* Town / City of the site address
|
|
963
1110
|
*/
|
|
964
|
-
siteAddressTown
|
|
1111
|
+
siteAddressTown?: string | null;
|
|
965
1112
|
/**
|
|
966
1113
|
* County of the site address
|
|
967
1114
|
*/
|
|
968
|
-
siteAddressCounty
|
|
1115
|
+
siteAddressCounty?: string | null;
|
|
969
1116
|
/**
|
|
970
1117
|
* Postal code of the site address
|
|
971
1118
|
*/
|
|
972
|
-
siteAddressPostcode
|
|
1119
|
+
siteAddressPostcode?: string | null;
|
|
973
1120
|
/**
|
|
974
1121
|
* Provided information on site accessibility
|
|
975
1122
|
*/
|
|
@@ -1271,8 +1418,8 @@ export interface AppealS78Case {
|
|
|
1271
1418
|
* The net gain in residences of the proposed development
|
|
1272
1419
|
*/
|
|
1273
1420
|
numberOfResidencesNetChange: number | null;
|
|
1274
|
-
siteGridReferenceEasting
|
|
1275
|
-
siteGridReferenceNorthing
|
|
1421
|
+
siteGridReferenceEasting?: string | null;
|
|
1422
|
+
siteGridReferenceNorthing?: string | null;
|
|
1276
1423
|
siteViewableFromRoad: boolean | null;
|
|
1277
1424
|
siteWithinSSSI: boolean | null;
|
|
1278
1425
|
typeOfPlanningApplication:
|
|
@@ -1306,7 +1453,7 @@ export interface AppealS78Case {
|
|
|
1306
1453
|
statementOfCommonGroundDueDate?: string | null;
|
|
1307
1454
|
planningObligationDueDate?: string | null;
|
|
1308
1455
|
[k: string]: unknown;
|
|
1309
|
-
}
|
|
1456
|
+
};
|
|
1310
1457
|
|
|
1311
1458
|
/**
|
|
1312
1459
|
* Schema defining the data returned by the DaRT API
|
|
@@ -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
|
+
});
|