Skip to content

Commit aa7b913

Browse files
authored
Merge pull request #193 from olavtar/HtmlTestsSeparated
Separated HTML Report Tests
2 parents 4ca7ea4 + 1d59b0b commit aa7b913

File tree

2 files changed

+308
-265
lines changed

2 files changed

+308
-265
lines changed

src/test/java/com/redhat/exhort/integration/AnalysisTest.java

Lines changed: 0 additions & 265 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import static org.junit.jupiter.api.Assertions.assertNotNull;
2828
import static org.junit.jupiter.api.Assertions.assertNull;
2929
import static org.junit.jupiter.api.Assertions.assertTrue;
30-
import static org.junit.jupiter.api.Assertions.fail;
3130

3231
import java.io.IOException;
3332
import java.net.URI;
@@ -47,16 +46,6 @@
4746
import org.junit.jupiter.params.provider.MethodSource;
4847
import org.junit.jupiter.params.provider.ValueSource;
4948

50-
import com.gargoylesoftware.htmlunit.html.DomElement;
51-
import com.gargoylesoftware.htmlunit.html.DomNodeList;
52-
import com.gargoylesoftware.htmlunit.html.HtmlButton;
53-
import com.gargoylesoftware.htmlunit.html.HtmlHeading4;
54-
import com.gargoylesoftware.htmlunit.html.HtmlPage;
55-
import com.gargoylesoftware.htmlunit.html.HtmlTable;
56-
import com.gargoylesoftware.htmlunit.html.HtmlTableBody;
57-
import com.gargoylesoftware.htmlunit.html.HtmlTableDataCell;
58-
import com.gargoylesoftware.htmlunit.html.HtmlTableHeaderCell;
59-
import com.gargoylesoftware.htmlunit.html.HtmlTableRow;
6049
import com.redhat.exhort.api.PackageRef;
6150
import com.redhat.exhort.api.v4.AnalysisReport;
6251
import com.redhat.exhort.api.v4.DependencyReport;
@@ -426,121 +415,6 @@ public void testNonVerboseWithToken() {
426415
verifySnykRequest(OK_TOKEN);
427416
}
428417

