Skip to content

Commit 5fcbb77

Browse files
committed
Fix minimum maximum validators with type array
1 parent 98b842d commit 5fcbb77

File tree

9 files changed

+105
-7
lines changed

9 files changed

+105
-7
lines changed

src/main/java/com/networknt/schema/keyword/BaseKeywordValidator.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.networknt.schema.keyword;
1818

1919
import tools.jackson.databind.JsonNode;
20+
2021
import com.networknt.schema.ErrorMessages;
2122
import com.networknt.schema.Schema;
2223
import com.networknt.schema.MessageSourceError;
@@ -83,12 +84,23 @@ public Schema getParentSchema() {
8384
return this.parentSchema;
8485
}
8586

86-
protected String getNodeFieldType() {
87+
protected boolean hasType(String type) {
8788
JsonNode typeField = this.getParentSchema().getSchemaNode().get("type");
8889
if (typeField != null) {
89-
return typeField.asString();
90+
switch (typeField.getNodeType()) {
91+
case STRING:
92+
return type.equals(typeField.stringValue());
93+
case ARRAY:
94+
for (JsonNode item : typeField.values()) {
95+
if (item.isString() && type.equals(item.stringValue())) {
96+
return true;
97+
}
98+
}
99+
default:
100+
return false;
101+
}
90102
}
91-
return null;
103+
return false;
92104
}
93105

94106
protected void preloadSchemas(final Collection<Schema> schemas) {

src/main/java/com/networknt/schema/keyword/ExclusiveMaximumValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public ExclusiveMaximumValidator(SchemaLocation schemaLocation, final JsonNode s
4141
throw new SchemaException("exclusiveMaximum value is not a number");
4242
}
4343
final String maximumText = schemaNode.asString();
44-
if ((schemaNode.isLong() || schemaNode.isInt()) && (JsonType.INTEGER.toString().equals(getNodeFieldType()))) {
44+
if ((schemaNode.isLong() || schemaNode.isInt()) && hasType(JsonType.INTEGER.toString())) {
4545
// "integer", and within long range
4646
final long lm = schemaNode.asLong();
4747
typedMaximum = new ThresholdMixin() {

src/main/java/com/networknt/schema/keyword/ExclusiveMinimumValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public ExclusiveMinimumValidator(SchemaLocation schemaLocation, final JsonNode s
4545
throw new SchemaException("exclusiveMinimum value is not a number");
4646
}
4747
final String minimumText = schemaNode.asString();
48-
if ((schemaNode.isLong() || schemaNode.isInt()) && JsonType.INTEGER.toString().equals(getNodeFieldType())) {
48+
if ((schemaNode.isLong() || schemaNode.isInt()) && hasType(JsonType.INTEGER.toString())) {
4949
// "integer", and within long range
5050
final long lmin = schemaNode.asLong();
5151
typedMinimum = new ThresholdMixin() {

src/main/java/com/networknt/schema/keyword/MaximumValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public MaximumValidator(SchemaLocation schemaLocation, final JsonNode schemaNode
5454
}
5555

5656
final String maximumText = schemaNode.asString();
57-
if ((schemaNode.isLong() || schemaNode.isInt()) && (JsonType.INTEGER.toString().equals(getNodeFieldType()))) {
57+
if ((schemaNode.isLong() || schemaNode.isInt()) && hasType(JsonType.INTEGER.toString())) {
5858
// "integer", and within long range
5959
final long lm = schemaNode.asLong();
6060
this.typedMaximum = new ThresholdMixin() {

src/main/java/com/networknt/schema/keyword/MinimumValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public MinimumValidator(SchemaLocation schemaLocation, final JsonNode schemaNode
5858
}
5959

6060
final String minimumText = schemaNode.asString();
61-
if ((schemaNode.isLong() || schemaNode.isInt()) && JsonType.INTEGER.toString().equals(getNodeFieldType())) {
61+
if ((schemaNode.isLong() || schemaNode.isInt()) && hasType(JsonType.INTEGER.toString())) {
6262
// "integer", and within long range
6363
final long lmin = schemaNode.asLong();
6464
this.typedMinimum = new ThresholdMixin() {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.networknt.schema;
17+
18+
import static org.junit.jupiter.api.Assertions.assertEquals;
19+
20+
import org.junit.jupiter.api.Test;
21+
22+
import com.networknt.schema.dialect.Dialects;
23+
24+
/**
25+
* Test ExclusiveMaximumValidator validator.
26+
*/
27+
class ExclusiveMaximumValidatorTest {
28+
@Test
29+
void exclusiveMaximum() {
30+
final String schemaString = """
31+
{
32+
"$schema": "http://json-schema.org/draft-07/schema#",
33+
"type": ["null", "integer"],
34+
"exclusiveMaximum": 10
35+
}
36+
""";
37+
final SchemaRegistry schemaRegistry = SchemaRegistry.withDialect(Dialects.getDraft7());
38+
assertEquals(1, schemaRegistry.getSchema(schemaString).validate("10", InputFormat.JSON).size());
39+
}
40+
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,17 @@ void draftV7ShouldNotAllowExclusiveMinimumBoolean() {
9292
SchemaRegistry factory = SchemaRegistry.withDialect(dialect);
9393
assertThrows(SchemaException.class, () -> factory.getSchema(schemaData));
9494
}
95+
96+
@Test
97+
void exclusiveMinimum() {
98+
final String schemaString = """
99+
{
100+
"$schema": "http://json-schema.org/draft-07/schema#",
101+
"type": ["null", "integer"],
102+
"exclusiveMinimum": 10
103+
}
104+
""";
105+
final SchemaRegistry schemaRegistry = SchemaRegistry.withDialect(Dialects.getDraft7());
106+
assertEquals(1, schemaRegistry.getSchema(schemaString).validate("10", InputFormat.JSON).size());
107+
}
95108
}

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@
2121
import tools.jackson.databind.ObjectMapper;
2222
import org.junit.jupiter.api.Test;
2323

24+
import com.networknt.schema.dialect.Dialects;
25+
2426
import java.io.IOException;
2527
import java.math.BigDecimal;
2628
import java.util.List;
2729

2830
import static java.lang.String.format;
31+
import static org.junit.jupiter.api.Assertions.assertEquals;
2932
import static org.junit.jupiter.api.Assertions.assertFalse;
3033
import static org.junit.jupiter.api.Assertions.assertTrue;
3134

@@ -326,6 +329,19 @@ private static void expectSomeMessages(String[][] values, String schemaTemplate,
326329
assertFalse(messages.isEmpty(), format(MaximumValidatorTest.NEGATIVE_TEST_CASE_TEMPLATE, value, maximum));
327330
}
328331
}
332+
333+
@Test
334+
void maximumWithArrayType() {
335+
final String schemaString = """
336+
{
337+
"$schema": "http://json-schema.org/draft-07/schema#",
338+
"type": ["null", "integer"],
339+
"maximum": 10
340+
}
341+
""";
342+
final SchemaRegistry schemaRegistry = SchemaRegistry.withDialect(Dialects.getDraft7());
343+
assertEquals(1, schemaRegistry.getSchema(schemaString).validate("11", InputFormat.JSON).size());
344+
}
329345
}
330346

331347

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static com.networknt.schema.MaximumValidatorTest.augmentWithQuotes;
2020
import static java.lang.String.format;
21+
import static org.junit.jupiter.api.Assertions.assertEquals;
2122
import static org.junit.jupiter.api.Assertions.assertFalse;
2223
import static org.junit.jupiter.api.Assertions.assertTrue;
2324

@@ -28,6 +29,8 @@
2829
import org.junit.jupiter.api.BeforeEach;
2930
import org.junit.jupiter.api.Test;
3031

32+
import com.networknt.schema.dialect.Dialects;
33+
3134
import tools.jackson.databind.DeserializationFeature;
3235
import tools.jackson.databind.JsonNode;
3336
import tools.jackson.databind.ObjectMapper;
@@ -298,6 +301,20 @@ private void expectNoMessages(String[][] values, String integer, ObjectMapper ma
298301
assertTrue(messages.isEmpty(), format(MinimumValidatorTest.POSITIVT_MESSAGE_TEMPLATE, value, minimum));
299302
}
300303
}
304+
305+
@Test
306+
void minimumWithArrayType() {
307+
final String schemaString = """
308+
{
309+
"$schema": "http://json-schema.org/draft-07/schema#",
310+
"type": ["null", "integer"],
311+
"minimum": 10
312+
}
313+
""";
314+
final SchemaRegistry schemaRegistry = SchemaRegistry.withDialect(Dialects.getDraft7());
315+
assertEquals(1, schemaRegistry.getSchema(schemaString).validate("9", InputFormat.JSON).size());
316+
}
317+
301318
}
302319

303320

0 commit comments

Comments
 (0)