Skip to content

Commit ee6ee43

Browse files
authored
Merge pull request #143 from networknt/fix/#142-enum-object-validation
Fix/#142 enum object validation
2 parents c58aab8 + 3c9d0e0 commit ee6ee43

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,20 @@
2424
import java.util.Set;
2525

2626
public class TypeValidator extends BaseJsonValidator implements JsonValidator {
27+
private static final String TYPE = "type";
28+
private static final String ENUM = "enum";
29+
private static final String REF = "$ref";
30+
2731
private static final Logger logger = LoggerFactory.getLogger(TypeValidator.class);
2832

2933
private JsonType schemaType;
34+
private JsonSchema parentSchema;
3035
private UnionTypeValidator unionTypeValidator;
3136

3237
public TypeValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
3338
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.TYPE, validationContext);
3439
schemaType = TypeFactory.getSchemaNodeType(schemaNode);
40+
this.parentSchema = parentSchema;
3541

3642
if (schemaType == JsonType.UNION) {
3743
unionTypeValidator = new UnionTypeValidator(schemaPath, schemaNode, parentSchema, validationContext);
@@ -62,6 +68,11 @@ public boolean equalsToSchemaType(JsonNode node) {
6268
return true;
6369
}
6470
}
71+
// Skip the type validation when the schema is an enum object schema. Since the current type
72+
// of node itself can be used for type validation.
73+
if (isEnumObjectSchema(parentSchema)) {
74+
return true;
75+
}
6576
if(config.isTypeLoose()) {
6677
if (nodeType == JsonType.STRING) {
6778
if(schemaType == JsonType.INTEGER) {
@@ -215,4 +226,28 @@ public static boolean isNumber(JsonNode node, boolean isTypeLoose) {
215226
}
216227
return false;
217228
}
229+
230+
private static boolean isEnumObjectSchema(JsonSchema jsonSchema) {
231+
// There are three conditions for enum object schema
232+
// 1. The current schema contains key "type", and the value is object
233+
// 2. The current schema contains key "enum", and the value is an array
234+
// 3. The parent schema if refer from components, which means the corresponding enum object class would be generated
235+
JsonNode typeNode = null;
236+
JsonNode enumNode = null;
237+
JsonNode refNode = null;
238+
239+
if (jsonSchema != null) {
240+
if (jsonSchema.getSchemaNode() != null) {
241+
typeNode = jsonSchema.getSchemaNode().get(TYPE);
242+
enumNode = jsonSchema.getSchemaNode().get(ENUM);
243+
}
244+
if (jsonSchema.getParentSchema() != null && jsonSchema.getParentSchema().getSchemaNode() != null) {
245+
refNode = jsonSchema.getParentSchema().getSchemaNode().get(REF);
246+
}
247+
}
248+
if (typeNode != null && enumNode != null && refNode != null) {
249+
return TypeFactory.getSchemaNodeType(typeNode) == JsonType.OBJECT && enumNode.isArray();
250+
}
251+
return false;
252+
}
218253
}

src/test/java/com/networknt/schema/JsonSchemaTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,11 @@ public void testUnionTypeValidator() throws Exception {
284284
public void testUniqueItemsValidator() throws Exception {
285285
runTestFile("tests/uniqueItems.json");
286286
}
287+
288+
@Test
289+
public void testEnumObject() throws Exception {
290+
runTestFile("tests/enumObject.json");
291+
}
287292

288293
@Test
289294
public void testIdSchemaWithUrl() throws Exception {
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
[
2+
{
3+
"description": "simple enum object validation",
4+
"schema": {
5+
"properties": {
6+
"foo": {
7+
"type": "object",
8+
"enum": [1, 2, 3]
9+
},
10+
"bar": {
11+
"$ref": "#/properties/foo"
12+
}
13+
}
14+
},
15+
"tests": [
16+
{
17+
"description": "one of the enum is valid",
18+
"data": {
19+
"bar": 1
20+
},
21+
"valid": true
22+
},
23+
{
24+
"description": "one of the enum is valid",
25+
"isTypeLoose": true,
26+
"data": {
27+
"bar": "1"
28+
},
29+
"valid": true
30+
},
31+
{
32+
"description": "something else is invalid",
33+
"isTypeLoose": false,
34+
"data": {
35+
"bar": "1"
36+
},
37+
"valid": false
38+
},
39+
{
40+
"description": "something else is invalid",
41+
"data": {
42+
"bar": 4
43+
},
44+
"valid": false
45+
}
46+
]
47+
},
48+
{
49+
"description": "fake enum object validation",
50+
"schema": {
51+
"type": "object",
52+
"enum": [1, 2, {"key": "value"}]
53+
},
54+
"tests": [
55+
{
56+
"description": "one of the enum is invalid",
57+
"data": 1,
58+
"valid": false
59+
},
60+
{
61+
"description": "one of the enum is valid",
62+
"isTypeLoose": true,
63+
"data": {"key": "value"},
64+
"valid": true
65+
}
66+
]
67+
}
68+
]

0 commit comments

Comments
 (0)