Skip to content

Commit 5970f14

Browse files
fixes #575 (#578)
* upgrade itu to 1.7.0 (#575) * Add unit tests to ensure that valid time zone offsets are not marked as being invalid (#575)
1 parent ebf4a59 commit 5970f14

File tree

3 files changed

+142
-1
lines changed

3 files changed

+142
-1
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
<version.mockito>2.7.21</version.mockito>
7272
<version.hamcrest>2.2</version.hamcrest>
7373
<version.undertow>2.2.14.Final</version.undertow>
74-
<version.itu>1.5.1</version.itu>
74+
<version.itu>1.7.0</version.itu>
7575
</properties>
7676
<dependencies>
7777
<dependency>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package com.networknt.schema;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import org.junit.jupiter.api.Assertions;
6+
import org.junit.jupiter.api.BeforeAll;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.Arguments;
9+
import org.junit.jupiter.params.provider.MethodSource;
10+
11+
import java.io.InputStream;
12+
import java.util.Set;
13+
import java.util.stream.Stream;
14+
15+
/**
16+
* This project uses a dependency (com.ethlo.time:itu) to validate time representations. Version 1.51 of this library
17+
* has a problem dealing with certain time zones having a negative offset; for example "-2:30" (Newfoundland time, NDT).
18+
* Moving to version 1.7.0 of this library resolves the issue.
19+
*
20+
* This test class confirms that valid negative offsets do not result in a JSON validation error if the ITU library is
21+
* updated to version 1.7.0 or later.
22+
*/
23+
public class Issue575Test {
24+
private static JsonSchema schema;
25+
26+
@BeforeAll
27+
static void init() {
28+
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909);
29+
String schemaPath = "/schema/issue575-2019-09.json";
30+
InputStream schemaInputStream = Issue575Test.class.getResourceAsStream(schemaPath);
31+
schema = factory.getSchema(schemaInputStream);
32+
}
33+
34+
public static Stream<Arguments> validTimeZoneOffsets() {
35+
String json1 = "{\"testDateTime\":\"2022-05-18T08:27:53-05:00\"}"; // America/New_York
36+
String json2 = "{\"testDateTime\":\"2022-05-18T08:27:53-04:00\"}"; // America/New_York (DST)
37+
String json3 = "{\"testDateTime\":\"2022-05-18T08:27:53-03:30\"}"; // America/St_Johns
38+
String json4 = "{\"testDateTime\":\"2022-05-18T08:27:53-02:30\"}"; // America/St_Johns (DST)
39+
String json5 = "{\"testDateTime\":\"2022-05-18T08:27:53+02:00\"}"; // Africa/Cairo
40+
String json6 = "{\"testDateTime\":\"2022-05-18T08:27:53+03:30\"}"; // Asia/Tehran
41+
String json7 = "{\"testDateTime\":\"2022-05-18T08:27:53+04:30\"}"; // Asia/Tehran (DST)
42+
String json8 = "{\"testDateTime\":\"2022-05-18T08:27:53+04:00\"}"; // Asia/Dubai
43+
String json9 = "{\"testDateTime\":\"2022-05-18T08:27:53+05:00\"}"; // Indian/Maldives
44+
String json10 = "{\"testDateTime\":\"2022-05-18T08:27:53+05:30\"}"; // Asia/Kolkata
45+
String json11 = "{\"testDateTime\":\"2022-05-18T08:27:53+10:00\"}"; // Australia/Sydney
46+
String json12 = "{\"testDateTime\":\"2022-05-18T08:27:53+11:00\"}"; // Australia/Sydney (DST)
47+
String json13 = "{\"testDateTime\":\"2022-05-18T08:27:53+14:00\"}"; // Pacific/Kiritimati
48+
String json14 = "{\"testDateTime\":\"2022-05-18T18:45:32.123-05:00\"}"; // America/New_York
49+
String json15 = "{\"testDateTime\":\"2022-05-18T18:45:32.123456-05:00\"}"; // America/New_York
50+
String json16 = "{\"testDateTime\":\"2022-05-18T08:27:53Z\"}"; // UTC
51+
String json17 = "{\"testDateTime\":\"2022-05-18T08:27:53+00:00\"}"; // UTC
52+
53+
return Stream.of(
54+
Arguments.of(json1),
55+
Arguments.of(json2),
56+
Arguments.of(json3),
57+
Arguments.of(json4),
58+
Arguments.of(json5),
59+
Arguments.of(json6),
60+
Arguments.of(json7),
61+
Arguments.of(json8),
62+
Arguments.of(json9),
63+
Arguments.of(json10),
64+
Arguments.of(json11),
65+
Arguments.of(json12),
66+
Arguments.of(json13),
67+
Arguments.of(json14),
68+
Arguments.of(json15),
69+
Arguments.of(json16),
70+
Arguments.of(json17)
71+
);
72+
}
73+
74+
/**
75+
* Confirms that valid time zone offsets do not result in a JSON validation error.
76+
*
77+
* @param jsonObject a sample JSON payload to test
78+
*/
79+
@ParameterizedTest
80+
@MethodSource("validTimeZoneOffsets")
81+
void testValidTimeZoneOffsets(String jsonObject) throws JsonProcessingException {
82+
Set<ValidationMessage> errors = schema.validate(new ObjectMapper().readTree(jsonObject));
83+
Assertions.assertTrue(errors.isEmpty());
84+
}
85+
86+
public static Stream<Arguments> invalidTimeRepresentations() {
87+
// Invalid JSON payload: 30 days in April
88+
String json1 = "{\"testDateTime\":\"2022-04-31T08:27:53+05:00\"}";
89+
// Invalid JSON payload: Invalid date/time separator
90+
String json2 = "{\"testDateTime\":\"2022-05-18X08:27:53+05:00\"}";
91+
// Invalid JSON payload: Time zone details are missing
92+
String json3 = "{\"testDateTime\":\"2022-05-18T08:27:53\"}";
93+
// Invalid JSON payload: seconds missing from time
94+
String json4 = "{\"testDateTime\":\"2022-05-18T11:23Z\"}";
95+
// Invalid JSON payload: Text instead of date-time value
96+
String json5 = "{\"testDateTime\":\"Orlando\"}";
97+
// Invalid JSON payload: A time zone offset of +23:00 is not valid
98+
String json6 = "{\"testDateTime\":\"2022-05-18T08:27:53+23:00\"}";
99+
// Invalid JSON payload: A time zone offset of -23:00 is not valid
100+
String json7 = "{\"testDateTime\":\"2022-05-18T08:27:53-23:00\"}";
101+
// Invalid JSON payload: com.ethlo.time:itu does not allow offset -00:00 (Valid per RFC3339 section 4.3. but prohibited in ISO-8601)
102+
String json8 = "{\"testDateTime\":\"2022-05-18T08:27:53-00:00\"}";
103+
104+
return Stream.of(
105+
Arguments.of(json1),
106+
Arguments.of(json2),
107+
Arguments.of(json3),
108+
Arguments.of(json4),
109+
Arguments.of(json5),
110+
Arguments.of(json6),
111+
Arguments.of(json7),
112+
Arguments.of(json8)
113+
);
114+
}
115+
116+
/**
117+
* Confirms that invalid time representations result in one or more a JSON validation errors.
118+
*
119+
* @param jsonObject a sample JSON payload to test
120+
*/
121+
@ParameterizedTest
122+
@MethodSource("invalidTimeRepresentations")
123+
void testInvalidTimeRepresentations(String jsonObject) throws JsonProcessingException {
124+
Set<ValidationMessage> errors = schema.validate(new ObjectMapper().readTree(jsonObject));
125+
Assertions.assertFalse(errors.isEmpty());
126+
}
127+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"$schema" : "https://json-schema.org/draft/2019-09/schema#",
3+
"title": "Test Time Zone Schema (for testing time zones with negative offsets)",
4+
"type": "object",
5+
"properties": {
6+
"testDateTime": {
7+
"description": "A date-time value.",
8+
"type" : "string",
9+
"minLength" : 1,
10+
"maxLength" : 32,
11+
"format" : "date-time"
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)