|
13 | 13 | */ |
14 | 14 | package org.cyclonedx.schema; |
15 | 15 |
|
16 | | -import java.io.File; |
| 16 | +import static java.util.Objects.requireNonNull; |
| 17 | +import static org.junit.jupiter.api.Assertions.assertFalse; |
| 18 | +import static org.junit.jupiter.api.Assertions.assertTrue; |
| 19 | + |
| 20 | +import com.fasterxml.jackson.core.JsonParser; |
| 21 | +import com.fasterxml.jackson.databind.JsonNode; |
| 22 | +import com.fasterxml.jackson.databind.ObjectMapper; |
| 23 | +import com.fasterxml.jackson.databind.json.JsonMapper; |
| 24 | +import com.networknt.schema.DefaultJsonMetaSchemaFactory; |
| 25 | +import com.networknt.schema.DisallowUnknownKeywordFactory; |
| 26 | +import com.networknt.schema.JsonMetaSchema; |
| 27 | +import com.networknt.schema.JsonMetaSchemaFactory; |
| 28 | +import com.networknt.schema.JsonSchema; |
| 29 | +import com.networknt.schema.JsonSchemaFactory; |
| 30 | +import com.networknt.schema.NonValidationKeyword; |
| 31 | +import com.networknt.schema.SchemaId; |
| 32 | +import com.networknt.schema.SchemaValidatorsConfig; |
| 33 | +import java.io.IOException; |
| 34 | +import java.io.InputStream; |
| 35 | +import java.net.URISyntaxException; |
17 | 36 | import java.util.ArrayList; |
18 | 37 | import java.util.Collection; |
19 | 38 | import java.util.List; |
20 | | - |
21 | | -import org.cyclonedx.parsers.JsonParser; |
22 | | -import org.cyclonedx.Version; |
| 39 | +import org.apache.commons.lang3.StringUtils; |
23 | 40 | import org.junit.jupiter.api.DynamicTest; |
24 | 41 | import org.junit.jupiter.api.TestFactory; |
25 | 42 |
|
26 | | -import static org.junit.jupiter.api.Assertions.assertTrue; |
27 | | -import static org.junit.jupiter.api.Assertions.assertFalse; |
| 43 | +class JsonSchemaVerificationTest extends BaseSchemaVerificationTest { |
| 44 | + |
| 45 | + private static final ObjectMapper MAPPER = new JsonMapper(); |
| 46 | + |
| 47 | + private static final JsonSchema VERSION_12; |
| 48 | + private static final JsonSchema VERSION_13; |
| 49 | + private static final JsonSchema VERSION_14; |
| 50 | + private static final JsonSchema VERSION_15; |
| 51 | + private static final JsonSchema VERSION_16; |
| 52 | + |
| 53 | + static { |
| 54 | + JsonMetaSchemaFactory metaSchemaFactory = new DefaultJsonMetaSchemaFactory() { |
| 55 | + @Override |
| 56 | + public JsonMetaSchema getMetaSchema( |
| 57 | + String iri, JsonSchemaFactory schemaFactory, SchemaValidatorsConfig config) { |
| 58 | + return addCustomKeywords(super.getMetaSchema(iri, schemaFactory, config)); |
| 59 | + } |
| 60 | + }; |
| 61 | + JsonSchemaFactory factory = JsonSchemaFactory.builder() |
| 62 | + .defaultMetaSchemaIri(SchemaId.V7) |
| 63 | + .metaSchema(addCustomKeywords(JsonMetaSchema.getV7())) |
| 64 | + .metaSchemaFactory(metaSchemaFactory) |
| 65 | + .build(); |
| 66 | + ClassLoader cl = JsonSchemaVerificationTest.class.getClassLoader(); |
| 67 | + try { |
| 68 | + VERSION_12 = factory.getSchema( |
| 69 | + requireNonNull(cl.getResource("bom-1.2-strict.schema.json")).toURI()); |
| 70 | + VERSION_13 = factory.getSchema( |
| 71 | + requireNonNull(cl.getResource("bom-1.3-strict.schema.json")).toURI()); |
| 72 | + VERSION_14 = factory.getSchema( |
| 73 | + requireNonNull(cl.getResource("bom-1.4.schema.json")).toURI()); |
| 74 | + VERSION_15 = factory.getSchema( |
| 75 | + requireNonNull(cl.getResource("bom-1.5.schema.json")).toURI()); |
| 76 | + VERSION_16 = factory.getSchema( |
| 77 | + requireNonNull(cl.getResource("bom-1.6.schema.json")).toURI()); |
| 78 | + } catch (URISyntaxException e) { |
| 79 | + throw new IllegalStateException(e); |
| 80 | + } |
| 81 | + } |
28 | 82 |
|
29 | | -public class JsonSchemaVerificationTest extends BaseSchemaVerificationTest { |
| 83 | + private static JsonMetaSchema addCustomKeywords(JsonMetaSchema metaSchema) { |
| 84 | + return JsonMetaSchema.builder(metaSchema) |
| 85 | + // Non-standard keywords in the CycloneDX schema files. |
| 86 | + .keyword(new NonValidationKeyword("deprecated")) |
| 87 | + .keyword(new NonValidationKeyword("meta:enum")) |
| 88 | + .unknownKeywordFactory(new DisallowUnknownKeywordFactory()) |
| 89 | + .build(); |
| 90 | + } |
30 | 91 |
|
31 | 92 | @TestFactory |
32 | 93 | Collection<DynamicTest> dynamicTestsWithCollection() throws Exception { |
33 | | - final List<String> files = getAllResources(); |
| 94 | + final List<String> resources = getAllResources(); |
34 | 95 | final List<DynamicTest> dynamicTests = new ArrayList<>(); |
35 | | - for (final String file: files) { |
36 | | - if (file.endsWith(".json")) { |
37 | | - final Version schemaVersion; |
38 | | - if (file.endsWith("-1.2.json")) { |
39 | | - schemaVersion = Version.VERSION_12; |
40 | | - } else if (file.endsWith("-1.3.json")) { |
41 | | - schemaVersion = Version.VERSION_13; |
42 | | - } else if (file.endsWith("-1.4.json")) { |
43 | | - schemaVersion = Version.VERSION_14; |
44 | | - } else if (file.endsWith("-1.5.json")) { |
45 | | - schemaVersion = Version.VERSION_15; |
46 | | - } else if (file.endsWith("-1.6.json")) { |
47 | | - schemaVersion = Version.VERSION_16; |
48 | | - } else { |
49 | | - schemaVersion = null; |
50 | | - } |
51 | | - if (file.startsWith("valid") && schemaVersion != null) { |
52 | | - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertTrue( |
53 | | - isValidJson(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); |
54 | | - } else if (file.startsWith("invalid") && schemaVersion != null) { |
55 | | - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertFalse( |
56 | | - isValidJson(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); |
| 96 | + for (final String resource : resources) { |
| 97 | + String resourceName = StringUtils.substringAfterLast(resource, "/"); |
| 98 | + if (resourceName.endsWith(".json")) { |
| 99 | + JsonSchema schema = getSchema(resourceName); |
| 100 | + if (schema != null) { |
| 101 | + if (resourceName.startsWith("valid")) { |
| 102 | + dynamicTests.add(DynamicTest.dynamicTest( |
| 103 | + resource, () -> assertTrue(isValid(schema, resource), resource))); |
| 104 | + } else if (resourceName.startsWith("invalid")) { |
| 105 | + dynamicTests.add(DynamicTest.dynamicTest( |
| 106 | + resource, () -> assertFalse(isValid(schema, resource), resource))); |
| 107 | + } |
57 | 108 | } |
58 | 109 | } |
59 | 110 | } |
60 | 111 | return dynamicTests; |
61 | 112 | } |
62 | 113 |
|
63 | | - private boolean isValidJson(Version version, String resource) throws Exception { |
64 | | - final File file = new File(this.getClass().getResource(resource).getFile()); |
65 | | - final JsonParser parser = new JsonParser(); |
66 | | - return parser.isValid(file, version); |
67 | | - |
68 | | - // Uncomment to provide more detailed validation errors |
69 | | - /* |
70 | | - try { |
71 | | - final String jsonString = FileUtils.readFileToString(file, StandardCharsets.UTF_8); |
72 | | - parser.getJsonSchema(version, true).validate(new JSONObject(jsonString)); |
73 | | - return true; |
74 | | - } catch (ValidationException e) { |
75 | | - e.printStackTrace(); |
| 114 | + private boolean isValid(JsonSchema schema, String resource) { |
| 115 | + try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource); |
| 116 | + JsonParser parser = MAPPER.createParser(input)) { |
| 117 | + JsonNode node = parser.readValueAsTree(); |
| 118 | + return schema.validate(node).isEmpty(); |
| 119 | + } catch (IOException e) { |
76 | 120 | return false; |
77 | 121 | } |
78 | | - */ |
| 122 | + } |
| 123 | + |
| 124 | + private JsonSchema getSchema(String resourceName) { |
| 125 | + if (resourceName.endsWith("-1.2.json")) { |
| 126 | + return VERSION_12; |
| 127 | + } |
| 128 | + if (resourceName.endsWith("-1.3.json")) { |
| 129 | + return VERSION_13; |
| 130 | + } |
| 131 | + if (resourceName.endsWith("-1.4.json")) { |
| 132 | + return VERSION_14; |
| 133 | + } |
| 134 | + if (resourceName.endsWith("-1.5.json")) { |
| 135 | + return VERSION_15; |
| 136 | + } |
| 137 | + if (resourceName.endsWith("-1.6.json")) { |
| 138 | + return VERSION_16; |
| 139 | + } |
| 140 | + return null; |
79 | 141 | } |
80 | 142 | } |
0 commit comments