Skip to content

Commit 7f96315

Browse files
authored
parent schema of additionItems can be correctly referenced (#493) (#497)
1 parent 788c0aa commit 7f96315

File tree

7 files changed

+212
-2
lines changed

7 files changed

+212
-2
lines changed

src/main/java/com/networknt/schema/ItemsValidator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public ItemsValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentS
5858
if (addItemNode.isBoolean()) {
5959
additionalItems = addItemNode.asBoolean();
6060
} else if (addItemNode.isObject()) {
61-
foundAdditionalSchema = new JsonSchema(validationContext, parentSchema.getCurrentUri(), addItemNode);
61+
foundAdditionalSchema = new JsonSchema(validationContext, "#", parentSchema.getCurrentUri(), addItemNode, parentSchema);
6262
}
6363
}
6464
}
@@ -197,4 +197,4 @@ public void preloadJsonSchema() {
197197
additionalSchema.initializeValidators();
198198
}
199199
}
200-
}
200+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package com.networknt.schema;
2+
3+
import static org.hamcrest.MatcherAssert.assertThat;
4+
5+
import java.io.InputStream;
6+
import java.util.HashSet;
7+
import java.util.Set;
8+
9+
import org.hamcrest.Matchers;
10+
import org.junit.jupiter.api.Assertions;
11+
import org.junit.jupiter.api.DisplayName;
12+
import org.junit.jupiter.api.Test;
13+
14+
import com.fasterxml.jackson.databind.JsonNode;
15+
import com.fasterxml.jackson.databind.ObjectMapper;
16+
17+
class Issue493Test
18+
{
19+
20+
private static JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909);
21+
private static String schemaPath1 = "/schema/issue493.json";
22+
23+
private JsonNode getJsonNodeFromJsonData (String jsonFilePath)
24+
throws Exception
25+
{
26+
InputStream content = getClass().getResourceAsStream(jsonFilePath);
27+
ObjectMapper mapper = new ObjectMapper();
28+
return mapper.readTree(content);
29+
}
30+
31+
@Test
32+
@DisplayName("Test valid with required item only")
33+
void testValidJson1 ()
34+
throws Exception
35+
{
36+
InputStream schemaInputStream = Issue493Test.class.getResourceAsStream(schemaPath1);
37+
JsonSchema schema = factory.getSchema(schemaInputStream);
38+
JsonNode node = getJsonNodeFromJsonData("/data/issue493-valid-1.json");
39+
Set<ValidationMessage> errors = schema.validate(node);
40+
Assertions.assertTrue(errors.isEmpty());
41+
}
42+
43+
@Test
44+
@DisplayName("Test valid with optional item")
45+
void testValidJson2 ()
46+
throws Exception
47+
{
48+
InputStream schemaInputStream = Issue493Test.class.getResourceAsStream(schemaPath1);
49+
JsonSchema schema = factory.getSchema(schemaInputStream);
50+
JsonNode node = getJsonNodeFromJsonData("/data/issue493-valid-2.json");
51+
Set<ValidationMessage> errors = schema.validate(node);
52+
Assertions.assertTrue(errors.isEmpty());
53+
}
54+
55+
@Test
56+
@DisplayName("Test invalid with required item but wrong type")
57+
void testInvalidJson1 ()
58+
throws Exception
59+
{
60+
InputStream schemaInputStream = Issue491Test.class.getResourceAsStream(schemaPath1);
61+
JsonSchema schema = factory.getSchema(schemaInputStream);
62+
JsonNode node = getJsonNodeFromJsonData("/data/issue493-invalid-1.json");
63+
Set<ValidationMessage> errors = schema.validate(node);
64+
Assertions.assertEquals(2, errors.size());
65+
66+
Set<String> allErrorMessages = new HashSet<>();
67+
errors.forEach(vm -> {
68+
allErrorMessages.add(vm.getMessage());
69+
});
70+
assertThat(allErrorMessages,
71+
Matchers.containsInAnyOrder("$.parameters[0].value: string found, integer expected",
72+
"$.parameters[0].value: does not match the regex pattern ^\\{\\{.+\\}\\}$"));
73+
}
74+
75+
@Test
76+
@DisplayName("Test invalid with optional item but wrong type")
77+
void testInvalidJson2 ()
78+
throws Exception
79+
{
80+
InputStream schemaInputStream = Issue491Test.class.getResourceAsStream(schemaPath1);
81+
JsonSchema schema = factory.getSchema(schemaInputStream);
82+
JsonNode node = getJsonNodeFromJsonData("/data/issue493-invalid-2.json");
83+
Set<ValidationMessage> errors = schema.validate(node);
84+
Assertions.assertEquals(2, errors.size());
85+
86+
Set<String> allErrorMessages = new HashSet<>();
87+
errors.forEach(vm -> {
88+
allErrorMessages.add(vm.getMessage());
89+
});
90+
assertThat(allErrorMessages,
91+
Matchers.containsInAnyOrder("$.parameters[1].value: string found, integer expected",
92+
"$.parameters[1].value: does not match the regex pattern ^\\{\\{.+\\}\\}$"));
93+
}
94+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"parameters": [
3+
{
4+
"name": "param-required",
5+
"value": "wrongtype"
6+
}
7+
]
8+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"parameters": [
3+
{
4+
"name": "param-required",
5+
"value": 123
6+
},
7+
{
8+
"name": "param-optional",
9+
"value": "wrongtype"
10+
}
11+
]
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"parameters": [
3+
{
4+
"name": "param-required",
5+
"value": 123
6+
},
7+
{
8+
"name": "param-optional",
9+
"value": "{{test}}"
10+
}
11+
]
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"parameters": [
3+
{
4+
"name": "param-required",
5+
"value": 123
6+
},
7+
{
8+
"name": "param-optional",
9+
"value": "{{test}}"
10+
}
11+
]
12+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2019-09/schema",
3+
"type": "object",
4+
"additionalProperties": false,
5+
"properties": {
6+
"parameters": {
7+
"type": "array",
8+
"uniqueItems": true,
9+
"items": [
10+
{
11+
"type": "object",
12+
"required": [
13+
"name",
14+
"value"
15+
],
16+
"properties": {
17+
"name": {
18+
"const": "param-required"
19+
},
20+
"value": {
21+
"anyOf": [
22+
{
23+
"$ref": "#/$defs/test-ref1"
24+
},
25+
{
26+
"$ref": "#/$defs/test-ref2"
27+
}
28+
]
29+
}
30+
}
31+
}
32+
],
33+
"additionalItems": {
34+
"oneOf": [
35+
{
36+
"type": "object",
37+
"required": [
38+
"name",
39+
"value"
40+
],
41+
"properties": {
42+
"name": {
43+
"const": "param-optional"
44+
},
45+
"value": {
46+
"anyOf": [
47+
{
48+
"$ref": "#/$defs/test-ref1"
49+
},
50+
{
51+
"$ref": "#/$defs/test-ref2"
52+
}
53+
]
54+
}
55+
}
56+
}
57+
]
58+
},
59+
"minItems": 1,
60+
"maxItems": 2
61+
}
62+
},
63+
"$defs": {
64+
"test-ref1": {
65+
"type": "string",
66+
"pattern": "^\\{\\{.+\\}\\}$"
67+
},
68+
"test-ref2": {
69+
"type": "integer"
70+
}
71+
}
72+
}

0 commit comments

Comments
 (0)