@planning-inspectorate/data-model 2.14.0 → 2.16.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/nsip-project-defs-meeting.md +39 -10
- package/docs/nsip-project.md +39 -10
- package/package.json +1 -1
- package/pins_data_model/models/model_appeal_document.py +1 -1
- package/pins_data_model/models/model_appeal_event.py +1 -1
- package/pins_data_model/models/model_appeal_event_estimate.py +1 -1
- package/pins_data_model/models/model_appeal_has.py +1 -1
- package/pins_data_model/models/model_appeal_representation.py +1 -1
- package/pins_data_model/models/model_appeal_s78.py +1 -1
- package/pins_data_model/models/model_dart_response.py +1 -1
- package/pins_data_model/models/model_entraid.py +1 -1
- package/pins_data_model/models/model_folder.py +1 -1
- package/pins_data_model/models/model_gettimesheets_response.py +1 -1
- package/pins_data_model/models/model_listed_building.py +1 -1
- package/pins_data_model/models/model_listed_buildings.py +1 -1
- package/pins_data_model/models/model_nsip_document.py +1 -1
- package/pins_data_model/models/model_nsip_exam_timetable.py +1 -1
- package/pins_data_model/models/model_nsip_invoice.py +1 -1
- package/pins_data_model/models/model_nsip_meeting.py +1 -1
- package/pins_data_model/models/model_nsip_project.py +8 -2
- package/pins_data_model/models/model_nsip_project_update.py +1 -1
- package/pins_data_model/models/model_nsip_representation.py +1 -1
- package/pins_data_model/models/model_nsip_subscription.py +1 -1
- package/pins_data_model/models/model_pins_inspector.py +1 -1
- package/pins_data_model/models/model_pins_lpa.py +1 -1
- package/pins_data_model/models/model_s51_advice.py +1 -1
- package/pins_data_model/models/model_service_user.py +1 -1
- package/schemas/commands/appellant-submission.schema.json +8 -0
- package/schemas/commands/lpa-questionnaire.schema.json +2 -2
- package/schemas/nsip-project.schema.json +8 -1
- package/src/schemas.d.ts +11 -3
- package/tests/appeals/commands/enforcement-listed-questionnaire.test.js +109 -0
- package/tests/appeals/commands/enforcement-listed-submission.test.js +187 -0
|
@@ -4,14 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
# meeting Properties
|
|
6
6
|
|
|
7
|
-
| Property
|
|
8
|
-
|
|
|
9
|
-
| [meetingId](#meetingid)
|
|
10
|
-
| [meetingAgenda](#meetingagenda)
|
|
11
|
-
| [planningInspectorateRole](#planninginspectoraterole)
|
|
12
|
-
| [meetingDate](#meetingdate)
|
|
13
|
-
| [
|
|
14
|
-
|
|
|
7
|
+
| Property | Type | Required | Nullable | Defined by |
|
|
8
|
+
| :-------------------------------------------------------- | :-------- | :------- | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| [meetingId](#meetingid) | `integer` | Required | cannot be null | [NSIP Project](nsip-project-defs-meeting-properties-meetingid.md "nsip-project.schema.json#/$defs/meeting/properties/meetingId") |
|
|
10
|
+
| [meetingAgenda](#meetingagenda) | `string` | Optional | can be null | [NSIP Project](nsip-project-defs-meeting-properties-meetingagenda.md "nsip-project.schema.json#/$defs/meeting/properties/meetingAgenda") |
|
|
11
|
+
| [planningInspectorateRole](#planninginspectoraterole) | `string` | Optional | can be null | [NSIP Project](nsip-project-defs-meeting-properties-planninginspectoraterole.md "nsip-project.schema.json#/$defs/meeting/properties/planningInspectorateRole") |
|
|
12
|
+
| [meetingDate](#meetingdate) | `string` | Optional | can be null | [NSIP Project](nsip-project-defs-meeting-properties-meetingdate.md "nsip-project.schema.json#/$defs/meeting/properties/meetingDate") |
|
|
13
|
+
| [estimatedPrelimMeetingDate](#estimatedprelimmeetingdate) | `string` | Optional | can be null | [NSIP Project](nsip-project-defs-meeting-properties-estimatedprelimmeetingdate.md "nsip-project.schema.json#/$defs/meeting/properties/estimatedPrelimMeetingDate") |
|
|
14
|
+
| [meetingType](#meetingtype) | `string` | Optional | can be null | [NSIP Project](nsip-project-defs-meeting-properties-meetingtype.md "nsip-project.schema.json#/$defs/meeting/properties/meetingType") |
|
|
15
|
+
| Additional Properties | Any | Optional | can be null | |
|
|
15
16
|
|
|
16
17
|
## meetingId
|
|
17
18
|
|
|
@@ -19,11 +20,11 @@ Unique identifier for the meeting
|
|
|
19
20
|
|
|
20
21
|
`meetingId`
|
|
21
22
|
|
|
22
|
-
* is
|
|
23
|
+
* is required
|
|
23
24
|
|
|
24
25
|
* Type: `integer`
|
|
25
26
|
|
|
26
|
-
*
|
|
27
|
+
* cannot be null
|
|
27
28
|
|
|
28
29
|
* defined in: [NSIP Project](nsip-project-defs-meeting-properties-meetingid.md "nsip-project.schema.json#/$defs/meeting/properties/meetingId")
|
|
29
30
|
|
|
@@ -124,6 +125,34 @@ Meeting date
|
|
|
124
125
|
"2023-07-27T20:30:00.000Z"
|
|
125
126
|
```
|
|
126
127
|
|
|
128
|
+
## estimatedPrelimMeetingDate
|
|
129
|
+
|
|
130
|
+
Estimated Preliminary Meeting date
|
|
131
|
+
|
|
132
|
+
`estimatedPrelimMeetingDate`
|
|
133
|
+
|
|
134
|
+
* is optional
|
|
135
|
+
|
|
136
|
+
* Type: `string`
|
|
137
|
+
|
|
138
|
+
* can be null
|
|
139
|
+
|
|
140
|
+
* defined in: [NSIP Project](nsip-project-defs-meeting-properties-estimatedprelimmeetingdate.md "nsip-project.schema.json#/$defs/meeting/properties/estimatedPrelimMeetingDate")
|
|
141
|
+
|
|
142
|
+
### estimatedPrelimMeetingDate Type
|
|
143
|
+
|
|
144
|
+
`string`
|
|
145
|
+
|
|
146
|
+
### estimatedPrelimMeetingDate Constraints
|
|
147
|
+
|
|
148
|
+
**date time**: the string must be a date time string, according to [RFC 3339, section 5.6](https://tools.ietf.org/html/rfc3339 "check the specification")
|
|
149
|
+
|
|
150
|
+
### estimatedPrelimMeetingDate Examples
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
"2023-07-27T20:30:00.000Z"
|
|
154
|
+
```
|
|
155
|
+
|
|
127
156
|
## meetingType
|
|
128
157
|
|
|
129
158
|
Type of Meeting
|
package/docs/nsip-project.md
CHANGED
|
@@ -3592,14 +3592,15 @@ Reference this group by using
|
|
|
3592
3592
|
{"$ref":"nsip-project.schema.json#/$defs/meeting"}
|
|
3593
3593
|
```
|
|
3594
3594
|
|
|
3595
|
-
| Property
|
|
3596
|
-
|
|
|
3597
|
-
| [meetingId](#meetingid)
|
|
3598
|
-
| [meetingAgenda](#meetingagenda)
|
|
3599
|
-
| [planningInspectorateRole](#planninginspectoraterole)
|
|
3600
|
-
| [meetingDate](#meetingdate)
|
|
3601
|
-
| [
|
|
3602
|
-
|
|
|
3595
|
+
| Property | Type | Required | Nullable | Defined by |
|
|
3596
|
+
| :-------------------------------------------------------- | :-------- | :------- | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
3597
|
+
| [meetingId](#meetingid) | `integer` | Required | cannot be null | [NSIP Project](nsip-project-defs-meeting-properties-meetingid.md "nsip-project.schema.json#/$defs/meeting/properties/meetingId") |
|
|
3598
|
+
| [meetingAgenda](#meetingagenda) | `string` | Optional | can be null | [NSIP Project](nsip-project-defs-meeting-properties-meetingagenda.md "nsip-project.schema.json#/$defs/meeting/properties/meetingAgenda") |
|
|
3599
|
+
| [planningInspectorateRole](#planninginspectoraterole) | `string` | Optional | can be null | [NSIP Project](nsip-project-defs-meeting-properties-planninginspectoraterole.md "nsip-project.schema.json#/$defs/meeting/properties/planningInspectorateRole") |
|
|
3600
|
+
| [meetingDate](#meetingdate) | `string` | Optional | can be null | [NSIP Project](nsip-project-defs-meeting-properties-meetingdate.md "nsip-project.schema.json#/$defs/meeting/properties/meetingDate") |
|
|
3601
|
+
| [estimatedPrelimMeetingDate](#estimatedprelimmeetingdate) | `string` | Optional | can be null | [NSIP Project](nsip-project-defs-meeting-properties-estimatedprelimmeetingdate.md "nsip-project.schema.json#/$defs/meeting/properties/estimatedPrelimMeetingDate") |
|
|
3602
|
+
| [meetingType](#meetingtype) | `string` | Optional | can be null | [NSIP Project](nsip-project-defs-meeting-properties-meetingtype.md "nsip-project.schema.json#/$defs/meeting/properties/meetingType") |
|
|
3603
|
+
| Additional Properties | Any | Optional | can be null | |
|
|
3603
3604
|
|
|
3604
3605
|
### meetingId
|
|
3605
3606
|
|
|
@@ -3607,11 +3608,11 @@ Unique identifier for the meeting
|
|
|
3607
3608
|
|
|
3608
3609
|
`meetingId`
|
|
3609
3610
|
|
|
3610
|
-
* is
|
|
3611
|
+
* is required
|
|
3611
3612
|
|
|
3612
3613
|
* Type: `integer`
|
|
3613
3614
|
|
|
3614
|
-
*
|
|
3615
|
+
* cannot be null
|
|
3615
3616
|
|
|
3616
3617
|
* defined in: [NSIP Project](nsip-project-defs-meeting-properties-meetingid.md "nsip-project.schema.json#/$defs/meeting/properties/meetingId")
|
|
3617
3618
|
|
|
@@ -3712,6 +3713,34 @@ Meeting date
|
|
|
3712
3713
|
"2023-07-27T20:30:00.000Z"
|
|
3713
3714
|
```
|
|
3714
3715
|
|
|
3716
|
+
### estimatedPrelimMeetingDate
|
|
3717
|
+
|
|
3718
|
+
Estimated Preliminary Meeting date
|
|
3719
|
+
|
|
3720
|
+
`estimatedPrelimMeetingDate`
|
|
3721
|
+
|
|
3722
|
+
* is optional
|
|
3723
|
+
|
|
3724
|
+
* Type: `string`
|
|
3725
|
+
|
|
3726
|
+
* can be null
|
|
3727
|
+
|
|
3728
|
+
* defined in: [NSIP Project](nsip-project-defs-meeting-properties-estimatedprelimmeetingdate.md "nsip-project.schema.json#/$defs/meeting/properties/estimatedPrelimMeetingDate")
|
|
3729
|
+
|
|
3730
|
+
#### estimatedPrelimMeetingDate Type
|
|
3731
|
+
|
|
3732
|
+
`string`
|
|
3733
|
+
|
|
3734
|
+
#### estimatedPrelimMeetingDate Constraints
|
|
3735
|
+
|
|
3736
|
+
**date time**: the string must be a date time string, according to [RFC 3339, section 5.6](https://tools.ietf.org/html/rfc3339 "check the specification")
|
|
3737
|
+
|
|
3738
|
+
#### estimatedPrelimMeetingDate Examples
|
|
3739
|
+
|
|
3740
|
+
```json
|
|
3741
|
+
"2023-07-27T20:30:00.000Z"
|
|
3742
|
+
```
|
|
3743
|
+
|
|
3715
3744
|
### meetingType
|
|
3716
3745
|
|
|
3717
3746
|
Type of Meeting
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: nsip-project.schema.json
|
|
3
|
-
# timestamp: 2026-02-
|
|
3
|
+
# timestamp: 2026-02-05T18:48:26+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -310,7 +310,7 @@ class Meeting(BaseModel):
|
|
|
310
310
|
model_config = ConfigDict(
|
|
311
311
|
extra="allow",
|
|
312
312
|
)
|
|
313
|
-
meetingId: int
|
|
313
|
+
meetingId: int = Field(..., examples=[123])
|
|
314
314
|
"""
|
|
315
315
|
Unique identifier for the meeting
|
|
316
316
|
"""
|
|
@@ -330,6 +330,12 @@ class Meeting(BaseModel):
|
|
|
330
330
|
"""
|
|
331
331
|
Meeting date
|
|
332
332
|
"""
|
|
333
|
+
estimatedPrelimMeetingDate: AwareDatetime | None = Field(
|
|
334
|
+
None, examples=["2023-07-27T20:30:00.000Z"]
|
|
335
|
+
)
|
|
336
|
+
"""
|
|
337
|
+
Estimated Preliminary Meeting date
|
|
338
|
+
"""
|
|
333
339
|
meetingType: MeetingType | None = None
|
|
334
340
|
"""
|
|
335
341
|
Type of Meeting
|
|
@@ -73,6 +73,14 @@
|
|
|
73
73
|
{ "$ref": "appeals-components/appellant-procedure-preference.schema.json" },
|
|
74
74
|
{ "$ref": "appeals-components/appeal-ldc.submission.schema.json" }
|
|
75
75
|
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"$comment": "Enforcement listed building",
|
|
79
|
+
"allOf": [
|
|
80
|
+
{ "properties": { "caseType": { "enum": ["F"] } } },
|
|
81
|
+
{ "$ref": "appeals-components/appeal-enforcement-submission.schema.json" },
|
|
82
|
+
{ "$ref": "appeals-components/appellant-procedure-preference.schema.json" }
|
|
83
|
+
]
|
|
76
84
|
}
|
|
77
85
|
]
|
|
78
86
|
},
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
|
-
"$comment": "Enforcement",
|
|
74
|
+
"$comment": "Enforcement + Enforcement listed building",
|
|
75
75
|
"allOf": [
|
|
76
|
-
{ "properties": { "caseType": { "enum": ["C"] } } },
|
|
76
|
+
{ "properties": { "caseType": { "enum": ["C", "F"] } } },
|
|
77
77
|
{ "$ref": "appeals-components/lpa-questionnaire-common.schema.json" },
|
|
78
78
|
{ "$ref": "appeals-components/lpa-questionnaire-has.schema.json" },
|
|
79
79
|
{ "$ref": "appeals-components/lpa-procedure-preference.schema.json" },
|
|
@@ -871,9 +871,10 @@
|
|
|
871
871
|
"type": "object",
|
|
872
872
|
"additionalProperties": true,
|
|
873
873
|
"description": "A meeting related to the project",
|
|
874
|
+
"required": ["meetingId"],
|
|
874
875
|
"properties": {
|
|
875
876
|
"meetingId": {
|
|
876
|
-
"type":
|
|
877
|
+
"type": "integer",
|
|
877
878
|
"description": "Unique identifier for the meeting",
|
|
878
879
|
"examples": [123]
|
|
879
880
|
},
|
|
@@ -894,6 +895,12 @@
|
|
|
894
895
|
"format": "date-time",
|
|
895
896
|
"examples": ["2023-07-27T20:30:00.000Z"]
|
|
896
897
|
},
|
|
898
|
+
"estimatedPrelimMeetingDate": {
|
|
899
|
+
"type": ["string", "null"],
|
|
900
|
+
"description": "Estimated Preliminary Meeting date",
|
|
901
|
+
"format": "date-time",
|
|
902
|
+
"examples": ["2023-07-27T20:30:00.000Z"]
|
|
903
|
+
},
|
|
897
904
|
"meetingType": {
|
|
898
905
|
"type": ["string", "null"],
|
|
899
906
|
"description": "Type of Meeting",
|
package/src/schemas.d.ts
CHANGED
|
@@ -2914,7 +2914,7 @@ export interface Meeting {
|
|
|
2914
2914
|
/**
|
|
2915
2915
|
* Unique identifier for the meeting
|
|
2916
2916
|
*/
|
|
2917
|
-
meetingId
|
|
2917
|
+
meetingId: number;
|
|
2918
2918
|
/**
|
|
2919
2919
|
* Meeting agenda
|
|
2920
2920
|
*/
|
|
@@ -2927,6 +2927,10 @@ export interface Meeting {
|
|
|
2927
2927
|
* Meeting date
|
|
2928
2928
|
*/
|
|
2929
2929
|
meetingDate?: string | null;
|
|
2930
|
+
/**
|
|
2931
|
+
* Estimated Preliminary Meeting date
|
|
2932
|
+
*/
|
|
2933
|
+
estimatedPrelimMeetingDate?: string | null;
|
|
2930
2934
|
/**
|
|
2931
2935
|
* Type of Meeting
|
|
2932
2936
|
*/
|
|
@@ -3993,7 +3997,11 @@ export interface AppellantSubmissionCommand {
|
|
|
3993
3997
|
} & AppellantCommonSubmissionProperties &
|
|
3994
3998
|
AppellantCommonPlanningProperties &
|
|
3995
3999
|
AppellantProcedurePreferenceProperties &
|
|
3996
|
-
LDCSpecificProperties)
|
|
4000
|
+
LDCSpecificProperties)
|
|
4001
|
+
| ({
|
|
4002
|
+
caseType?: 'F';
|
|
4003
|
+
} & AppellantEnforcementSubmissionProperties &
|
|
4004
|
+
AppellantProcedurePreferenceProperties);
|
|
3997
4005
|
documents: {
|
|
3998
4006
|
/**
|
|
3999
4007
|
* The unique identifier for the document
|
|
@@ -4597,7 +4605,7 @@ export interface LPAQuestionnaireCommand {
|
|
|
4597
4605
|
LPAProcedurePreferenceProperties &
|
|
4598
4606
|
ChangedListedBuildingNumbersProperties)
|
|
4599
4607
|
| ({
|
|
4600
|
-
caseType?: 'C';
|
|
4608
|
+
caseType?: 'C' | 'F';
|
|
4601
4609
|
} & LPAQCommonSubmissionProperties &
|
|
4602
4610
|
LPAQHASSubmissionProperties &
|
|
4603
4611
|
LPAProcedurePreferenceProperties &
|
|
@@ -0,0 +1,109 @@
|
|
|
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 exampleEnforcementListedQuestionnaireSchema = {
|
|
21
|
+
casedata: {
|
|
22
|
+
caseType: 'F',
|
|
23
|
+
caseReference: 'est ea elit in nulla',
|
|
24
|
+
lpaQuestionnaireSubmittedDate: null,
|
|
25
|
+
siteAccessDetails: ['velit adipisicing fugiat dolor ullamco'],
|
|
26
|
+
siteSafetyDetails: ['ut', 'dolore ut sint Duis', 'magna consequat quis laboris officia'],
|
|
27
|
+
nearbyCaseReferences: ['nulla', 'incididunt eu nostrud eiusmod', 'exercitation', 'Ut nostrud', 'eiusmod cillum eu'],
|
|
28
|
+
neighbouringSiteAddresses: null,
|
|
29
|
+
isCorrectAppealType: true,
|
|
30
|
+
affectedListedBuildingNumbers: null,
|
|
31
|
+
isGreenBelt: null,
|
|
32
|
+
inConservationArea: null,
|
|
33
|
+
newConditionDetails: null,
|
|
34
|
+
notificationMethod: ['irure', 'cillum tempor incididunt labore in'],
|
|
35
|
+
lpaCostsAppliedFor: true,
|
|
36
|
+
lpaStatement: 'ex laborum cupidatat',
|
|
37
|
+
changedListedBuildingNumbers: null,
|
|
38
|
+
affectsScheduledMonument: true,
|
|
39
|
+
hasProtectedSpecies: false,
|
|
40
|
+
isAonbNationalLandscape: true,
|
|
41
|
+
designatedSitesNames: ['quis nulla eu officia exercitation'],
|
|
42
|
+
hasTreePreservationOrder: null,
|
|
43
|
+
isGypsyOrTravellerSite: true,
|
|
44
|
+
isPublicRightOfWay: null,
|
|
45
|
+
eiaEnvironmentalImpactSchedule: 'schedule-2',
|
|
46
|
+
eiaDevelopmentDescription: 'production-processing-of-metals',
|
|
47
|
+
eiaSensitiveAreaDetails: null,
|
|
48
|
+
eiaColumnTwoThreshold: false,
|
|
49
|
+
eiaScreeningOpinion: false,
|
|
50
|
+
eiaRequiresEnvironmentalStatement: null,
|
|
51
|
+
eiaCompletedEnvironmentalStatement: true,
|
|
52
|
+
hasStatutoryConsultees: true,
|
|
53
|
+
consultedBodiesDetails: 'in in labore irure nostrud',
|
|
54
|
+
hasConsultationResponses: null,
|
|
55
|
+
hasEmergingPlan: null,
|
|
56
|
+
hasSupplementaryPlanningDocs: null,
|
|
57
|
+
hasInfrastructureLevy: true,
|
|
58
|
+
isInfrastructureLevyFormallyAdopted: false,
|
|
59
|
+
infrastructureLevyAdoptedDate: '1913-06-14T10:40:33.0Z',
|
|
60
|
+
infrastructureLevyExpectedDate: '1912-06-14T10:40:33.0Z',
|
|
61
|
+
lpaProcedurePreference: null,
|
|
62
|
+
lpaProcedurePreferenceDetails: 'in reprehenderit',
|
|
63
|
+
lpaProcedurePreferenceDuration: -34480053.16630782,
|
|
64
|
+
noticeRelatesToBuildingEngineeringMiningOther: null,
|
|
65
|
+
siteAreaSquareMetres: null,
|
|
66
|
+
hasAllegedBreachArea: null,
|
|
67
|
+
doesAllegedBreachCreateFloorSpace: null,
|
|
68
|
+
changeOfUseRefuseOrWaste: null,
|
|
69
|
+
changeOfUseMineralExtraction: null,
|
|
70
|
+
changeOfUseMineralStorage: null,
|
|
71
|
+
relatesToErectionOfBuildingOrBuildings: null,
|
|
72
|
+
relatesToBuildingWithAgriculturalPurpose: null,
|
|
73
|
+
relatesToBuildingSingleDwellingHouse: null,
|
|
74
|
+
affectedTrunkRoadName: null,
|
|
75
|
+
isSiteOnCrownLand: null,
|
|
76
|
+
article4AffectedDevelopmentRights: null
|
|
77
|
+
},
|
|
78
|
+
documents: [document]
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
describe('Enforcement listed building questionnaire command schema', () => {
|
|
82
|
+
const schemas = loadAllSchemasSync();
|
|
83
|
+
const flatSchemas = Object.values(schemas).reduce((a, c) => ({ ...a, ...c }), {});
|
|
84
|
+
const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
|
|
85
|
+
addFormats(ajv);
|
|
86
|
+
|
|
87
|
+
it('should allow valid schema for Enforcement listed building', () => {
|
|
88
|
+
const validationResult = ajv.validate(schema, exampleEnforcementListedQuestionnaireSchema);
|
|
89
|
+
assert.strictEqual(validationResult, true);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should reject missing caseReference', () => {
|
|
93
|
+
const test = structuredClone(exampleEnforcementListedQuestionnaireSchema);
|
|
94
|
+
delete test.casedata.caseReference;
|
|
95
|
+
const validationResult = ajv.validate(schema, test);
|
|
96
|
+
assert.strictEqual(validationResult, false);
|
|
97
|
+
assert.strictEqual(
|
|
98
|
+
ajv.errors.some((x) => x.message === "must have required property 'caseReference'"),
|
|
99
|
+
true
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should allow additional props', () => {
|
|
104
|
+
const test = structuredClone(exampleEnforcementListedQuestionnaireSchema);
|
|
105
|
+
test.test = 1;
|
|
106
|
+
const validationResult = ajv.validate(schema, test);
|
|
107
|
+
assert.strictEqual(validationResult, true);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -0,0 +1,187 @@
|
|
|
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: 'priorCorrespondenceWithPINS'
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const exampleEnforcementListedSubmissionSchema = {
|
|
31
|
+
casedata: {
|
|
32
|
+
caseType: 'F',
|
|
33
|
+
submissionId: '4b78fc58-fcb0-70d6-5dea-b9b774f802d6',
|
|
34
|
+
caseProcedure: 'written',
|
|
35
|
+
lpaCode: 'cupidatat',
|
|
36
|
+
caseSubmittedDate: '1890-12-28T22:49:47.0Z',
|
|
37
|
+
enforcementNotice: true,
|
|
38
|
+
enforcementReference: '12345',
|
|
39
|
+
enforcementIssueDate: '1890-12-28T22:49:47.0Z',
|
|
40
|
+
enforcementEffectiveDate: '1890-12-28T22:49:47.0Z',
|
|
41
|
+
contactPlanningInspectorateDate: null,
|
|
42
|
+
interestInLand: 'owner',
|
|
43
|
+
writtenOrVerbalPermission: null,
|
|
44
|
+
descriptionOfAllegedBreach: 'a new chimney',
|
|
45
|
+
applicationMadeAndFeePaid: true,
|
|
46
|
+
applicationDevelopmentAllOrPart: 'all-of-the-development',
|
|
47
|
+
originalDevelopmentDescription: 'in amet',
|
|
48
|
+
changedDevelopmentDescription: true,
|
|
49
|
+
applicationReference: '43010/APP/1/290572',
|
|
50
|
+
applicationDate: '1890-12-28T22:49:47.0Z',
|
|
51
|
+
applicationDecision: 'granted',
|
|
52
|
+
applicationDecisionAppealed: false,
|
|
53
|
+
applicationDecisionDate: '1890-12-28T22:49:47.0Z',
|
|
54
|
+
appealDecisionDate: null,
|
|
55
|
+
caseSubmissionDueDate: null,
|
|
56
|
+
siteAddressLine1: 'occaecat aliquip non pariatur consequat',
|
|
57
|
+
siteAddressLine2: null,
|
|
58
|
+
siteAddressTown: 'et',
|
|
59
|
+
siteAddressCounty: 'velit',
|
|
60
|
+
siteAddressPostcode: 'nisi minim laboris sed',
|
|
61
|
+
siteGridReferenceEasting: '357144',
|
|
62
|
+
siteGridReferenceNorthing: '400534',
|
|
63
|
+
contactAddressLine1: null,
|
|
64
|
+
contactAddressLine2: null,
|
|
65
|
+
contactAddressTown: null,
|
|
66
|
+
contactAddressCounty: null,
|
|
67
|
+
contactAddressPostcode: null,
|
|
68
|
+
contactGridReferenceEasting: null,
|
|
69
|
+
contactGridReferenceNorthing: null,
|
|
70
|
+
siteAccessDetails: ['laborum', 'aute velit quis', 'dolor'],
|
|
71
|
+
siteSafetyDetails: ['velit aliqua', 'qui', 'tempor Duis ut dolore', 'anim Ut in ea', 'eiusmod laborum'],
|
|
72
|
+
appellantCostsAppliedFor: false,
|
|
73
|
+
appellantProcedurePreference: null,
|
|
74
|
+
appellantProcedurePreferenceDetails: 'eiusmod ex exercitation',
|
|
75
|
+
appellantProcedurePreferenceDuration: 10816414.941069126,
|
|
76
|
+
appellantProcedurePreferenceWitnessCount: -91300569.36444478,
|
|
77
|
+
statusPlanningObligation: 'proident aute',
|
|
78
|
+
nearbyCaseReferences: ['incididunt'],
|
|
79
|
+
namedIndividuals: [
|
|
80
|
+
{
|
|
81
|
+
firstName: 'Bob',
|
|
82
|
+
lastName: 'Bobberson',
|
|
83
|
+
interestInLand: 'owner',
|
|
84
|
+
writtenOrVerbalPermission: 'yes'
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
appealGrounds: [
|
|
88
|
+
{
|
|
89
|
+
groundRef: 'a',
|
|
90
|
+
factsForGround: 'I like Christmas'
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
documents: [document],
|
|
95
|
+
users: [user]
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
describe(' listed building submission command schema', () => {
|
|
99
|
+
const schemas = loadAllSchemasSync();
|
|
100
|
+
const flatSchemas = Object.values(schemas).reduce((a, c) => ({ ...a, ...c }), {});
|
|
101
|
+
const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
|
|
102
|
+
addFormats(ajv);
|
|
103
|
+
|
|
104
|
+
it('should allow valid schema for enforcement listed building', () => {
|
|
105
|
+
const validationResult = ajv.validate(schema, exampleEnforcementListedSubmissionSchema);
|
|
106
|
+
assert.strictEqual(validationResult, true);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should enforce eastings-northings pattern', () => {
|
|
110
|
+
const invalidPatterns = [
|
|
111
|
+
{ easting: 'abc123', northing: '400534', description: 'easting with letters' },
|
|
112
|
+
{ easting: '1234567*', northing: '400534', description: 'easting too long' },
|
|
113
|
+
{ easting: '12345', northing: '400534', description: 'easting too short' },
|
|
114
|
+
{ easting: '357144', northing: 'xyz123', description: 'northing with letters' },
|
|
115
|
+
{ easting: '357144', northing: '12345678', description: 'northing too long' },
|
|
116
|
+
{ easting: '357144', northing: '12345', description: 'northing too short' },
|
|
117
|
+
{ easting: '', northing: '400534', description: 'empty easting' },
|
|
118
|
+
{ easting: '357144', northing: '', description: 'empty northing' }
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
for (const pattern of invalidPatterns) {
|
|
122
|
+
const test = structuredClone(exampleEnforcementListedSubmissionSchema);
|
|
123
|
+
test.casedata.siteGridReferenceEasting = pattern.easting;
|
|
124
|
+
test.casedata.siteGridReferenceNorthing = pattern.northing;
|
|
125
|
+
|
|
126
|
+
const validationResult = ajv.validate(schema, test);
|
|
127
|
+
assert.strictEqual(validationResult, false, `Expected validation to fail for ${pattern.description}`);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should allow only eastings-northings', () => {
|
|
132
|
+
const test = structuredClone(exampleEnforcementListedSubmissionSchema);
|
|
133
|
+
test.casedata.siteAddressPostcode = undefined;
|
|
134
|
+
test.casedata.siteAddressLine1 = null;
|
|
135
|
+
test.casedata.siteAddressTown = null;
|
|
136
|
+
const validationResult = ajv.validate(schema, test);
|
|
137
|
+
assert.strictEqual(validationResult, true);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should allow only site address', () => {
|
|
141
|
+
const test = structuredClone(exampleEnforcementListedSubmissionSchema);
|
|
142
|
+
test.casedata.siteGridReferenceEasting = undefined;
|
|
143
|
+
test.casedata.siteGridReferenceNorthing = null;
|
|
144
|
+
const validationResult = ajv.validate(schema, test);
|
|
145
|
+
assert.strictEqual(validationResult, true);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should enforce either site address or easting-northing', () => {
|
|
149
|
+
const test = structuredClone(exampleEnforcementListedSubmissionSchema);
|
|
150
|
+
test.casedata.siteAddressPostcode = undefined;
|
|
151
|
+
test.casedata.siteAddressLine1 = null;
|
|
152
|
+
test.casedata.siteAddressTown = null;
|
|
153
|
+
test.casedata.siteGridReferenceEasting = undefined;
|
|
154
|
+
test.casedata.siteGridReferenceNorthing = null;
|
|
155
|
+
const validationResult = ajv.validate(schema, test);
|
|
156
|
+
assert.strictEqual(validationResult, false);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('should reject missing root property', () => {
|
|
160
|
+
const test = structuredClone(exampleEnforcementListedSubmissionSchema);
|
|
161
|
+
delete test.casedata.caseType;
|
|
162
|
+
const validationResult = ajv.validate(schema, test);
|
|
163
|
+
assert.strictEqual(validationResult, false);
|
|
164
|
+
assert.strictEqual(
|
|
165
|
+
ajv.errors.some((x) => x.message === "must have required property 'caseType'"),
|
|
166
|
+
true
|
|
167
|
+
);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('should reject missing nested property', () => {
|
|
171
|
+
const test = structuredClone(exampleEnforcementListedSubmissionSchema);
|
|
172
|
+
delete test.casedata.caseProcedure;
|
|
173
|
+
const validationResult = ajv.validate(schema, test);
|
|
174
|
+
assert.strictEqual(validationResult, false);
|
|
175
|
+
assert.strictEqual(
|
|
176
|
+
ajv.errors.some((x) => x.message === "must have required property 'caseProcedure'"),
|
|
177
|
+
true
|
|
178
|
+
);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('should allow additional props', () => {
|
|
182
|
+
const test = structuredClone(exampleEnforcementListedSubmissionSchema);
|
|
183
|
+
test.test = 1;
|
|
184
|
+
const validationResult = ajv.validate(schema, test);
|
|
185
|
+
assert.strictEqual(validationResult, true);
|
|
186
|
+
});
|
|
187
|
+
});
|