Repository: networknt/json-schema-validator
Pull request #376 (2021-02-12 17:21:07)

PropertyNames to return validator value on error (#375)
* Fix for issue-375


Patch:
diff --git a/src/main/java/com/networknt/schema/PropertyNamesValidator.java b/src/main/java/com/networknt/schema/PropertyNamesValidator.java
index 8d53693..c8407c4 100644
--- a/src/main/java/com/networknt/schema/PropertyNamesValidator.java
+++ b/src/main/java/com/networknt/schema/PropertyNamesValidator.java
@@ -35,7 +35,7 @@ public class PropertyNamesValidator extends BaseJsonValidator implements JsonVal
             for (Iterator<String> it = schemaNode.fieldNames(); it.hasNext(); ) {
                 String pname = it.next();
                 schemas.put(pname, new JsonSchema(validationContext, schemaPath + "/" + pname, parentSchema.getCurrentUri(), schemaNode.get(pname), parentSchema)
-                        .initialize());
+                    .initialize());
             }
         }
     }
@@ -53,14 +53,17 @@ public class PropertyNamesValidator extends BaseJsonValidator implements JsonVal
                 }
                 for (Iterator<String> it = node.fieldNames(); it.hasNext(); ) {
                     String pname = it.next();
-                    if("maxLength".equals(entry.getKey()) && pname.length() > entry.getValue().getSchemaNode().intValue()) {
-                        errors.add(buildValidationMessage(at + "." + pname, "maxLength"));
+                    int maxLength = entry.getValue().getSchemaNode().intValue();
+                    if("maxLength".equals(entry.getKey()) && pname.length() > maxLength) {
+                        errors.add(buildValidationMessage(at + "." + pname, "maxLength " + maxLength));
                     }
-                    if("minLength".equals(entry.getKey()) && pname.length() < entry.getValue().getSchemaNode().intValue()) {
-                        errors.add(buildValidationMessage(at + "." + pname, "minLength"));
+                    int minLength = entry.getValue().getSchemaNode().intValue();
+                    if("minLength".equals(entry.getKey()) && pname.length() < minLength) {
+                        errors.add(buildValidationMessage(at + "." + pname, "minLength " + minLength));
                     }
-                    if("pattern".equals(entry.getKey()) && !Pattern.matches(entry.getValue().getSchemaNode().textValue(),pname)) {
-                        errors.add(buildValidationMessage(at + "." + pname, "pattern"));
+                    String pattern = entry.getValue().getSchemaNode().textValue();
+                    if("pattern".equals(entry.getKey()) && !Pattern.matches(pattern,pname)) {
+                        errors.add(buildValidationMessage(at + "." + pname, "pattern " + pattern));
                     }
                 }
             }


Test patch:
diff --git a/src/test/java/com/networknt/schema/Issue375Test.java b/src/test/java/com/networknt/schema/Issue375Test.java
new file mode 100644
index 0000000..ebdc5f7
--- /dev/null
+++ b/src/test/java/com/networknt/schema/Issue375Test.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2020 Network New Technologies Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.networknt.schema;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.networknt.schema.SpecVersion.VersionFlag;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+public class Issue375Test {
+    protected JsonSchema getJsonSchemaFromStreamContent(InputStream schemaContent) {
+        JsonSchemaFactory factory = JsonSchemaFactory.getInstance(VersionFlag.V201909);
+        return factory.getSchema(schemaContent);
+    }
+
+    protected JsonNode getJsonNodeFromStreamContent(InputStream content) throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        return mapper.readTree(content);
+    }
+
+    @Test
+    public void shouldFailAndShowValidationValuesWithError() throws Exception {
+        String schemaPath = "/draft2019-09/issue375.json";
+        String dataPath = "/data/issue375.json";
+        InputStream schemaInputStream = getClass().getResourceAsStream(schemaPath);
+        JsonSchema schema = getJsonSchemaFromStreamContent(schemaInputStream);
+        InputStream dataInputStream = getClass().getResourceAsStream(dataPath);
+        JsonNode node = getJsonNodeFromStreamContent(dataInputStream);
+        Set<ValidationMessage> errors = schema.validate(node);
+        List<String> errorMessages = new ArrayList<String>();
+        for (ValidationMessage error: errors) {
+            errorMessages.add(error.getMessage());
+        }
+
+        List<String> expectedMessages = Arrays.asList(
+            "Property name $.fields.longName123 is not valid for validation: maxLength 5",
+            "Property name $.fields.longName123 is not valid for validation: pattern ^[a-zA-Z]+$",
+            "Property name $.fields.a is not valid for validation: minLength 3");
+        MatcherAssert.assertThat(errorMessages, Matchers.containsInAnyOrder(expectedMessages.toArray()));
+    }
+}
diff --git a/src/test/resources/data/issue375.json b/src/test/resources/data/issue375.json
new file mode 100644
index 0000000..b940e62
--- /dev/null
+++ b/src/test/resources/data/issue375.json
@@ -0,0 +1,10 @@
+{
+  "fields": {
+    "longName123": {
+      "action": "doStuff"
+    },
+    "a": {
+      "action": "doMagic"
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/test/resources/draft2019-09/issue375.json b/src/test/resources/draft2019-09/issue375.json
new file mode 100644
index 0000000..fe6206f
--- /dev/null
+++ b/src/test/resources/draft2019-09/issue375.json
@@ -0,0 +1,28 @@
+{
+  "$schema": "https://json-schema.org/draft/2019-09/schema#",
+  "title": "test",
+  "description": "asdasdint",
+  "type": "object",
+  "properties": {
+    "fields": {
+      "type": "object",
+      "propertyNames": {
+        "pattern": "^[a-zA-Z]+$",
+        "maxLength": 5,
+        "minLength": 3
+      },
+      "additionalProperties": {
+        "type": "object",
+        "properties": {
+          "action": {
+            "type": "string"
+          }
+        },
+        "additionalProperties": false,
+        "required": [
+          "action"
+        ]
+      }
+    }
+  }
+}
\ No newline at end of file