429-
/**
430-
* The generated HTML only has 1 vulnerability tab for Snyk. The quarkus-hibernate-orm has a
431-
* private vulnerability that should be hidden and display the "Sign up" link to the user.
432-
*
433-
* <p>In order to expand the transitive table, it is required to click on the button contained in
434-
* the <td>
435-
*/
436-
@Test
437-
public void testHtmlWithoutToken() {
438-
stubAllProviders();
439-
440-
String body =
441-
given()
442-
.header(CONTENT_TYPE, CycloneDxMediaType.APPLICATION_CYCLONEDX_JSON)
443-
.body(loadSBOMFile(CYCLONEDX))
444-
.header("Accept", MediaType.TEXT_HTML)
445-
.when()
446-
.post("/api/v4/analysis")
447-
.then()
448-
.assertThat()
449-
.statusCode(200)
450-
.contentType(MediaType.TEXT_HTML)
451-
.extract()
452-
.body()
453-
.asString();
454-
455-
var page = extractPage(body);
456-
DomNodeList<DomElement> tables = page.getElementsByTagName("table");
457-
assertEquals(1, tables.size());
458-
var snykTable = tables.get(0);
459-
var tbody = getTableBodyForDependency("io.quarkus:quarkus-hibernate-orm", snykTable);
460-
assertNotNull(tbody);
461-
page = expandTransitiveTableDataCell(tbody);
462-
snykTable = page.getElementsByTagName("table").get(0);
463-
tbody = getTableBodyForDependency("io.quarkus:quarkus-hibernate-orm", snykTable);
464-
465-
var issuesTable = getIssuesTable(tbody);
466-
List<HtmlTableBody> tbodies = issuesTable.getByXPath(".//table//tbody");
467-
var privateIssueTbody =
468-
tbodies.stream()
469-
.filter(
470-
issuesTbody -> {
471-
List<HtmlTableDataCell> tds = issuesTbody.getByXPath("./tr/td");
472-
return tds.size() == 4;
473-
})
474-
.findFirst()
475-
.get();
476-
assertNotNull(privateIssueTbody);
477-
HtmlTableDataCell td = privateIssueTbody.getFirstByXPath("./tr/td");
478-
assertEquals(
479-
"Sign up for a Snyk account to learn about the vulnerabilities found",
480-
td.asNormalizedText());
481-
482-
verifySnykRequest(null);
483-
}
484-
485-
/**
486-
* This report contains both oss-index and snyk reports. So in order to show the Snyk report, we
487-
* need to click on the tab. Then the quarkus-hibernate-orm having the unique vulnerability should
488-
* appear without limitations.
489-
*
490-
* @throws IOException
491-
*/
492-
@Test
493-
public void testHtmlWithToken() throws IOException {
494-
stubAllProviders();
495-
496-
var body =
497-
given()
498-
.header(CONTENT_TYPE, CycloneDxMediaType.APPLICATION_CYCLONEDX_JSON)
499-
.body(loadSBOMFile(CYCLONEDX))
500-
.header("Accept", MediaType.TEXT_HTML)
501-
.header(Constants.SNYK_TOKEN_HEADER, OK_TOKEN)
502-
.header(Constants.OSS_INDEX_USER_HEADER, OK_USER)
503-
.header(Constants.OSS_INDEX_TOKEN_HEADER, OK_TOKEN)
504-
.when()
505-
.post("/api/v4/analysis")
506-
.then()
507-
.assertThat()
508-
.statusCode(200)
509-
.contentType(MediaType.TEXT_HTML)
510-
.extract()
511-
.body()
512-
.asString();
513-
514-
var page = extractPage(body);
515-
// Select the Snyk Source
516-
HtmlButton snykSourceBtn = page.getFirstByXPath("//button[@aria-label='snyk source']");
517-
assertNotNull(snykSourceBtn);
518-
page = snykSourceBtn.click();
519-
520-
DomNodeList<DomElement> tables = page.getElementsByTagName("table");
521-
assertEquals(2, tables.size());
522-
523-
var tbody = getTableBodyForDependency("io.quarkus:quarkus-hibernate-orm", tables.get(1));
524-
assertNotNull(tbody);
525-
page = expandTransitiveTableDataCell(tbody);
526-
tables = page.getElementsByTagName("table");
527-
tbody = getTableBodyForDependency("io.quarkus:quarkus-hibernate-orm", tables.get(1));
528-
529-
// TODO: figure out why the Snyk unique vulnerability is not being rendered in headless mode
530-
531-
// HtmlTable issuesTable = getIssuesTable(tbody);
532-
// List<HtmlTableBody> tbodies = issuesTable.getByXPath(".//table//tbody");
533-
// HtmlTableBody privateIssueTbody = tbodies.stream().filter(issuesTbody -> {
534-
// List<HtmlTableDataCell> tds = issuesTbody.getByXPath("./tr/td");
535-
// return tds.get(0).asNormalizedText().startsWith("SNYK");
536-
537-
// }).findFirst().get();
538-
// assertNotNull(privateIssueTbody);
539-
540-
verifySnykRequest(OK_TOKEN);
541-
verifyOssRequest(OK_USER, OK_TOKEN, false);
542-
}
543-
544418
@ParameterizedTest
545419
@ValueSource(strings = {"HTTP_1_1", "HTTP_2"})
546420
public void testMultipart_HttpVersions(String version) throws IOException, InterruptedException {
@@ -567,99 +441,6 @@ public void testMultipart_HttpVersions(String version) throws IOException, Inter
567441
verifyOssRequest(OK_USER, OK_TOKEN, false);
568442
}
569443

