|
3 | 3 | import com.freenow.sauron.model.DataSet; |
4 | 4 | import com.freenow.sauron.properties.PluginsConfigurationProperties; |
5 | 5 | import com.github.tomakehurst.wiremock.junit.WireMockRule; |
| 6 | +import java.lang.reflect.InvocationTargetException; |
| 7 | +import java.lang.reflect.Method; |
| 8 | +import java.nio.charset.StandardCharsets; |
| 9 | +import org.cyclonedx.model.Component; |
6 | 10 | import org.junit.Before; |
7 | 11 | import org.junit.Rule; |
8 | 12 | import org.junit.Test; |
|
14 | 18 | import java.nio.file.Path; |
15 | 19 | import java.nio.file.Paths; |
16 | 20 | import java.util.HashMap; |
| 21 | +import java.util.List; |
17 | 22 | import java.util.Map; |
18 | 23 | import java.util.Objects; |
19 | 24 | import java.util.Optional; |
@@ -220,8 +225,7 @@ public void testDependencyCheckerNodeJs() throws IOException, URISyntaxException |
220 | 225 | )) |
221 | 226 | ); |
222 | 227 | } |
223 | | - |
224 | | - |
| 228 | + |
225 | 229 | @Test |
226 | 230 | public void testDependencyCheckerNodeJsYarnNotSupported() throws IOException, URISyntaxException |
227 | 231 | { |
@@ -440,4 +444,102 @@ private PluginsConfigurationProperties pluginConfigurationProperties() |
440 | 444 |
|
441 | 445 | return properties; |
442 | 446 | } |
| 447 | + |
| 448 | + @Test |
| 449 | + public void testParseCycloneDxJsonWithInvalidSerialNumber() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException |
| 450 | + { |
| 451 | + // Given |
| 452 | + String invalidBomContent = "{\n" + |
| 453 | + " \"bomFormat\": \"CycloneDX\",\n" + |
| 454 | + " \"specVersion\": \"1.4\",\n" + |
| 455 | + " \"serialNumber\": \"urn:uuid:***\",\n" + |
| 456 | + " \"version\": 1,\n" + |
| 457 | + " \"components\": [\n" + |
| 458 | + " {\n" + |
| 459 | + " \"type\": \"library\",\n" + |
| 460 | + " \"name\": \"react\",\n" + |
| 461 | + " \"version\": \"18.2.0\"\n" + |
| 462 | + " }\n" + |
| 463 | + " ]\n" + |
| 464 | + "}"; |
| 465 | + |
| 466 | + Path bomJson = tempFolder.getRoot().toPath().resolve("bom.json"); |
| 467 | + Files.write(bomJson, invalidBomContent.getBytes(StandardCharsets.UTF_8)); |
| 468 | + |
| 469 | + // When |
| 470 | + List<Component> components = invokeParseCycloneDxJson(plugin, bomJson); |
| 471 | + |
| 472 | + // Then |
| 473 | + assertNotNull(components); |
| 474 | + assertEquals(1, components.size()); |
| 475 | + assertEquals("react", components.get(0).getName()); |
| 476 | + assertEquals("18.2.0", components.get(0).getVersion()); |
| 477 | + |
| 478 | + String sanitizedBomContent = new String(Files.readAllBytes(bomJson), StandardCharsets.UTF_8); |
| 479 | + assertFalse("The serialNumber should have been sanitized", sanitizedBomContent.contains("***")); |
| 480 | + } |
| 481 | + |
| 482 | + @Test |
| 483 | + public void testParseCycloneDxJsonWithValidBom() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException |
| 484 | + { |
| 485 | + // Given |
| 486 | + String validBomContent = "{\n" + |
| 487 | + " \"bomFormat\": \"CycloneDX\",\n" + |
| 488 | + " \"specVersion\": \"1.4\",\n" + |
| 489 | + " \"serialNumber\": \"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79\",\n" + |
| 490 | + " \"version\": 1,\n" + |
| 491 | + " \"components\": [\n" + |
| 492 | + " {\n" + |
| 493 | + " \"type\": \"library\",\n" + |
| 494 | + " \"name\": \"express\",\n" + |
| 495 | + " \"version\": \"4.18.2\"\n" + |
| 496 | + " }\n" + |
| 497 | + " ]\n" + |
| 498 | + "}"; |
| 499 | + |
| 500 | + Path bomJson = tempFolder.getRoot().toPath().resolve("bom.json"); |
| 501 | + Files.write(bomJson, validBomContent.getBytes(StandardCharsets.UTF_8)); |
| 502 | + |
| 503 | + // When |
| 504 | + List<Component> components = invokeParseCycloneDxJson(plugin, bomJson); |
| 505 | + |
| 506 | + // Then |
| 507 | + assertNotNull(components); |
| 508 | + assertEquals(1, components.size()); |
| 509 | + assertEquals("express", components.get(0).getName()); |
| 510 | + assertEquals("4.18.2", components.get(0).getVersion()); |
| 511 | + |
| 512 | + String bomContent = new String(Files.readAllBytes(bomJson), StandardCharsets.UTF_8); |
| 513 | + assertEquals("The BOM file should not be modified", validBomContent, bomContent); |
| 514 | + } |
| 515 | + |
| 516 | + @Test |
| 517 | + public void testParseCycloneDxJsonWithNoComponents() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException |
| 518 | + { |
| 519 | + // Given |
| 520 | + String bomWithNoComponents = "{\n" + |
| 521 | + " \"bomFormat\": \"CycloneDX\",\n" + |
| 522 | + " \"specVersion\": \"1.4\",\n" + |
| 523 | + " \"serialNumber\": \"urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79\",\n" + |
| 524 | + " \"version\": 1,\n" + |
| 525 | + " \"components\": []\n" + |
| 526 | + "}"; |
| 527 | + |
| 528 | + Path bomJson = tempFolder.getRoot().toPath().resolve("bom.json"); |
| 529 | + Files.write(bomJson, bomWithNoComponents.getBytes(StandardCharsets.UTF_8)); |
| 530 | + |
| 531 | + // When |
| 532 | + List<Component> components = invokeParseCycloneDxJson(plugin, bomJson); |
| 533 | + |
| 534 | + // Then |
| 535 | + assertNotNull(components); |
| 536 | + assertTrue(components.isEmpty()); |
| 537 | + } |
| 538 | + |
| 539 | + @SuppressWarnings("unchecked") |
| 540 | + private List<Component> invokeParseCycloneDxJson(DependencyChecker plugin, Path bom) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { |
| 541 | + Method method = DependencyChecker.class.getDeclaredMethod("parseCycloneDxJson", Path.class); |
| 542 | + method.setAccessible(true); |
| 543 | + return (List<Component>) method.invoke(plugin, bom); |
| 544 | + } |
443 | 545 | } |
0 commit comments