Skip to content

Commit ad795de

Browse files
authored
Support config param to disable custom messages from schema (#801)
* Support config param to disable custom messages from schema * Null safety check
1 parent bf1bf01 commit ad795de

File tree

6 files changed

+169
-6
lines changed

6 files changed

+169
-6
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@ private Map<String, JsonValidator> read(JsonNode schemaNode) {
302302
};
303303

304304
private String getCustomMessage(JsonNode schemaNode, String pname) {
305+
if (this.validationContext.getConfig() != null && !this.validationContext.getConfig().isCustomMessageSupported()) {
306+
return null;
307+
}
305308
final JsonSchema parentSchema = getParentSchema();
306309
final JsonNode message = getMessageNode(schemaNode, parentSchema, pname);
307310
if (message != null && message.get(pname) != null) {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ public class SchemaValidatorsConfig {
5959
*/
6060
private boolean losslessNarrowing;
6161

62+
/**
63+
* When set to true, "messages" provided in schema are used for forming validation errors
64+
* else default messages are used
65+
*/
66+
private boolean isCustomMessageSupported = true;
67+
6268
/**
6369
* When set to true, support for discriminators is enabled for validations of
6470
* oneOf, anyOf and allOf as described on <a href=
@@ -225,6 +231,14 @@ public void setJavaSemantics(boolean javaSemantics) {
225231
this.javaSemantics = javaSemantics;
226232
}
227233

234+
public boolean isCustomMessageSupported() {
235+
return isCustomMessageSupported;
236+
}
237+
238+
public void setCustomMessageSupported(boolean customMessageSupported) {
239+
this.isCustomMessageSupported = customMessageSupported;
240+
}
241+
228242
public void addKeywordWalkListener(JsonSchemaWalkListener keywordWalkListener) {
229243
if (keywordWalkListenersMap.get(ALL_KEYWORD_WALK_LISTENER_KEY) == null) {
230244
List<JsonSchemaWalkListener> keywordWalkListeners = new ArrayList<JsonSchemaWalkListener>();

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,8 @@
1919
import com.fasterxml.jackson.core.type.TypeReference;
2020
import com.fasterxml.jackson.databind.ObjectMapper;
2121
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
22-
23-
import static com.networknt.schema.SpecVersionDetector.detectOptionalVersion;
24-
2522
import com.networknt.schema.SpecVersion.VersionFlag;
2623
import com.networknt.schema.uri.URITranslator;
27-
2824
import org.junit.jupiter.api.AssertionFailureBuilder;
2925
import org.junit.jupiter.api.DynamicNode;
3026
import org.opentest4j.AssertionFailedError;
@@ -48,6 +44,7 @@
4844
import java.util.stream.Stream;
4945
import java.util.stream.StreamSupport;
5046

47+
import static com.networknt.schema.SpecVersionDetector.detectOptionalVersion;
5148
import static org.junit.jupiter.api.DynamicContainer.dynamicContainer;
5249
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
5350

@@ -126,6 +123,10 @@ private DynamicNode buildTest(JsonSchemaFactory validatorFactory, TestSpec testS
126123
config.setTypeLoose(typeLoose);
127124
config.setEcma262Validator(TestSpec.RegexKind.JDK != testSpec.getRegex());
128125
testSpec.getStrictness().forEach(config::setStrict);
126+
if (testSpec.getConfig() != null && testSpec.getConfig().containsKey("isCustomMessageSupported")) {
127+
config.setCustomMessageSupported((Boolean) testSpec.getConfig().get("isCustomMessageSupported"));
128+
}
129+
129130
URI testCaseFileUri = URI.create("classpath:" + toForwardSlashPath(testSpec.getTestCase().getSpecification()));
130131
JsonSchema schema = validatorFactory.getSchema(testCaseFileUri, testSpec.getTestCase().getSchema(), config);
131132

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,15 @@
1212
public class CustomMessageTest extends AbstractJsonSchemaTestSuite {
1313

1414
@TestFactory
15-
@DisplayName("Draft 2019-09")
16-
Stream<DynamicNode> draft201909() {
15+
@DisplayName("Draft 2019-09 - Custom Messages Enabled")
16+
Stream<DynamicNode> draft201909__customMessagesEnabled() {
1717
return createTests(VersionFlag.V201909, "src/test/resources/schema/customMessageTests/custom-message-tests.json");
1818
}
1919

20+
@TestFactory
21+
@DisplayName("Draft 2019-09 - Custom Messages Disabled")
22+
Stream<DynamicNode> draft201909__customMessagesDisabled() {
23+
return createTests(VersionFlag.V201909, "src/test/resources/schema/customMessageTests/custom-message-disabled-tests.json");
24+
}
25+
2026
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public class TestSpec {
2626
*/
2727
private final String comment;
2828

29+
/**
30+
* Config information to be provided for {@link SchemaValidatorsConfig} with which schema can be validated
31+
*/
32+
private final Map<String, Object> config;
33+
2934
/**
3035
* The instance which should be validated against the schema in "schema".
3136
* (Required)
@@ -107,6 +112,7 @@ public class TestSpec {
107112
public TestSpec(
108113
@JsonProperty("description") String description,
109114
@JsonProperty("comment") String comment,
115+
@JsonProperty("config") Map<String, Object> config,
110116
@JsonProperty("data") JsonNode data,
111117
@JsonProperty("valid") boolean valid,
112118
@JsonProperty("strictness") Map<String, Boolean> strictness,
@@ -117,6 +123,7 @@ public TestSpec(
117123
) {
118124
this.description = description;
119125
this.comment = comment;
126+
this.config = config;
120127
this.data = data;
121128
this.valid = valid;
122129
this.validationMessages = validationMessages;
@@ -159,6 +166,14 @@ public String getComment() {
159166
return comment;
160167
}
161168

169+
170+
/**
171+
* Config information to be provided for {@link SchemaValidatorsConfig} with which schema can be validated
172+
*/
173+
public Map<String, Object> getConfig() {
174+
return config;
175+
}
176+
162177
/**
163178
* The instance which should be validated against the schema in "schema".
164179
* (Required)
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
[
2+
{
3+
"description": "Tests that validate custom message functionality doesn't work for keywords at any level, if validator config has isCustomMessageSupported set as false",
4+
"schema": {
5+
"type": "object",
6+
"properties": {
7+
"foo": {
8+
"type": "array",
9+
"maxItems": 3,
10+
"items" : {
11+
"type" : "number"
12+
},
13+
"message" : {
14+
"maxItems" : "Custom Message: Maximum 3 numbers can be given in 'foo'",
15+
"type" : "Custom Message: Only numbers are supported in 'foo'"
16+
}
17+
},
18+
"bar": {
19+
"type": "string"
20+
}
21+
},
22+
"message": {
23+
"type" : "Custom Message: Invalid type provided"
24+
}
25+
},
26+
"tests": [
27+
{
28+
"description": "Basic Success Test 1",
29+
"config": {
30+
"isCustomMessageSupported": false
31+
},
32+
"data": {
33+
"foo": [],
34+
"bar": "Bar 1"
35+
},
36+
"valid": true
37+
},
38+
{
39+
"description": "Basic Success Test 2",
40+
"config": {
41+
"isCustomMessageSupported": false
42+
},
43+
"data": {
44+
"foo": [1, 2],
45+
"bar": "Bar 1"
46+
},
47+
"valid": true
48+
},
49+
{
50+
"description": "Custom error message for keyword failing at top level - type keyword",
51+
"config": {
52+
"isCustomMessageSupported": false
53+
},
54+
"data": {
55+
"foo": [1, 2, 3],
56+
"bar": 123
57+
},
58+
"valid": false,
59+
"validationMessages": [
60+
"$.bar: integer found, string expected"
61+
]
62+
},
63+
{
64+
"description": "Custom error message for keyword failing at nested property level - type keyword",
65+
"config": {
66+
"isCustomMessageSupported": false
67+
},
68+
"data": {
69+
"foo": [1, 2, "text"],
70+
"bar": "Bar 1"
71+
},
72+
"valid": false,
73+
"validationMessages": [
74+
"$.foo[2]: string found, number expected"
75+
]
76+
},
77+
{
78+
"description": "Custom error message for keyword failing at nested property level - maxItems keyword",
79+
"config": {
80+
"isCustomMessageSupported": false
81+
},
82+
"data": {
83+
"foo": [1, 2, 3, 4],
84+
"bar": "Bar 1"
85+
},
86+
"valid": false,
87+
"validationMessages": [
88+
"$.foo: there must be a maximum of 3 items in the array"
89+
]
90+
},
91+
{
92+
"description": "Custom error message for keyword failing at both top level and nested property level - type keyword",
93+
"config": {
94+
"isCustomMessageSupported": false
95+
},
96+
"data": {
97+
"foo": [1, 2, "text"],
98+
"bar": 123
99+
},
100+
"valid": false,
101+
"validationMessages": [
102+
"$.foo[2]: string found, number expected",
103+
"$.bar: integer found, string expected"
104+
]
105+
},
106+
{
107+
"description": "Custom error message for keyword failing at both top level and nested property level - type keyword",
108+
"config": {
109+
"isCustomMessageSupported": false
110+
},
111+
"data": {
112+
"foo": [1, 2, "text", 3],
113+
"bar": 123
114+
},
115+
"valid": false,
116+
"validationMessages": [
117+
"$.foo: there must be a maximum of 3 items in the array",
118+
"$.foo[2]: string found, number expected",
119+
"$.bar: integer found, string expected"
120+
]
121+
}
122+
]
123+
}
124+
]

0 commit comments

Comments
 (0)