570-
@Test
571-
public void testHtmlUnauthorized() {
572-
stubAllProviders();
573-
574-
var body =
575-
given()
576-
.header(CONTENT_TYPE, CycloneDxMediaType.APPLICATION_CYCLONEDX_JSON)
577-
.body(loadSBOMFile(CYCLONEDX))
578-
.header("Accept", MediaType.TEXT_HTML)
579-
.header(Constants.SNYK_TOKEN_HEADER, INVALID_TOKEN)
580-
.when()
581-
.post("/api/v4/analysis")
582-
.then()
583-
.assertThat()
584-
.statusCode(200)
585-
.contentType(MediaType.TEXT_HTML)
586-
.extract()
587-
.body()
588-
.asString();
589-
590-
var page = extractPage(body);
591-
HtmlHeading4 heading = page.getFirstByXPath("//div[@class='pf-v5-c-alert pf-m-warning']/h4");
592-
assertEquals(
593-
"Warning alert:Snyk: Unauthorized: Verify the provided credentials are valid.",
594-
heading.getTextContent());
595-
assertTrue(page.getElementsByTagName("table").isEmpty());
596-
597-
verifySnykRequest(INVALID_TOKEN);
598-
verifyNoInteractionsWithOSS();
599-
}
600-
601-
@Test
602-
public void testHtmlForbidden() {
603-
stubAllProviders();
604-
605-
var body =
606-
given()
607-
.header(CONTENT_TYPE, CycloneDxMediaType.APPLICATION_CYCLONEDX_JSON)
608-
.body(loadSBOMFile(CYCLONEDX))
609-
.header("Accept", MediaType.TEXT_HTML)
610-
.header(Constants.SNYK_TOKEN_HEADER, UNAUTH_TOKEN)
611-
.when()
612-
.post("/api/v4/analysis")
613-
.then()
614-
.assertThat()
615-
.statusCode(200)
616-
.contentType(MediaType.TEXT_HTML)
617-
.extract()
618-
.body()
619-
.asString();
620-
621-
var page = extractPage(body);
622-
HtmlHeading4 heading = page.getFirstByXPath("//div[@class='pf-v5-c-alert pf-m-warning']/h4");
623-
assertEquals(
624-
"Warning alert:Snyk: Forbidden: The provided credentials don't have the required"
625-
+ " permissions.",
626-
heading.getTextContent());
627-
assertTrue(page.getElementsByTagName("table").isEmpty());
628-
629-
verifySnykRequest(UNAUTH_TOKEN);
630-
verifyNoInteractionsWithOSS();
631-
}
632-
633-
@Test
634-
public void testHtmlError() {
635-
stubAllProviders();
636-
637-
var body =
638-
given()
639-
.header(CONTENT_TYPE, CycloneDxMediaType.APPLICATION_CYCLONEDX_JSON)
640-
.body(loadSBOMFile(CYCLONEDX))
641-
.header("Accept", MediaType.TEXT_HTML)
642-
.header(Constants.SNYK_TOKEN_HEADER, ERROR_TOKEN)
643-
.when()
644-
.post("/api/v4/analysis")
645-
.then()
646-
.assertThat()
647-
.statusCode(200)
648-
.contentType(MediaType.TEXT_HTML)
649-
.extract()
650-
.body()
651-
.asString();
652-
653-
var page = extractPage(body);
654-
HtmlHeading4 heading = page.getFirstByXPath("//div[@class='pf-v5-c-alert pf-m-danger']/h4");
655-
assertEquals(
656-
"Danger alert:Snyk: Server Error: This is an example error", heading.getTextContent());
657-
assertTrue(page.getElementsByTagName("table").isEmpty());
658-
659-
verifySnykRequest(ERROR_TOKEN);
660-
verifyNoInteractionsWithOSS();
661-
}
662-
663444
@Test
664445
public void testUnknownMediaType() {
665446
given()
@@ -732,50 +513,4 @@ private DependencyReport getReport(String pkgName, List<DependencyReport> depend
732513
assertNotNull(dep);
733514
return dep;
734515
}
735-
736-
private HtmlTableBody getTableBodyForDependency(String depRef, DomElement table) {
737-
List<HtmlTableBody> tbodies = table.getByXPath(".//tbody");
738-
return tbodies.stream()
739-
.filter(
740-
tbody -> {
741-
HtmlTableHeaderCell th = tbody.getFirstByXPath("./tr/th");
742-
return th.asNormalizedText().equals(depRef);
743-
})
744-
.findFirst()
745-
.orElse(null);
746-
}
747-
748-
private HtmlPage expandTransitiveTableDataCell(HtmlTableBody tbody) {
749-
return expandTableDataCell(tbody, "Transitive Vulnerabilities");
750-
}
751-
752-
private HtmlPage expandDirectTableDataCell(HtmlTableBody tbody) {
753-
return expandTableDataCell(tbody, "Direct Vulnerabilities");
754-
}
755-
756-
private HtmlPage expandTableDataCell(HtmlTableBody tbody, String dataLabel) {
757-
HtmlTableDataCell td =
758-
tbody.getFirstByXPath(String.format("./tr/td[@data-label='%s']", dataLabel));
759-
if (td.getAttribute("class").contains("pf-m-expanded")) {
760-
return tbody.getHtmlPageOrNull();
761-
}
762-
try {
763-
HtmlButton button = td.getFirstByXPath("./button");
764-
return button.click();
765-
} catch (IOException e) {
766-
fail("Unable to click on td for data-label: " + dataLabel, e);
767-
return null;
768-
}
769-
}
770-
771-
private HtmlTable getIssuesTable(HtmlTableBody dependencyTable) {
772-
List<HtmlTableRow> rows = dependencyTable.getByXPath("./tr");
773-
if (rows.size() != 2) {
774-
fail(
775-
"Expected table to have 2 <tr>. One for the dependency name and another for the"
776-
+ " vulnerabilities. Found: "
777-
+ rows.size());
778-
}
779-
return rows.get(1).getFirstByXPath("//table");
780-
}
781516
}

0 commit comments

Comments
 (0)