Added tests for validations
This commit is contained in:
parent
6eb8b66560
commit
de610f7f3e
@ -6,13 +6,19 @@ import java.net.MalformedURLException;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.time.chrono.IsoChronology;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeFormatterBuilder;
|
||||||
import java.time.format.DateTimeParseException;
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.time.format.ResolverStyle;
|
||||||
import java.util.IllformedLocaleException;
|
import java.util.IllformedLocaleException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.oneedtech.inspect.core.probe.json.JsonPathEvaluator;
|
import org.oneedtech.inspect.core.probe.json.JsonPathEvaluator;
|
||||||
|
import org.oneedtech.inspect.util.json.ObjectMapperCache;
|
||||||
|
import org.oneedtech.inspect.util.json.ObjectMapperCache.Config;
|
||||||
|
|
||||||
import com.apicatalog.jsonld.JsonLd;
|
import com.apicatalog.jsonld.JsonLd;
|
||||||
import com.apicatalog.jsonld.JsonLdError;
|
import com.apicatalog.jsonld.JsonLdError;
|
||||||
@ -20,11 +26,9 @@ import com.apicatalog.jsonld.document.JsonDocument;
|
|||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.ObjectReader;
|
import com.fasterxml.jackson.databind.ObjectReader;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.google.common.io.Resources;
|
import com.google.common.io.Resources;
|
||||||
|
|
||||||
import jakarta.json.JsonArray;
|
|
||||||
import jakarta.json.JsonObject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validator for ValueType. Translated into java from PrimitiveValueValidator in validation.py
|
* Validator for ValueType. Translated into java from PrimitiveValueValidator in validation.py
|
||||||
*/
|
*/
|
||||||
@ -39,13 +43,30 @@ public class PrimitiveValueValidator {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjectMapper mapper = ObjectMapperCache.get(Config.DEFAULT); // TODO: get from RunContext
|
||||||
|
|
||||||
|
try {
|
||||||
|
JsonNode node = mapper.readTree(Resources.getResource("contexts/ob-v2p0.json"));
|
||||||
|
ObjectReader readerForUpdating = mapper.readerForUpdating(node);
|
||||||
|
JsonNode merged = readerForUpdating.readValue("{\"" + value.asText() + "\" : \"TEST\"}");
|
||||||
|
JsonDocument jsonDocument = JsonDocument.of(new StringReader(merged.toString()));
|
||||||
|
|
||||||
|
JsonNode expanded = mapper.readTree(JsonLd.expand(jsonDocument).get().toString());
|
||||||
|
if (expanded.isArray() && ((ArrayNode) expanded).size() > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (NullPointerException | IOException | JsonLdError e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean validateDataUri(JsonNode value) {
|
public static boolean validateDataUri(JsonNode value) {
|
||||||
try {
|
try {
|
||||||
URI uri = new URI(value.asText());
|
URI uri = new URI(value.asText());
|
||||||
return "data".equalsIgnoreCase(uri.getScheme());
|
return "data".equalsIgnoreCase(uri.getScheme()) && uri.getSchemeSpecificPart().contains(",");
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -55,14 +76,29 @@ public class PrimitiveValueValidator {
|
|||||||
return validateUrl(value) || validateDataUri(value);
|
return validateUrl(value) || validateDataUri(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DateTimeFormatter ISO_OFFSET_TIME_JOINED = new DateTimeFormatterBuilder()
|
||||||
|
.parseCaseInsensitive()
|
||||||
|
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
|
||||||
|
.parseLenient()
|
||||||
|
.appendOffset("+Hmmss", "Z")
|
||||||
|
.parseStrict()
|
||||||
|
.toFormatter();
|
||||||
|
|
||||||
public static boolean validateDatetime(JsonNode value) {
|
public static boolean validateDatetime(JsonNode value) {
|
||||||
|
boolean valid = List.of(ISO_OFFSET_TIME_JOINED,
|
||||||
|
DateTimeFormatter.ISO_OFFSET_DATE_TIME,
|
||||||
|
DateTimeFormatter.ISO_INSTANT)
|
||||||
|
.stream().anyMatch(formatter -> {
|
||||||
try {
|
try {
|
||||||
DateTimeFormatter.ISO_INSTANT.parse(value.asText());
|
formatter.parse(value.asText());
|
||||||
return true;
|
return true;
|
||||||
} catch (DateTimeParseException | NullPointerException ignored) {
|
} catch (DateTimeParseException | NullPointerException ignored) {
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean validateEmail(JsonNode value) {
|
public static boolean validateEmail(JsonNode value) {
|
||||||
return value.asText().matches("(^[^@\\s]+@[^@\\s]+$)");
|
return value.asText().matches("(^[^@\\s]+@[^@\\s]+$)");
|
||||||
@ -88,7 +124,10 @@ public class PrimitiveValueValidator {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean validateIri(JsonNode value) {
|
public static boolean validateIri(JsonNode value) {
|
||||||
return validateUrl(value) || value.asText().matches("^_:") || value.asText().matches("^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$");
|
return
|
||||||
|
Pattern.compile("^_:.+", Pattern.CASE_INSENSITIVE).matcher(value.asText()).matches()
|
||||||
|
|| Pattern.compile("^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", Pattern.CASE_INSENSITIVE).matcher(value.asText()).matches()
|
||||||
|
|| validateUrl(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean validateLanguage(JsonNode value) {
|
public static boolean validateLanguage(JsonNode value) {
|
||||||
@ -109,7 +148,7 @@ public class PrimitiveValueValidator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper(); // TODO: get from RunContext
|
ObjectMapper mapper = ObjectMapperCache.get(Config.DEFAULT); // TODO: get from RunContext
|
||||||
JsonPathEvaluator jsonPath = new JsonPathEvaluator(mapper); // TODO: get from RunContext
|
JsonPathEvaluator jsonPath = new JsonPathEvaluator(mapper); // TODO: get from RunContext
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -0,0 +1,162 @@
|
|||||||
|
package org.oneedtech.inspect.vc.util;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.oneedtech.inspect.util.json.ObjectMapperCache.Config.DEFAULT;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.oneedtech.inspect.util.json.ObjectMapperCache;
|
||||||
|
import org.oneedtech.inspect.vc.Assertion.ValueType;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test case for PrimitiveValueValidator.
|
||||||
|
* Maps to "PropertyValidationTests" in python implementation
|
||||||
|
*/
|
||||||
|
public class PrimitiveValueValidatorTests {
|
||||||
|
private static ObjectMapper mapper;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void setup() {
|
||||||
|
mapper = ObjectMapperCache.get(DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDataUri() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<String> goodValues = List.of("data:image/gif;base64,R0lGODlhyAAiALM...DfD0QAADs=",
|
||||||
|
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",
|
||||||
|
"data:text/plain;charset=UTF-8;page=21,the%20data:1234,5678",
|
||||||
|
"data:text/vnd-example+xyz;foo=bar;base64,R0lGODdh",
|
||||||
|
"data:,actually%20a%20valid%20data%20URI",
|
||||||
|
"data:,");
|
||||||
|
List<String> badValues = List.of("data:image/gif",
|
||||||
|
"http://someexample.org",
|
||||||
|
"data:bad:path");
|
||||||
|
assertFunction(ValueType.DATA_URI, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDataUriOrUrl() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<String> goodValues = List.of("data:image/gif;base64,R0lGODlhyAAiALM...DfD0QAADs=",
|
||||||
|
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",
|
||||||
|
"data:text/plain;charset=UTF-8;page=21,the%20data:1234,5678",
|
||||||
|
"data:text/vnd-example+xyz;foo=bar;base64,R0lGODdh",
|
||||||
|
"http://www.example.com:8080/", "http://www.example.com:8080/foo/bar",
|
||||||
|
"http://www.example.com/foo%20bar", "http://www.example.com/foo/bar?a=b&c=d",
|
||||||
|
"http://www.example.com/foO/BaR", "HTTPS://www.EXAMPLE.cOm/",
|
||||||
|
"http://142.42.1.1:8080/", "http://142.42.1.1/",
|
||||||
|
"http://foo.com/blah_(wikipedia)#cite-1", "http://a.b-c.de",
|
||||||
|
"http://userid:password@example.com/", "http://-.~:%40:80%2f:password@example.com",
|
||||||
|
"http://code.google.com/events/#&product=browser");
|
||||||
|
List<String> badValues = List.of("///", "///f", "//",
|
||||||
|
"rdar://12345", "h://test", ":// should fail", "", "a",
|
||||||
|
"urn:uuid:129487129874982374", "urn:uuid:9d278beb-36cf-4bc8-888d-674ff9843d72");
|
||||||
|
assertFunction(ValueType.DATA_URI_OR_URL, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUrl() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<String> goodValues = List.of("http://www.example.com:8080/", "http://www.example.com:8080/foo/bar",
|
||||||
|
"http://www.example.com/foo%20bar", "http://www.example.com/foo/bar?a=b&c=d",
|
||||||
|
"http://www.example.com/foO/BaR", "HTTPS://www.EXAMPLE.cOm/",
|
||||||
|
"http://142.42.1.1:8080/", "http://142.42.1.1/", "http://localhost:3000/123",
|
||||||
|
"http://foo.com/blah_(wikipedia)#cite-1", "http://a.b-c.de",
|
||||||
|
"http://userid:password@example.com/", "http://-.~:%40:80%2f:password@example.com",
|
||||||
|
"http://code.google.com/events/#&product=browser");
|
||||||
|
List<String> badValues = List.of("data:image/gif;base64,R0lGODlhyAAiALM...DfD0QAADs=", "///", "///f", "//",
|
||||||
|
"rdar://12345", "h://test", ":// should fail", "", "a",
|
||||||
|
"urn:uuid:129487129874982374", "urn:uuid:9d278beb-36cf-4bc8-888d-674ff9843d72");
|
||||||
|
assertFunction(ValueType.URL, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIri() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<String> goodValues = List.of("http://www.example.com:8080/", "_:b0", "_:b12", "_:b107", "_:b100000001232",
|
||||||
|
"urn:uuid:9d278beb-36cf-4bc8-888d-674ff9843d72",
|
||||||
|
"urn:uuid:9D278beb-36cf-4bc8-888d-674ff9843d72");
|
||||||
|
List<String> badValues = List.of("data:image/gif;base64,R0lGODlhyAAiALM...DfD0QAADs=", "urn:uuid", "urn:uuid:123",
|
||||||
|
"", "urn:uuid:", "urn:uuid:zz278beb-36cf-4bc8-888d-674ff9843d72");
|
||||||
|
assertFunction(ValueType.IRI, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUrlAuthority() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<String> goodValues = List.of("google.com", "nerds.example.com");
|
||||||
|
List<String> badValues = List.of("666", "http://google.com/", "https://www.google.com/search?q=murder+she+wrote&oq=murder+she+wrote",
|
||||||
|
"ftp://123.123.123.123", "bears", "lots of hungry bears", "bears.com/thewoods",
|
||||||
|
"192.168.0.1", "1::6:7:8");
|
||||||
|
assertFunction(ValueType.URL_AUTHORITY, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCompactedIRI() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<String> goodValues = List.of("id", "email", "telephone", "url");
|
||||||
|
List<String> badValues = List.of("sloths");
|
||||||
|
assertFunction(ValueType.COMPACT_IRI, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBasicText() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<String> goodValues = List.of("string value");
|
||||||
|
List<Integer> badValues = List.of(3, 4);
|
||||||
|
assertFunction(ValueType.TEXT, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTelephone() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<String> goodValues = List.of("+64010", "+15417522845", "+18006664358", "+18006662344;ext=666");
|
||||||
|
List<String> badValues = List.of("1-800-666-DEVIL", "1 (555) 555-5555", "+99 55 22 1234", "+18006664343 x666");
|
||||||
|
assertFunction(ValueType.TELEPHONE, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmail() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<String> goodValues = List.of("abc@localhost", "cool+uncool@example.org");
|
||||||
|
List<String> badValues = List.of(" spacey@gmail.com", "steveman [at] gee mail dot com");
|
||||||
|
assertFunction(ValueType.EMAIL, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBoolean() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<Boolean> goodValues = List.of(true, false);
|
||||||
|
List<String> badValues = List.of(" spacey@gmail.com", "steveman [at] gee mail dot com");
|
||||||
|
assertFunction(ValueType.BOOLEAN, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDateTime() throws JsonMappingException, JsonProcessingException {
|
||||||
|
List<String> goodValues = List.of("1977-06-10T12:00:00+0800",
|
||||||
|
"1977-06-10T12:00:00-0800",
|
||||||
|
"1977-06-10T12:00:00+08",
|
||||||
|
"1977-06-10T12:00:00+08:00");
|
||||||
|
List<String> badValues = List.of("notadatetime", "1977-06-10T12:00:00");
|
||||||
|
assertFunction(ValueType.DATETIME, goodValues, badValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertFunction(ValueType valueType, List<? extends Object> goodValues, List<? extends Object> badValues) throws JsonMappingException, JsonProcessingException {
|
||||||
|
Function<JsonNode, Boolean> validationFunction = valueType.getValidationFunction();
|
||||||
|
for (Object goodValue : goodValues) {
|
||||||
|
assertTrue(validationFunction.apply(parseNode(goodValue)),
|
||||||
|
"`" + goodValue + "` should pass " + valueType + " validation but failed.");
|
||||||
|
}
|
||||||
|
for (Object badValue : badValues) {
|
||||||
|
assertFalse(validationFunction.apply(parseNode(badValue)),
|
||||||
|
"`" + badValue + "` should fail " + valueType + " validation but passed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonNode parseNode(Object value) throws JsonMappingException, JsonProcessingException {
|
||||||
|
if (value instanceof String) {
|
||||||
|
return mapper.readTree("\"" + value + "\"");
|
||||||
|
}
|
||||||
|
return mapper.readTree(value.toString());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user