Skip to content

Commit b08a54a

Browse files
committed
fix: Verify collection processing properties everywhere
This makes sure that *any* invalid processing property causes a validation error.
1 parent c6d5a0c commit b08a54a

File tree

2 files changed

+211
-52
lines changed

2 files changed

+211
-52
lines changed

json-schema/schema.json

Lines changed: 57 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"properties": {
2525
"allOf": [
2626
{
27-
"$ref": "#/definitions/require_any_field"
27+
"$ref": "#/definitions/fields"
2828
},
2929
{
3030
"$ref": "#/definitions/fields"
@@ -59,15 +59,10 @@
5959
},
6060
{
6161
"$ref": "#/definitions/stac_extensions"
62-
}
63-
],
64-
"anyOf": [
62+
},
6563
{
6664
"$comment": "Validate fields in Collection Providers.",
6765
"type": "object",
68-
"required": [
69-
"providers"
70-
],
7166
"properties": {
7267
"providers": {
7368
"type": "array",
@@ -95,7 +90,7 @@
9590
}
9691
},
9792
{
98-
"$ref": "#/definitions/require_any_field"
93+
"$ref": "#/definitions/fields"
9994
},
10095
{
10196
"$ref": "#/definitions/fields"
@@ -116,64 +111,84 @@
116111
{
117112
"type": "object",
118113
"$comment": "This validates the fields in Collection Assets, but does not require them.",
119-
"required": [
120-
"assets"
121-
],
122114
"properties": {
123115
"assets": {
124116
"type": "object",
125-
"not": {
126-
"additionalProperties": {
127-
"not": {
128-
"allOf": [
129-
{
130-
"$ref": "#/definitions/require_any_field"
131-
},
132-
{
133-
"$ref": "#/definitions/fields"
134-
}
135-
]
117+
"additionalProperties": {
118+
"allOf": [
119+
{
120+
"$ref": "#/definitions/fields"
121+
},
122+
{
123+
"$ref": "#/definitions/fields"
136124
}
137-
}
125+
]
138126
}
139127
}
140128
}
141129
},
142130
{
143131
"type": "object",
144132
"$comment": "This is the schema for the fields in Item Asset Definitions. It doesn't require any fields.",
145-
"required": [
146-
"item_assets"
147-
],
148133
"properties": {
149134
"item_assets": {
150135
"type": "object",
151-
"not": {
152-
"additionalProperties": {
153-
"not": {
154-
"allOf": [
155-
{
156-
"$ref": "#/definitions/require_any_field"
157-
},
158-
{
159-
"$ref": "#/definitions/fields"
160-
}
161-
]
136+
"additionalProperties": {
137+
"allOf": [
138+
{
139+
"$ref": "#/definitions/fields"
140+
},
141+
{
142+
"$ref": "#/definitions/fields"
162143
}
163-
}
144+
]
164145
}
165146
}
166147
}
167148
},
168149
{
169150
"type": "object",
170151
"$comment": "This is the schema for the fields in Summaries. By default, only checks the existance of the properties, but not the schema of the summaries.",
171-
"required": [
172-
"summaries"
173-
],
174152
"properties": {
175153
"summaries": {
176-
"$ref": "#/definitions/require_any_field"
154+
"type": "object",
155+
"properties": {
156+
"processing:expression": {
157+
"type": "array",
158+
"items": {
159+
"$ref": "#/definitions/fields/properties/processing:expression"
160+
},
161+
"minItems": 1
162+
},
163+
"processing:facility": {
164+
"type": "array",
165+
"items": {
166+
"$ref": "#/definitions/fields/properties/processing:facility"
167+
},
168+
"minItems": 1
169+
},
170+
"processing:level": {
171+
"type": "array",
172+
"items": {
173+
"$ref": "#/definitions/fields/properties/processing:level"
174+
},
175+
"minItems": 1
176+
},
177+
"processing:lineage": {
178+
"type": "array",
179+
"items": {
180+
"$ref": "#/definitions/fields/properties/processing:lineage"
181+
},
182+
"minItems": 1
183+
},
184+
"processing:software": {
185+
"type": "array",
186+
"items": {
187+
"$ref": "#/definitions/fields/properties/processing:software"
188+
},
189+
"minItems": 1
190+
}
191+
}
177192
}
178193
}
179194
}
@@ -195,16 +210,6 @@
195210
}
196211
}
197212
},
198-
"require_any_field": {
199-
"$comment": "Please list all fields here so that we can force the existence of one of them in other parts of the schemas.",
200-
"anyOf": [
201-
{"type": "object", "required": ["processing:expression"]},
202-
{"type": "object", "required": ["processing:lineage"]},
203-
{"type": "object", "required": ["processing:level"]},
204-
{"type": "object", "required": ["processing:facility"]},
205-
{"type": "object", "required": ["processing:software"]}
206-
]
207-
},
208213
"fields": {
209214
"$comment": "Add your new fields here. Don't require them here, do that above in the corresponding schema.",
210215
"type": "object",

tests/collection.test.js

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,158 @@ describe('Collection example', () => {
2222

2323
expect(valid).toBeTruthy();
2424
});
25+
26+
it('should fail validation when providers processing expression is invalid', async () => {
27+
// given
28+
example.providers[0]['processing:expression'] = null;
29+
30+
// when
31+
let valid = validate(example);
32+
33+
// then
34+
expect(valid).toBeFalsy();
35+
expect(
36+
validate.errors.some(
37+
(error) =>
38+
error.instancePath === '/providers/0/processing:expression'
39+
&& error.message === 'must be object',
40+
)
41+
).toBeTruthy();
42+
});
43+
44+
it('should fail validation when asset processing expression is invalid', async () => {
45+
// given
46+
example.assets = {
47+
'example': {
48+
'href': 'https://example.org/file.xyz',
49+
'processing:expression': null,
50+
}
51+
};
52+
53+
// when
54+
let valid = validate(example);
55+
56+
// then
57+
expect(valid).toBeFalsy();
58+
expect(
59+
validate.errors.some(
60+
(error) =>
61+
error.instancePath === '/assets/example/processing:expression'
62+
&& error.message === 'must be object',
63+
)
64+
).toBeTruthy();
65+
});
66+
67+
it('should fail validation when item asset processing expression is invalid', async () => {
68+
// given
69+
example.item_assets = {
70+
'example': {
71+
'href': 'https://example.org/file.xyz',
72+
'processing:expression': null,
73+
}
74+
};
75+
76+
// when
77+
let valid = validate(example);
78+
79+
// then
80+
expect(valid).toBeFalsy();
81+
expect(
82+
validate.errors.some(
83+
(error) =>
84+
error.instancePath === '/item_assets/example/processing:expression'
85+
&& error.message === 'must be object',
86+
)
87+
).toBeTruthy();
88+
});
89+
90+
it('should fail validation when summary processing expression is invalid', async () => {
91+
// given
92+
example.summaries['processing:expression'] = null;
93+
94+
// when
95+
let valid = validate(example);
96+
97+
// then
98+
expect(valid).toBeFalsy();
99+
expect(
100+
validate.errors.some(
101+
(error) =>
102+
error.instancePath === '/summaries/processing:expression'
103+
&& error.message === 'must be array',
104+
)
105+
).toBeTruthy();
106+
});
107+
108+
it('should fail validation when summary processing facility is invalid', async () => {
109+
// given
110+
example.summaries['processing:facility'] = null;
111+
112+
// when
113+
let valid = validate(example);
114+
115+
// then
116+
expect(valid).toBeFalsy();
117+
expect(
118+
validate.errors.some(
119+
(error) =>
120+
error.instancePath === '/summaries/processing:facility'
121+
&& error.message === 'must be array',
122+
)
123+
).toBeTruthy();
124+
});
125+
126+
it('should fail validation when summary processing level is invalid', async () => {
127+
// given
128+
example.summaries['processing:level'] = null;
129+
130+
// when
131+
let valid = validate(example);
132+
133+
// then
134+
expect(valid).toBeFalsy();
135+
expect(
136+
validate.errors.some(
137+
(error) =>
138+
error.instancePath === '/summaries/processing:level'
139+
&& error.message === 'must be array',
140+
)
141+
).toBeTruthy();
142+
});
143+
144+
it('should fail validation when summary processing lineage is invalid', async () => {
145+
// given
146+
example.summaries['processing:lineage'] = null;
147+
148+
// when
149+
let valid = validate(example);
150+
151+
// then
152+
expect(valid).toBeFalsy();
153+
expect(
154+
validate.errors.some(
155+
(error) =>
156+
error.instancePath === '/summaries/processing:lineage'
157+
&& error.message === 'must be array',
158+
)
159+
).toBeTruthy();
160+
});
161+
162+
it('should fail validation when summary processing software is invalid', async () => {
163+
// given
164+
example.summaries['processing:software'] = null;
165+
166+
// when
167+
let valid = validate(example);
168+
169+
// then
170+
expect(valid).toBeFalsy();
171+
expect(
172+
validate.errors.some(
173+
(error) =>
174+
error.instancePath === '/summaries/processing:software'
175+
&& error.message === 'must be array',
176+
)
177+
).toBeTruthy();
178+
});
25179
});

0 commit comments

Comments
 (0)