Skip to content

Commit

Permalink
Merge pull request #3 from maicaballangan/feature/update-analysis-sum…
Browse files Browse the repository at this point in the history
…mary-layout

Feature/update analysis summary layout
  • Loading branch information
a-mnich authored Jul 9, 2024
2 parents 99213c0 + 34071b9 commit 19669a5
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Style getStyle() {
}

public enum Style {
NONE,
BULLET
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public Formatter<List> listFormatter() {
node.getChildren().forEach(i -> {
if (node.getStyle() == List.Style.BULLET) {
output.append("- ").append(format(i));
} else if (node.getStyle() == List.Style.NONE) {
output.append(format(i));
} else {
throw new IllegalArgumentException("Unknown list type: " + node.getStyle());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ public final class AnalysisSummary {
private final String duplicationsUrl;
private final String duplicationsImageUrl;

private final long totalIssueCount;

private final long bugCount;
private final String bugUrl;
private final String bugImageUrl;

private final long securityHotspotCount;
private final String securityHotspotUrl;
private final String securityHotspotImageUrl;

private final long vulnerabilityCount;
private final String vulnerabilityUrl;
private final String vulnerabilityImageUrl;
Expand All @@ -85,11 +86,12 @@ private AnalysisSummary(Builder builder) {
this.duplications = builder.duplications;
this.duplicationsUrl = builder.duplicationsUrl;
this.duplicationsImageUrl = builder.duplicationsImageUrl;
this.totalIssueCount = builder.totalIssueCount;
this.bugCount = builder.bugCount;
this.bugUrl = builder.bugUrl;
this.bugImageUrl = builder.bugImageUrl;
this.securityHotspotCount = builder.securityHotspotCount;
this.securityHotspotUrl = builder.securityHotspotUrl;
this.securityHotspotImageUrl = builder.securityHotspotImageUrl;
this.vulnerabilityCount = builder.vulnerabilityCount;
this.vulnerabilityUrl = builder.vulnerabilityUrl;
this.vulnerabilityImageUrl = builder.vulnerabilityImageUrl;
Expand Down Expand Up @@ -154,10 +156,6 @@ public String getDuplicationsImageUrl() {
return duplicationsImageUrl;
}

public long getTotalIssueCount() {
return totalIssueCount;
}

public long getBugCount() {
return bugCount;
}
Expand All @@ -174,6 +172,14 @@ public long getSecurityHotspotCount() {
return securityHotspotCount;
}

public String getSecurityHotspotUrl() {
return securityHotspotUrl;
}

public String getSecurityHotspotImageUrl() {
return securityHotspotImageUrl;
}

public long getVulnerabilityCount() {
return vulnerabilityCount;
}
Expand Down Expand Up @@ -203,45 +209,47 @@ public String format(FormatterFactory formatterFactory) {

List<String> failedConditions = getFailedQualityGateConditions();

Document document = new Document(new Paragraph(new Image(getStatusDescription(), getStatusImageUrl())),
Document document = new Document(
new Heading(
3,
new Text("Quality Gate"),
new Text(" "),
new Link(getDashboardUrl(), new Image(getStatusDescription(), getStatusImageUrl()))),
failedConditions.isEmpty() ? new Text("") :
new com.github.mc1arke.sonarqube.plugin.ce.pullrequest.markup.List(
com.github.mc1arke.sonarqube.plugin.ce.pullrequest.markup.List.Style.BULLET,
failedConditions.stream()
.map(Text::new)
.map(ListItem::new)
.toArray(ListItem[]::new)),
new Heading(1, new Text("Analysis Details")),
new Heading(2, new Text(pluralOf(getTotalIssueCount(), "Issue", "Issues"))),
new com.github.mc1arke.sonarqube.plugin.ce.pullrequest.markup.List(
com.github.mc1arke.sonarqube.plugin.ce.pullrequest.markup.List.Style.BULLET,
com.github.mc1arke.sonarqube.plugin.ce.pullrequest.markup.List.Style.NONE,
new ListItem(new Link(getBugUrl(), new Image("Bug", getBugImageUrl())),
new Text(" "),
new Text(pluralOf(getBugCount(), "Bug", "Bugs"))),
new ListItem(new Link(getSecurityHotspotUrl(), new Image("Security Hotspot", getSecurityHotspotImageUrl())),
new Text(" "),
new Text(pluralOf(getSecurityHotspotCount(), "Security Hotspot", "Security Hotspots"))),
new ListItem(new Link(getVulnerabilityUrl(), new Image("Vulnerability", getVulnerabilityImageUrl())),
new Text(" "),
new Text(pluralOf(getVulnerabilityCount() + getSecurityHotspotCount(), "Vulnerability", "Vulnerabilities"))),
new Text(pluralOf(getVulnerabilityCount(), "Vulnerability", "Vulnerabilities"))),
new ListItem(new Link(getCodeSmellUrl(), new Image("Code Smell", getCodeSmellImageUrl())),
new Text(" "),
new Text(pluralOf(getCodeSmellCount(), "Code Smell", "Code Smells")))),
new Heading(2, new Text("Coverage and Duplications")),
new com.github.mc1arke.sonarqube.plugin.ce.pullrequest.markup.List(
com.github.mc1arke.sonarqube.plugin.ce.pullrequest.markup.List.Style.BULLET,
new Text(pluralOf(getCodeSmellCount(), "Code Smell", "Code Smells"))),
new ListItem(new Link(getCoverageUrl(), new Image("Coverage", getCoverageImageUrl())),
new Text(" "), new Text(
Optional.ofNullable(getNewCoverage())
.map(decimalFormat::format)
.map(i -> i + "% Coverage")
.orElse("No coverage information") + " (" +
.orElse("No coverage info") + " (" +
decimalFormat.format(Optional.ofNullable(getCoverage()).orElse(BigDecimal.valueOf(0))) + "% Estimated after merge)")),
new ListItem(new Link(getDuplicationsUrl(), new Image("Duplications", getDuplicationsImageUrl())),
new Text(" "),
new Text(Optional.ofNullable(getNewDuplications())
.map(decimalFormat::format)
.map(i -> i + "% Duplicated Code")
.orElse("No duplication information") + " (" + decimalFormat.format(getDuplications()) + "% Estimated after merge)"))),
new Paragraph(new Text(String.format("**Project ID:** %s", getProjectKey()))),
new Paragraph(new Link(getDashboardUrl(), new Text("View in SonarQube"))));
.orElse("No duplication info") + " (" + decimalFormat.format(getDuplications()) + "% Estimated after merge)"))),
new Paragraph(new Text(String.format("**Project ID:** %s", getProjectKey()))));

return formatterFactory.documentFormatter().format(document);
}
Expand Down Expand Up @@ -274,13 +282,14 @@ public static class Builder {
private String duplicationsUrl;
private String duplicationsImageUrl;

private long totalIssueCount;

private long bugCount;
private String bugUrl;
private String bugImageUrl;

private long securityHotspotCount;
private String securityHotspotUrl;
private String securityHotspotImageUrl;

private long vulnerabilityCount;
private String vulnerabilityUrl;
private String vulnerabilityImageUrl;
Expand Down Expand Up @@ -363,11 +372,6 @@ public Builder withDuplicationsImageUrl(String duplicationsImageUrl) {
return this;
}

public Builder withTotalIssueCount(long totalIssueCount) {
this.totalIssueCount = totalIssueCount;
return this;
}

public Builder withBugCount(long bugCount) {
this.bugCount = bugCount;
return this;
Expand All @@ -388,6 +392,16 @@ public Builder withSecurityHotspotCount(long securityHotspotCount) {
return this;
}

public Builder withSecurityHotspotUrl(String securityHotspotUrl) {
this.securityHotspotUrl = securityHotspotUrl;
return this;
}

public Builder withSecurityHotspotImageUrl(String securityHotspotImageUrl) {
this.securityHotspotImageUrl = securityHotspotImageUrl;
return this;
}

public Builder withVulnerabilityCount(long vulnerabilityCount) {
this.vulnerabilityCount = vulnerabilityCount;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ public AnalysisSummary createAnalysisSummary(AnalysisDetails analysisDetails) {
.orElse(null);

Map<RuleType, Long> issueCounts = countRuleByType(analysisDetails.getIssues());
long issueTotal = issueCounts.values().stream().mapToLong(l -> l).sum();

List<QualityGate.Condition> failedConditions = analysisDetails.findFailedQualityGateConditions();

Expand Down Expand Up @@ -151,8 +150,9 @@ public AnalysisSummary createAnalysisSummary(AnalysisDetails analysisDetails) {
.withStatusImageUrl(QualityGate.Status.OK == analysisDetails.getQualityGateStatus()
? baseImageUrl + "/checks/QualityGateBadge/passed.png"
: baseImageUrl + "/checks/QualityGateBadge/failed.png")
.withTotalIssueCount(issueTotal)
.withSecurityHotspotCount(issueCounts.get(RuleType.SECURITY_HOTSPOT))
.withSecurityHotspotUrl(getIssuesUrlForRuleType(analysisDetails, RuleType.SECURITY_HOTSPOT))
.withSecurityHotspotImageUrl(baseImageUrl + "/common/security_hotspot.png")
.withVulnerabilityCount(issueCounts.get(RuleType.VULNERABILITY))
.withVulnerabilityUrl(getIssuesUrlForRuleType(analysisDetails, RuleType.VULNERABILITY))
.withVulnerabilityImageUrl(baseImageUrl + "/common/vulnerability.png")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ void testCreateAnalysisSummary() {
.withFailedQualityGateConditions(java.util.List.of("issuea", "issueb", "issuec"))
.withNewCoverage(BigDecimal.valueOf(99))
.withSecurityHotspotCount(69)
.withSecurityHotspotUrl("securityHotspotUrl")
.withSecurityHotspotImageUrl("securityHotspotImageUrl")
.withStatusDescription("status description")
.withStatusImageUrl("statusImageUrl")
.withTotalIssueCount(666)
.withVulnerabilityCount(96)
.withVulnerabilityUrl("vulnerabilityUrl")
.withVulnerabilityImageUrl("vulnerabilityImageUrl")
Expand All @@ -81,38 +82,42 @@ void testCreateAnalysisSummary() {
ArgumentCaptor<Document> documentArgumentCaptor = ArgumentCaptor.forClass(Document.class);
verify(formatter).format(documentArgumentCaptor.capture());

Document expectedDocument = new Document(new Paragraph(new Image("status description", "statusImageUrl")),
Document expectedDocument = new Document(
new Heading(
3,
new Text("Quality Gate"),
new Text(" "),
new Link("dashboardUrl", new Image("status description", "statusImageUrl"))),
new List(List.Style.BULLET,
new ListItem(new Text("issuea")),
new ListItem(new Text("issueb")),
new ListItem(new Text("issuec"))),
new Heading(1, new Text("Analysis Details")),
new Heading(2, new Text("666 Issues")),
new List(List.Style.BULLET,
new List(List.Style.NONE,
new ListItem(
new Link("bugUrl", new Image("Bug","bugImageUrl")),
new Text(" "),
new Text("911 Bugs")),
new ListItem(
new Link("vulnerabilityUrl", new Image("Vulnerability","vulnerabilityImageUrl")),
new Text(" "),
new Text("165 Vulnerabilities")),
new ListItem(
new Link("codeSmellUrl", new Image("Code Smell", "codeSmellImageUrl")),
new Text(" "),
new Text("1 Code Smell"))),
new Heading(2, new Text("Coverage and Duplications")),
new List(List.Style.BULLET,
new ListItem(
new Link("codeCoverageUrl", new Image("Coverage", "codeCoverageImageUrl")),
new Text(" "),
new Text("99.00% Coverage (303.00% Estimated after merge)")),
new ListItem(
new Link("duplicationsUrl", new Image("Duplications", "duplicationsImageUrl")),
new Text(" "),
new Text("199.00% Duplicated Code (66.00% Estimated after merge)"))),
new Paragraph(new Text("**Project ID:** projectKey")),
new Paragraph(new Link("dashboardUrl", new Text("View in SonarQube"))));
new ListItem(
new Link("securityHotspotUrl", new Image("Security Hotspot","securityHotspotImageUrl")),
new Text(" "),
new Text("69 Security Hotspots")),
new ListItem(
new Link("vulnerabilityUrl", new Image("Vulnerability","vulnerabilityImageUrl")),
new Text(" "),
new Text("96 Vulnerabilities")),
new ListItem(
new Link("codeSmellUrl", new Image("Code Smell", "codeSmellImageUrl")),
new Text(" "),
new Text("1 Code Smell")),
new ListItem(
new Link("codeCoverageUrl", new Image("Coverage", "codeCoverageImageUrl")),
new Text(" "),
new Text("99.00% Coverage (303.00% Estimated after merge)")),
new ListItem(
new Link("duplicationsUrl", new Image("Duplications", "duplicationsImageUrl")),
new Text(" "),
new Text("199.00% Duplicated Code (66.00% Estimated after merge)"))),
new Paragraph(new Text("**Project ID:** projectKey")));

assertThat(documentArgumentCaptor.getValue()).usingRecursiveComparison().isEqualTo(expectedDocument);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,13 @@ void shouldProduceCorrectAnalysisSummary(String coverage, String coverageImage,
.withProjectKey("projectKey")
.withSummaryImageUrl("http://localhost:9000/static/communityBranchPlugin/common/icon.png")
.withSecurityHotspotCount(1)
.withSecurityHotspotUrl("http://localhost:9000/project/issues?pullRequest=5&resolved=false&types=SECURITY_HOTSPOT&inNewCodePeriod=true&id=projectKey")
.withSecurityHotspotImageUrl("http://localhost:9000/static/communityBranchPlugin/common/security_hotspot.png")
.withVulnerabilityCount(1)
.withVulnerabilityUrl("http://localhost:9000/project/issues?pullRequest=5&resolved=false&types=VULNERABILITY&inNewCodePeriod=true&id=projectKey")
.withVulnerabilityImageUrl("http://localhost:9000/static/communityBranchPlugin/common/vulnerability.png")
.withStatusDescription("Failed")
.withStatusImageUrl("http://localhost:9000/static/communityBranchPlugin/checks/QualityGateBadge/failed.png")
.withTotalIssueCount(5)
.withFailedQualityGateConditions(List.of("19 Lines to Cover (is less than 20)",
"2 Code Smells (is greater than 0)",
"68.00% Line Coverage (is less than 80.00%)",
Expand Down

0 comments on commit 19669a5

Please sign in to comment.