Repository: networknt/json-schema-validator
Pull request #77 (2018-03-15 15:51:44)

One of was broken - it did not fail when there were no valid schemas
There was actually a bug in my previous commit for shortcut validation of oneOf - we reported success even if none of the schemas validated.  Sorry for sending you a patch without appropriate test case.

Here is the test case and a fix for that one.

But I noticed that https://github.com/networknt/json-schema-validator/commit/a77673858c7df3f2b08eedb6b971cd74fda58920#comments seems to have originally introduced the behaviour I called "bug" above deliberately. Unfortunately the question posted by @bamateus underneath that commit was not answered. As far as I understand the json schema spec, we must not validate oneOfs when none of the schemas validates. And if the validation error is about an additional property, it still is a validation error (if it was reported wrongly then it should be fixed in the validation code for additional properties, not here). 


Patch:
diff --git a/src/main/java/com/networknt/schema/OneOfValidator.java b/src/main/java/com/networknt/schema/OneOfValidator.java
index c80f82c..1e54503 100644
--- a/src/main/java/com/networknt/schema/OneOfValidator.java
+++ b/src/main/java/com/networknt/schema/OneOfValidator.java
@@ -141,14 +141,14 @@ public class OneOfValidator extends BaseJsonValidator implements JsonValidator {
                 continue;
             }
             JsonSchema schema = validator.schema;
-        	Set<ValidationMessage> schemaErrors = schema.validate(node, rootNode, at);
+        	    Set<ValidationMessage> schemaErrors = schema.validate(node, rootNode, at);
             if (schemaErrors.isEmpty()) {
                 numberOfValidSchema++;
                 errors = new LinkedHashSet<ValidationMessage>();
             }
             if(numberOfValidSchema == 0){
         		errors.addAll(schemaErrors);
-        	}
+        	    }
             if (numberOfValidSchema > 1) {
                 break;
             }
@@ -161,10 +161,10 @@ public class OneOfValidator extends BaseJsonValidator implements JsonValidator {
                 if (ValidatorTypeCode.ADDITIONAL_PROPERTIES.getValue().equals(msg.getType())) {
                     it.remove();
                 }
-                if (errors.isEmpty()) {
-                    // ensure there is always an error reported if number of valid schemas is 0
-                    errors.add(buildValidationMessage(at, ""));
-                }
+            }
+            if (errors.isEmpty()) {
+                // ensure there is always an error reported if number of valid schemas is 0
+                errors.add(buildValidationMessage(at, ""));
             }
         }
         if (numberOfValidSchema > 1) {


Test patch:
diff --git a/src/test/java/com/networknt/schema/JsonSchemaTest.java b/src/test/java/com/networknt/schema/JsonSchemaTest.java
index 33ba586..ec485c6 100644
--- a/src/test/java/com/networknt/schema/JsonSchemaTest.java
+++ b/src/test/java/com/networknt/schema/JsonSchemaTest.java
@@ -228,7 +228,7 @@ public class JsonSchemaTest {
     public void testOneOfValidator() throws Exception {
         runTestFile("tests/oneOf.json");
     }
-
+    
     @Test
     public void testPatternValidator() throws Exception {
         runTestFile("tests/pattern.json");
diff --git a/src/test/resources/tests/oneOf.json b/src/test/resources/tests/oneOf.json
index 1eaa4e4..34df669 100644
--- a/src/test/resources/tests/oneOf.json
+++ b/src/test/resources/tests/oneOf.json
@@ -64,5 +64,62 @@
                 "valid": false
             }
         ]
+    },
+    {
+        "description": "oneOf with objects and type pattern",
+        "schema": {
+			"oneOf": [
+				{
+					"type": "object",
+					"required": [
+						"type"
+					],
+					"properties": {
+						"type": {
+							"enum": [
+								"TYPE_1"
+							]
+						}
+					}
+				},			
+				{
+					"type": "object",
+					"required": [
+						"type"
+					],
+					"properties": {
+						"type": {
+							"enum": [
+								"TYPE_2"
+							]
+						}
+					}
+				}
+				
+			]
+		},
+        "tests": [
+            {
+                "description": "first oneOf valid",
+                "data": {
+				    "type": "TYPE_1"
+				},
+                "valid": true
+            },
+            {
+                "description": "second oneOf valid",
+                "data": {
+				    "type": "TYPE_2"
+				},
+                "valid": true
+            },
+            {
+                "description": "neither oneOf valid",
+                "data": {
+				    "type": "INVALID_TYPE"
+				},
+                "valid": false
+            }
+        ]
     }
 ]