@pdtf/schemas 3.4.1-1 → 3.4.1-3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +67 -73
- package/package.json +1 -1
- package/src/schemas/v3/overlays/extensions/as.json +15 -0
- package/src/schemas/v3/overlays/extensions/dr.json +14 -1
- package/src/schemas/v3/overlays/extensions/er.json +9 -0
- package/src/schemas/v3/overlays/extensions/fd.json +9 -0
- package/src/schemas/v3/overlays/extensions/hi.json +4 -0
- package/src/schemas/v3/overlays/extensions/hs.json +15 -0
- package/src/schemas/v3/overlays/extensions/jk.json +22 -1
- package/src/schemas/v3/overlays/extensions/la.json +19 -2
- package/src/schemas/v3/overlays/extensions/oc.json +20 -0
- package/src/schemas/v3/overlays/extensions/sb.json +15 -0
- package/src/schemas/v3/overlays/extensions/sf.json +15 -0
- package/src/schemas/v3/overlays/extensions/sl.json +20 -0
- package/src/schemas/v3/overlays/extensions/tf.json +9 -0
- package/src/schemas/v3/property-transaction-milestones.json +91 -0
- package/src/tests/v3/extensionOverlays.test.js +270 -81
- package/src/tests/v3/transactionSchema.test.js +0 -228
- package/src/utils/extractExtensionOverlays.js +153 -62
|
@@ -4,45 +4,63 @@ const {
|
|
|
4
4
|
getValidator,
|
|
5
5
|
} = require("../../../index.js");
|
|
6
6
|
|
|
7
|
-
const schemaId =
|
|
7
|
+
const schemaId =
|
|
8
|
+
"https://trust.propdata.org.uk/schemas/v3/pdtf-transaction.json";
|
|
8
9
|
|
|
9
10
|
describe("Extension Overlays", () => {
|
|
10
|
-
|
|
11
11
|
describe("String key support", () => {
|
|
12
12
|
test("should load extension overlays using string keys", () => {
|
|
13
13
|
const schema = getTransactionSchema(schemaId, ["nts2023", "jk"]);
|
|
14
|
-
const jkProp =
|
|
15
|
-
|
|
14
|
+
const jkProp =
|
|
15
|
+
schema.properties?.propertyPack?.properties?.specialistIssues
|
|
16
|
+
?.properties?.japaneseKnotweed;
|
|
17
|
+
|
|
16
18
|
expect(jkProp).toBeDefined();
|
|
17
19
|
expect(jkProp.ntsRef).toBe("A5.3");
|
|
18
20
|
});
|
|
19
21
|
|
|
20
22
|
test("should work with multiple extension string keys", () => {
|
|
21
|
-
const schema = getTransactionSchema(schemaId, [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
const schema = getTransactionSchema(schemaId, [
|
|
24
|
+
"nts2023",
|
|
25
|
+
"jk",
|
|
26
|
+
"tf",
|
|
27
|
+
"ma",
|
|
28
|
+
"er",
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
const jkProp =
|
|
32
|
+
schema.properties?.propertyPack?.properties?.specialistIssues
|
|
33
|
+
?.properties?.japaneseKnotweed;
|
|
34
|
+
const tfProp =
|
|
35
|
+
schema.properties?.propertyPack?.properties?.ownership?.properties
|
|
36
|
+
?.ownershipsToBeTransferred?.items?.oneOf?.[2]?.properties
|
|
37
|
+
?.leaseholdInformation?.properties?.serviceCharge?.oneOf?.[1]
|
|
38
|
+
?.properties?.transferFees;
|
|
39
|
+
const maProp =
|
|
40
|
+
schema.properties?.propertyPack?.properties?.ownership?.properties
|
|
41
|
+
?.ownershipsToBeTransferred?.items?.oneOf?.[2]?.properties
|
|
42
|
+
?.leaseholdInformation?.properties?.contactDetails;
|
|
43
|
+
const erProp =
|
|
44
|
+
schema.properties?.propertyPack?.properties?.ownership?.properties
|
|
45
|
+
?.ownershipsToBeTransferred?.items?.oneOf?.[0]?.properties
|
|
46
|
+
?.estateRentcharges;
|
|
47
|
+
|
|
27
48
|
expect(jkProp?.ntsRef).toBe("A5.3");
|
|
28
49
|
expect(tfProp?.ntsRef).toBe("A3.5.1.1");
|
|
29
50
|
expect(maProp?.ntsRef).toBe("A1.5.4");
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
test("should be equivalent to direct object access", () => {
|
|
33
|
-
const schemaString = getTransactionSchema(schemaId, ["nts2023", "jk"]);
|
|
34
|
-
const schemaDirect = getTransactionSchema(schemaId, ["nts2023", extensionOverlays.jk]);
|
|
35
|
-
|
|
36
|
-
expect(schemaString).toEqual(schemaDirect);
|
|
51
|
+
expect(erProp?.ntsRef).toBe("A3.4");
|
|
37
52
|
});
|
|
38
53
|
});
|
|
39
54
|
|
|
40
55
|
describe("Individual extension functionality", () => {
|
|
41
56
|
test("should add Japanese Knotweed extension correctly", () => {
|
|
42
57
|
const schema = getTransactionSchema(schemaId, ["nts2023", "jk"]);
|
|
43
|
-
const jkProp =
|
|
44
|
-
|
|
58
|
+
const jkProp =
|
|
59
|
+
schema.properties?.propertyPack?.properties?.specialistIssues
|
|
60
|
+
?.properties?.japaneseKnotweed;
|
|
61
|
+
|
|
45
62
|
expect(jkProp).toBeDefined();
|
|
63
|
+
|
|
46
64
|
expect(jkProp.ntsRef).toBe("A5.3");
|
|
47
65
|
expect(jkProp.required).toContain("yesNo");
|
|
48
66
|
expect(jkProp.discriminator?.propertyName).toBe("yesNo");
|
|
@@ -50,17 +68,26 @@ describe("Extension Overlays", () => {
|
|
|
50
68
|
|
|
51
69
|
test("should add Transfer Fees extension correctly", () => {
|
|
52
70
|
const schema = getTransactionSchema(schemaId, ["nts2023", "tf"]);
|
|
53
|
-
const tfProp =
|
|
54
|
-
|
|
71
|
+
const tfProp =
|
|
72
|
+
schema.properties?.propertyPack?.properties?.ownership?.properties
|
|
73
|
+
?.ownershipsToBeTransferred?.items?.oneOf?.[2]?.properties
|
|
74
|
+
?.leaseholdInformation?.properties?.serviceCharge?.oneOf?.[1]
|
|
75
|
+
?.properties?.transferFees;
|
|
76
|
+
|
|
55
77
|
expect(tfProp).toBeDefined();
|
|
56
78
|
expect(tfProp.ntsRef).toBe("A3.5.1.1");
|
|
57
|
-
expect(tfProp.title).toBe(
|
|
79
|
+
expect(tfProp.title).toBe(
|
|
80
|
+
"Are there any additional fees payable on sale or letting?"
|
|
81
|
+
);
|
|
58
82
|
});
|
|
59
83
|
|
|
60
84
|
test("should add Managing Agent extension correctly", () => {
|
|
61
85
|
const schema = getTransactionSchema(schemaId, ["nts2023", "ma"]);
|
|
62
|
-
const maProp =
|
|
63
|
-
|
|
86
|
+
const maProp =
|
|
87
|
+
schema.properties?.propertyPack?.properties?.ownership?.properties
|
|
88
|
+
?.ownershipsToBeTransferred?.items?.oneOf?.[2]?.properties
|
|
89
|
+
?.leaseholdInformation?.properties?.contactDetails;
|
|
90
|
+
|
|
64
91
|
expect(maProp).toBeDefined();
|
|
65
92
|
expect(maProp.ntsRef).toBe("A1.5.4");
|
|
66
93
|
expect(maProp.required).toContain("contacts");
|
|
@@ -68,32 +95,77 @@ describe("Extension Overlays", () => {
|
|
|
68
95
|
|
|
69
96
|
test("should add Solar Panels extension correctly", () => {
|
|
70
97
|
const schema = getTransactionSchema(schemaId, ["nts2023", "sl"]);
|
|
71
|
-
const slProp =
|
|
72
|
-
|
|
98
|
+
const slProp =
|
|
99
|
+
schema.properties?.propertyPack?.properties?.electricity?.properties
|
|
100
|
+
?.solarPanels?.oneOf?.[1]?.properties?.panelsOwnedOutright;
|
|
101
|
+
|
|
73
102
|
expect(slProp).toBeDefined();
|
|
74
103
|
expect(slProp.ntsRef).toBe("B3.7.1");
|
|
75
104
|
});
|
|
76
105
|
|
|
77
106
|
test("should add Heating Installation extension correctly", () => {
|
|
78
107
|
const schema = getTransactionSchema(schemaId, ["nts2023", "hi"]);
|
|
79
|
-
const hiProp =
|
|
80
|
-
|
|
108
|
+
const hiProp =
|
|
109
|
+
schema.properties?.propertyPack?.properties?.heating?.properties
|
|
110
|
+
?.heatingSystem?.oneOf?.[1]?.properties?.centralHeatingDetails
|
|
111
|
+
?.properties?.centralHeatingInstalled;
|
|
112
|
+
|
|
81
113
|
expect(hiProp).toBeDefined();
|
|
82
114
|
expect(hiProp.ntsRef).toBe("B3.4.3.2");
|
|
83
115
|
});
|
|
116
|
+
|
|
117
|
+
test("should add Estate Rentcharges extension correctly", () => {
|
|
118
|
+
const schema = getTransactionSchema(schemaId, ["nts2023", "er"]);
|
|
119
|
+
const erProp =
|
|
120
|
+
schema.properties?.propertyPack?.properties?.ownership?.properties
|
|
121
|
+
?.ownershipsToBeTransferred?.items?.oneOf?.[0]?.properties
|
|
122
|
+
?.estateRentcharges;
|
|
123
|
+
|
|
124
|
+
expect(erProp).toBeDefined();
|
|
125
|
+
|
|
126
|
+
expect(erProp.ntsRef).toBe("A3.4");
|
|
127
|
+
expect(erProp.required).toContain("yesNo");
|
|
128
|
+
expect(erProp.discriminator?.propertyName).toBe("yesNo");
|
|
129
|
+
expect(erProp.oneOf).toBeDefined();
|
|
130
|
+
expect(Array.isArray(erProp.oneOf)).toBe(true);
|
|
131
|
+
expect(erProp.oneOf.length).toBeGreaterThan(0);
|
|
132
|
+
|
|
133
|
+
// Check the conditional branch for "Yes" response
|
|
134
|
+
const yesBranch = erProp.oneOf.find(
|
|
135
|
+
(branch) =>
|
|
136
|
+
branch.required?.includes("details") &&
|
|
137
|
+
branch.required?.includes("amount")
|
|
138
|
+
);
|
|
139
|
+
expect(yesBranch).toBeDefined();
|
|
140
|
+
expect(yesBranch.properties?.details?.ntsRef).toBe("A3.4.2");
|
|
141
|
+
expect(yesBranch.properties?.amount?.ntsRef).toBe("A3.4.3");
|
|
142
|
+
});
|
|
84
143
|
});
|
|
85
144
|
|
|
86
145
|
describe("Extension overlay availability", () => {
|
|
87
146
|
test("should export all extension overlays", () => {
|
|
88
147
|
const expectedKeys = [
|
|
89
|
-
"as",
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"
|
|
148
|
+
"as",
|
|
149
|
+
"dr",
|
|
150
|
+
"jk",
|
|
151
|
+
"sb",
|
|
152
|
+
"hs", // Specialist Issues
|
|
153
|
+
"oa",
|
|
154
|
+
"la",
|
|
155
|
+
"sf",
|
|
156
|
+
"mc", // Property Features
|
|
157
|
+
"er",
|
|
158
|
+
"ma",
|
|
159
|
+
"tf", // Ownership & Financial
|
|
160
|
+
"sl",
|
|
161
|
+
"hi",
|
|
162
|
+
"fd", // Utilities & Services
|
|
163
|
+
"oc", // Transaction
|
|
94
164
|
];
|
|
95
|
-
|
|
96
|
-
expect(Object.keys(extensionOverlays).sort()).toEqual(
|
|
165
|
+
|
|
166
|
+
expect(Object.keys(extensionOverlays).sort()).toEqual(
|
|
167
|
+
expectedKeys.sort()
|
|
168
|
+
);
|
|
97
169
|
});
|
|
98
170
|
|
|
99
171
|
test("should have valid JSON structure for all extensions", () => {
|
|
@@ -110,78 +182,131 @@ describe("Extension Overlays", () => {
|
|
|
110
182
|
test("should produce equivalent result to nts2 when all relevant extensions are combined", () => {
|
|
111
183
|
// Get the full NTS2 schema
|
|
112
184
|
const nts2Schema = getTransactionSchema(schemaId, ["nts2025"]);
|
|
113
|
-
|
|
185
|
+
|
|
114
186
|
// Get NTS base with all relevant extensions
|
|
115
187
|
const allExtensions = [
|
|
116
188
|
"nts2023",
|
|
117
189
|
// Specialist issues extensions
|
|
118
|
-
"as",
|
|
119
|
-
|
|
120
|
-
"
|
|
190
|
+
"as",
|
|
191
|
+
"dr",
|
|
192
|
+
"jk",
|
|
193
|
+
"sb",
|
|
194
|
+
"hs",
|
|
195
|
+
// Property features extensions
|
|
196
|
+
"oa",
|
|
197
|
+
"la",
|
|
198
|
+
"sf",
|
|
199
|
+
"mc",
|
|
121
200
|
// Ownership & financial extensions
|
|
122
|
-
"er",
|
|
201
|
+
"er",
|
|
202
|
+
"ma",
|
|
203
|
+
"tf",
|
|
123
204
|
// Utilities & services extensions
|
|
124
|
-
"sl",
|
|
205
|
+
"sl",
|
|
206
|
+
"hi",
|
|
207
|
+
"fd",
|
|
125
208
|
// Transaction extensions
|
|
126
|
-
"oc"
|
|
209
|
+
"oc",
|
|
127
210
|
];
|
|
128
|
-
|
|
129
|
-
const ntsWithAllExtensions = getTransactionSchema(
|
|
130
|
-
|
|
211
|
+
|
|
212
|
+
const ntsWithAllExtensions = getTransactionSchema(
|
|
213
|
+
schemaId,
|
|
214
|
+
allExtensions
|
|
215
|
+
);
|
|
216
|
+
|
|
131
217
|
// Compare key structural elements
|
|
132
218
|
const nts2PropPack = nts2Schema.properties?.propertyPack;
|
|
133
219
|
const extPropPack = ntsWithAllExtensions.properties?.propertyPack;
|
|
134
|
-
|
|
220
|
+
|
|
135
221
|
// Check that specialist issues section exists in both
|
|
136
222
|
expect(nts2PropPack?.properties?.specialistIssues).toBeDefined();
|
|
137
223
|
expect(extPropPack?.properties?.specialistIssues).toBeDefined();
|
|
138
|
-
|
|
224
|
+
|
|
139
225
|
// Check key specialist issues properties
|
|
140
226
|
const nts2SI = nts2PropPack.properties.specialistIssues.properties;
|
|
141
227
|
const extSI = extPropPack.properties.specialistIssues.properties;
|
|
142
|
-
|
|
228
|
+
|
|
143
229
|
expect(extSI?.japaneseKnotweed).toBeDefined();
|
|
144
230
|
expect(extSI?.dryRotEtcTreatment).toBeDefined();
|
|
145
231
|
expect(extSI?.containsAsbestos).toBeDefined();
|
|
146
232
|
expect(extSI?.subsidenceOrStructuralFault).toBeDefined();
|
|
147
233
|
expect(extSI?.ongoingHealthOrSafetyIssue).toBeDefined();
|
|
148
|
-
|
|
234
|
+
|
|
149
235
|
// Check that references match (extensions use ntsRef, NTS2 uses nts2Ref)
|
|
150
236
|
if (nts2SI?.japaneseKnotweed && extSI?.japaneseKnotweed) {
|
|
151
237
|
expect(extSI.japaneseKnotweed.ntsRef).toBe("A5.3");
|
|
152
238
|
// NTS2 might have nts2Ref instead - this is expected difference
|
|
153
239
|
}
|
|
154
|
-
|
|
240
|
+
|
|
155
241
|
// Check outside areas
|
|
156
|
-
expect(
|
|
157
|
-
|
|
242
|
+
expect(
|
|
243
|
+
extPropPack?.properties?.residentialPropertyFeatures?.properties
|
|
244
|
+
?.outsideAreas
|
|
245
|
+
).toBeDefined();
|
|
246
|
+
|
|
158
247
|
// Check leasehold extensions
|
|
159
|
-
const leaseholdInfo =
|
|
248
|
+
const leaseholdInfo =
|
|
249
|
+
extPropPack?.properties?.ownership?.properties
|
|
250
|
+
?.ownershipsToBeTransferred?.items?.oneOf?.[2]?.properties
|
|
251
|
+
?.leaseholdInformation;
|
|
160
252
|
expect(leaseholdInfo?.properties?.contactDetails).toBeDefined(); // Managing agent
|
|
161
|
-
expect(
|
|
162
|
-
|
|
253
|
+
expect(
|
|
254
|
+
leaseholdInfo?.properties?.serviceCharge?.oneOf?.[1]?.properties
|
|
255
|
+
?.transferFees
|
|
256
|
+
).toBeDefined(); // Transfer fees
|
|
257
|
+
|
|
163
258
|
// Check utility extensions
|
|
164
|
-
expect(
|
|
165
|
-
|
|
166
|
-
|
|
259
|
+
expect(
|
|
260
|
+
extPropPack?.properties?.electricity?.properties?.solarPanels
|
|
261
|
+
?.oneOf?.[1]?.properties?.panelsOwnedOutright
|
|
262
|
+
).toBeDefined();
|
|
263
|
+
expect(
|
|
264
|
+
extPropPack?.properties?.heating?.properties?.heatingSystem?.oneOf?.[1]
|
|
265
|
+
?.properties?.centralHeatingDetails?.properties
|
|
266
|
+
?.centralHeatingInstalled
|
|
267
|
+
).toBeDefined();
|
|
268
|
+
|
|
167
269
|
// Check construction extensions
|
|
168
|
-
expect(
|
|
169
|
-
|
|
170
|
-
|
|
270
|
+
expect(
|
|
271
|
+
extPropPack?.properties?.typeOfConstruction?.properties?.loft
|
|
272
|
+
).toBeDefined();
|
|
273
|
+
expect(
|
|
274
|
+
extPropPack?.properties?.typeOfConstruction?.properties
|
|
275
|
+
?.sprayFoamInsulation
|
|
276
|
+
).toBeDefined();
|
|
277
|
+
|
|
171
278
|
// Check completion and moving
|
|
172
|
-
expect(
|
|
279
|
+
expect(
|
|
280
|
+
extPropPack?.properties?.completionAndMoving?.properties
|
|
281
|
+
?.otherPropertyInChain
|
|
282
|
+
).toBeDefined();
|
|
173
283
|
});
|
|
174
284
|
|
|
175
285
|
test("should validate data successfully with all extensions", () => {
|
|
176
286
|
const allExtensions = [
|
|
177
|
-
"nts2023",
|
|
178
|
-
"
|
|
287
|
+
"nts2023",
|
|
288
|
+
"as",
|
|
289
|
+
"dr",
|
|
290
|
+
"jk",
|
|
291
|
+
"sb",
|
|
292
|
+
"hs",
|
|
293
|
+
"oa",
|
|
294
|
+
"la",
|
|
295
|
+
"sf",
|
|
296
|
+
"mc",
|
|
297
|
+
"er",
|
|
298
|
+
"ma",
|
|
299
|
+
"tf",
|
|
300
|
+
"sl",
|
|
301
|
+
"hi",
|
|
302
|
+
"fd",
|
|
303
|
+
"oc",
|
|
179
304
|
];
|
|
180
|
-
|
|
305
|
+
|
|
181
306
|
const validator = getValidator(schemaId, allExtensions);
|
|
182
307
|
expect(validator).toBeDefined();
|
|
183
308
|
expect(typeof validator).toBe("function");
|
|
184
|
-
|
|
309
|
+
|
|
185
310
|
// Test with minimal valid data structure
|
|
186
311
|
const testData = {
|
|
187
312
|
propertyPack: {
|
|
@@ -205,11 +330,11 @@ describe("Extension Overlays", () => {
|
|
|
205
330
|
dryRotEtcTreatment: { yesNo: "No" },
|
|
206
331
|
containsAsbestos: { yesNo: "No" },
|
|
207
332
|
subsidenceOrStructuralFault: { yesNo: "No" },
|
|
208
|
-
ongoingHealthOrSafetyIssue: { yesNo: "No" }
|
|
209
|
-
}
|
|
210
|
-
}
|
|
333
|
+
ongoingHealthOrSafetyIssue: { yesNo: "No" },
|
|
334
|
+
},
|
|
335
|
+
},
|
|
211
336
|
};
|
|
212
|
-
|
|
337
|
+
|
|
213
338
|
// This might not validate due to missing required fields, but validator should not throw
|
|
214
339
|
expect(() => validator(testData)).not.toThrow();
|
|
215
340
|
});
|
|
@@ -218,8 +343,9 @@ describe("Extension Overlays", () => {
|
|
|
218
343
|
describe("Extension merging behavior", () => {
|
|
219
344
|
test("should preserve required arrays when merging extensions", () => {
|
|
220
345
|
const schema = getTransactionSchema(schemaId, ["nts2023", "jk", "as"]);
|
|
221
|
-
const siSection =
|
|
222
|
-
|
|
346
|
+
const siSection =
|
|
347
|
+
schema.properties?.propertyPack?.properties?.specialistIssues;
|
|
348
|
+
|
|
223
349
|
expect(siSection?.required).toBeDefined();
|
|
224
350
|
expect(siSection.required).toContain("japaneseKnotweed");
|
|
225
351
|
expect(siSection.required).toContain("containsAsbestos");
|
|
@@ -227,8 +353,10 @@ describe("Extension Overlays", () => {
|
|
|
227
353
|
|
|
228
354
|
test("should handle discriminator patterns correctly", () => {
|
|
229
355
|
const schema = getTransactionSchema(schemaId, ["nts2023", "jk"]);
|
|
230
|
-
const jkProp =
|
|
231
|
-
|
|
356
|
+
const jkProp =
|
|
357
|
+
schema.properties?.propertyPack?.properties?.specialistIssues
|
|
358
|
+
?.properties?.japaneseKnotweed;
|
|
359
|
+
|
|
232
360
|
expect(jkProp?.discriminator).toBeDefined();
|
|
233
361
|
expect(jkProp.discriminator.propertyName).toBe("yesNo");
|
|
234
362
|
expect(jkProp.oneOf).toBeDefined();
|
|
@@ -237,17 +365,78 @@ describe("Extension Overlays", () => {
|
|
|
237
365
|
|
|
238
366
|
test("should merge oneOf schemas correctly", () => {
|
|
239
367
|
const schema = getTransactionSchema(schemaId, ["nts2023", "tf"]);
|
|
240
|
-
const tfProp =
|
|
241
|
-
|
|
368
|
+
const tfProp =
|
|
369
|
+
schema.properties?.propertyPack?.properties?.ownership?.properties
|
|
370
|
+
?.ownershipsToBeTransferred?.items?.oneOf?.[2]?.properties
|
|
371
|
+
?.leaseholdInformation?.properties?.serviceCharge?.oneOf?.[1]
|
|
372
|
+
?.properties?.transferFees;
|
|
373
|
+
|
|
242
374
|
expect(tfProp?.oneOf).toBeDefined();
|
|
243
375
|
expect(tfProp.oneOf.length).toBeGreaterThan(0);
|
|
244
|
-
|
|
376
|
+
|
|
245
377
|
// Check the structure - details should be in the conditional oneOf branch
|
|
246
|
-
const conditionalBranch = tfProp.oneOf.find(
|
|
247
|
-
branch
|
|
378
|
+
const conditionalBranch = tfProp.oneOf.find(
|
|
379
|
+
(branch) =>
|
|
380
|
+
branch.properties?.details || branch.required?.includes("details")
|
|
248
381
|
);
|
|
249
382
|
expect(conditionalBranch).toBeDefined();
|
|
250
|
-
expect(
|
|
383
|
+
expect(
|
|
384
|
+
conditionalBranch.properties?.details ||
|
|
385
|
+
conditionalBranch.required?.includes("details")
|
|
386
|
+
).toBeTruthy();
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
test("should not require additional fields when 'No' is selected in extension overlays", () => {
|
|
390
|
+
// Test the 'as' (additional searches) extension overlay
|
|
391
|
+
const schema = getTransactionSchema(schemaId, ["as"]);
|
|
392
|
+
|
|
393
|
+
const containsAsbestos =
|
|
394
|
+
schema.properties?.propertyPack?.properties?.specialistIssues
|
|
395
|
+
?.properties?.containsAsbestos;
|
|
396
|
+
|
|
397
|
+
expect(containsAsbestos).toBeDefined();
|
|
398
|
+
expect(containsAsbestos.discriminator?.propertyName).toBe("yesNo");
|
|
399
|
+
expect(containsAsbestos.oneOf).toBeDefined();
|
|
400
|
+
expect(containsAsbestos.oneOf).toHaveLength(2); // Both "No" and "Yes" branches
|
|
401
|
+
|
|
402
|
+
// Find the "No" branch - it should not have additional required fields
|
|
403
|
+
const noBranch = containsAsbestos.oneOf.find((branch) =>
|
|
404
|
+
branch.properties?.yesNo?.enum?.includes("No")
|
|
405
|
+
);
|
|
406
|
+
expect(noBranch).toBeDefined();
|
|
407
|
+
expect(noBranch.properties.yesNo.enum).toEqual(["No"]);
|
|
408
|
+
// The "No" branch should not have additional required fields beyond "yesNo"
|
|
409
|
+
expect(noBranch.required).toBeUndefined();
|
|
410
|
+
|
|
411
|
+
// Find the "Yes" branch - it should have additional required fields
|
|
412
|
+
const yesBranch = containsAsbestos.oneOf.find((branch) =>
|
|
413
|
+
branch.properties?.yesNo?.enum?.includes("Yes")
|
|
414
|
+
);
|
|
415
|
+
expect(yesBranch).toBeDefined();
|
|
416
|
+
expect(yesBranch.properties.yesNo.enum).toEqual(["Yes"]);
|
|
417
|
+
expect(yesBranch.required).toBeDefined();
|
|
418
|
+
expect(yesBranch.required).toContain("details");
|
|
419
|
+
|
|
420
|
+
// Test that data with "No" answer validates correctly using subschema validation
|
|
421
|
+
const { getSubschemaValidator } = require("../../../index.js");
|
|
422
|
+
const subschemaValidator = getSubschemaValidator(
|
|
423
|
+
"/propertyPack/specialistIssues/containsAsbestos",
|
|
424
|
+
schemaId,
|
|
425
|
+
["as"]
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
const validDataWithNo = {
|
|
429
|
+
yesNo: "No",
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
const result = subschemaValidator(validDataWithNo);
|
|
433
|
+
// Handle both boolean and object return types
|
|
434
|
+
if (typeof result === "boolean") {
|
|
435
|
+
expect(result).toBe(true);
|
|
436
|
+
} else {
|
|
437
|
+
expect(result.valid).toBe(true);
|
|
438
|
+
expect(result.errors).toHaveLength(0);
|
|
439
|
+
}
|
|
251
440
|
});
|
|
252
441
|
});
|
|
253
|
-
});
|
|
442
|
+
});
|