Repository: networknt/json-schema-validator
Pull request #384 (2021-03-13 20:06:38)

Test case and potential fix for #383
- signal nodeMatch to parent handler in OneOfValidator

codecov-io: # [Codecov](https://codecov.io/gh/networknt/json-schema-validator/pull/384?src=pr&el=h1) Report
> Merging [#384](https://codecov.io/gh/networknt/json-schema-validator/pull/384?src=pr&el=desc) (09b2b04) into [master](https://codecov.io/gh/networknt/json-schema-validator/commit/e692d47195dfc311f6427ac811a4d1f01bb52a6e?el=desc) (e692d47) will **increase** coverage by `0.09%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/networknt/json-schema-validator/pull/384/graphs/tree.svg?width=650&height=150&src=pr&token=Dq6aZ2eKq9)](https://codecov.io/gh/networknt/json-schema-validator/pull/384?src=pr&el=tree)

```diff
@@             Coverage Diff              @@
##             master     #384      +/-   ##
============================================
+ Coverage     69.53%   69.63%   +0.09%     
- Complexity      705      707       +2     
============================================
  Files            81       81              
  Lines          2764     2766       +2     
  Branches        561      562       +1     
============================================
+ Hits           1922     1926       +4     
+ Misses          627      626       -1     
+ Partials        215      214       -1     
```


| [Impacted Files](https://codecov.io/gh/networknt/json-schema-validator/pull/384?src=pr&el=tree) | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| [...main/java/com/networknt/schema/OneOfValidator.java](https://codecov.io/gh/networknt/json-schema-validator/pull/384/diff?src=pr&el=tree#diff-c3JjL21haW4vamF2YS9jb20vbmV0d29ya250L3NjaGVtYS9PbmVPZlZhbGlkYXRvci5qYXZh) | `61.01% <100.00%> (+1.53%)` | `12.00 <0.00> (+1.00)` | |
| [.../main/java/com/networknt/schema/JsonSchemaRef.java](https://codecov.io/gh/networknt/json-schema-validator/pull/384/diff?src=pr&el=tree#diff-c3JjL21haW4vamF2YS9jb20vbmV0d29ya250L3NjaGVtYS9Kc29uU2NoZW1hUmVmLmphdmE=) | `91.66% <0.00%> (+8.33%)` | `5.00% <0.00%> (+1.00%)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/networknt/json-schema-validator/pull/384?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/networknt/json-schema-validator/pull/384?src=pr&el=footer). Last update [e692d47...09b2b04](https://codecov.io/gh/networknt/json-schema-validator/pull/384?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/src/main/java/com/networknt/schema/OneOfValidator.java b/src/main/java/com/networknt/schema/OneOfValidator.java
index f489b3e..e15194a 100644
--- a/src/main/java/com/networknt/schema/OneOfValidator.java
+++ b/src/main/java/com/networknt/schema/OneOfValidator.java
@@ -197,6 +197,9 @@ public class OneOfValidator extends BaseJsonValidator implements JsonValidator {
             }
         }
 
+        // Make sure to signal parent handlers we matched
+        if (errors.isEmpty())
+            state.setMatchedNode(true);
 
         // reset the ValidatorState object in the ThreadLocal
         validatorState.remove();


Test patch:
diff --git a/src/test/java/com/networknt/schema/Issue383Test.java b/src/test/java/com/networknt/schema/Issue383Test.java
new file mode 100644
index 0000000..cb9c162
--- /dev/null
+++ b/src/test/java/com/networknt/schema/Issue383Test.java
@@ -0,0 +1,35 @@
+package com.networknt.schema;
+
+import java.io.InputStream;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class Issue383Test {
+    protected JsonSchema getJsonSchemaFromStreamContentV7(InputStream schemaContent) {
+        JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7);
+        return factory.getSchema(schemaContent);
+    }
+
+    protected JsonNode getJsonNodeFromStreamContent(InputStream content) throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode node = mapper.readTree(content);
+        return node;
+    }
+
+    @Test
+    public void nestedOneOfsShouldStillMatchV7() throws Exception {
+        String schemaPath = "/schema/issue383-v7.json";
+        String dataPath = "/data/issue383.json";
+        InputStream schemaInputStream = getClass().getResourceAsStream(schemaPath);
+        JsonSchema schema = getJsonSchemaFromStreamContentV7(schemaInputStream);
+        InputStream dataInputStream = getClass().getResourceAsStream(dataPath);
+        JsonNode node = getJsonNodeFromStreamContent(dataInputStream);
+        Set<ValidationMessage> errors = schema.validate(node);
+        Assert.assertEquals(0, errors.size());
+    }
+}
diff --git a/src/test/resources/data/issue383.json b/src/test/resources/data/issue383.json
new file mode 100644
index 0000000..7fed0c5
--- /dev/null
+++ b/src/test/resources/data/issue383.json
@@ -0,0 +1,11 @@
+{
+  "validation": {
+    "all": [
+      {
+        "notEmpty": {
+          "field": "test"
+        }
+      }
+    ]
+  }
+}
diff --git a/src/test/resources/schema/issue383-v7.json b/src/test/resources/schema/issue383-v7.json
new file mode 100644
index 0000000..aa28c75
--- /dev/null
+++ b/src/test/resources/schema/issue383-v7.json
@@ -0,0 +1,85 @@
+{
+  "type": "object",
+  "properties": {
+    "validation": {
+      "$ref": "#/definitions/predicateOrNull"
+    }
+  },
+  "definitions": {
+    "fieldRef": {
+      "type": "object",
+      "properties": {
+        "field": {
+          "type": "string"
+        },
+        "set": {
+          "type": "string"
+        }
+      },
+      "required": [
+        "field"
+      ]
+    },
+    "patternPredicate": {
+      "type": "object",
+      "oneOf": [
+        {
+          "properties": {
+            "notEmpty": {
+              "$ref": "#/definitions/fieldRef"
+            }
+          },
+          "required": [
+            "notEmpty"
+          ]
+        },
+        {
+          "properties": {
+            "notBlank": {
+              "$ref": "#/definitions/fieldRef"
+            }
+          },
+          "required": [
+            "notBlank"
+          ]
+        }
+      ]
+    },
+    "allPredicate": {
+      "type": "object",
+      "properties": {
+        "all": {
+          "type": "array",
+          "minItems": 1,
+          "items": {
+            "$ref": "#/definitions/predicate"
+          }
+        }
+      },
+      "required": [
+        "all"
+      ]
+    },
+    "predicate": {
+      "type": "object",
+      "oneOf": [
+        {
+          "$ref": "#/definitions/patternPredicate"
+        },
+        {
+          "$ref": "#/definitions/allPredicate"
+        }
+      ]
+    },
+    "predicateOrNull": {
+      "oneOf": [
+        {
+          "$ref": "#/definitions/predicate"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  }
+}