From ffaa8f3cd63239fc25c624955e8e0760dc53ce11 Mon Sep 17 00:00:00 2001 From: Philippe Perrin Date: Tue, 23 Feb 2021 17:22:27 +0100 Subject: [PATCH] SONAR-13357 Custom hotspot rule's description isn't split into tabs --- .../server/rule/HotspotRuleDescription.java | 6 +-- .../server/rule/RuleDescriptionFormatter.java | 0 .../rule/HotspotRuleDescriptionTest.java | 38 +++++++++++++++++++ .../rule/RuleDescriptionFormatterTest.java | 0 .../sonar/server/hotspot/ws/ShowAction.java | 18 +++------ .../server/hotspot/ws/ShowActionTest.java | 8 +--- .../sonar/markdown/HtmlHeadingChannel.java | 2 +- .../java/org/sonar/markdown/MarkdownTest.java | 4 +- 8 files changed, 51 insertions(+), 25 deletions(-) rename server/{sonar-webserver-webapi => sonar-server-common}/src/main/java/org/sonar/server/rule/RuleDescriptionFormatter.java (100%) rename server/{sonar-webserver-webapi => sonar-server-common}/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java (100%) diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/HotspotRuleDescription.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/HotspotRuleDescription.java index 11b2607e2dc..01c434924f5 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/HotspotRuleDescription.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/HotspotRuleDescription.java @@ -48,7 +48,7 @@ public class HotspotRuleDescription { } public static HotspotRuleDescription from(RuleDefinitionDto dto) { - String description = dto.getDescription(); + String description = dto.isCustomRule() ? RuleDescriptionFormatter.getDescriptionAsHtml(dto) : dto.getDescription(); return from(description); } @@ -111,12 +111,12 @@ public class HotspotRuleDescription { if (endIndex == -1) { endIndex = description.length(); } - return new String[] { + return new String[]{ description.substring(0, beginningIndex) + description.substring(endIndex), description.substring(beginningIndex, endIndex) }; } else { - return new String[] {description, ""}; + return new String[]{description, ""}; } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleDescriptionFormatter.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/RuleDescriptionFormatter.java similarity index 100% rename from server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleDescriptionFormatter.java rename to server/sonar-server-common/src/main/java/org/sonar/server/rule/RuleDescriptionFormatter.java diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/HotspotRuleDescriptionTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/HotspotRuleDescriptionTest.java index a5c71d5e72b..f936c385a00 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/HotspotRuleDescriptionTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/HotspotRuleDescriptionTest.java @@ -25,6 +25,7 @@ import com.tngtech.java.junit.dataprovider.UseDataProvider; import org.junit.Test; import org.junit.runner.RunWith; import org.sonar.db.rule.RuleDefinitionDto; +import org.sonar.db.rule.RuleDto; import org.sonar.db.rule.RuleTesting; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; @@ -145,6 +146,43 @@ public class HotspotRuleDescriptionTest { assertThat(result.getFixIt().get()).isEqualTo(RECOMMENTEDCODINGPRACTICE + SEE); } + @Test + public void parse_custom_rule_description() { + String ruleDescription = "This is the custom rule description"; + String exceptionsContent = "This the exceptions section content"; + String askContent = "This is the ask section content"; + String recommendedContent = "This is the recommended section content"; + + RuleDefinitionDto dto = RuleTesting.newRule() + .setTemplateUuid("123") + .setDescriptionFormat(RuleDto.Format.MARKDOWN) + .setDescription( + ruleDescription + "\n" + + "== Exceptions" + "\n" + + exceptionsContent + "\n" + + "== Ask Yourself Whether" + "\n" + + askContent + "\n" + + "== Recommended Secure Coding Practices" + "\n" + + recommendedContent + "\n" + ); + + HotspotRuleDescription result = HotspotRuleDescription.from(dto); + + assertThat(result.getRisk().get()).hasToString( + ruleDescription + "
" + + "

Exceptions

" + + exceptionsContent + "
" + ); + assertThat(result.getVulnerable().get()).hasToString( + "

Ask Yourself Whether

" + + askContent + "
" + ); + assertThat(result.getFixIt().get()).hasToString( + "

Recommended Secure Coding Practices

" + + recommendedContent + "
" + ); + } + /* * Bunch of static constant to create rule description. */ diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java similarity index 100% rename from server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java rename to server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java index 20661d253e0..d05d9d1eaca 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/ShowAction.java @@ -45,7 +45,6 @@ import org.sonar.server.issue.IssueChangeWSSupport.Load; import org.sonar.server.issue.TextRangeResponseFormatter; import org.sonar.server.issue.ws.UserResponseFormatter; import org.sonar.server.rule.HotspotRuleDescription; -import org.sonar.server.rule.RuleDescriptionFormatter; import org.sonar.server.security.SecurityStandards; import org.sonar.server.text.MacroInterpreter; import org.sonarqube.ws.Common; @@ -169,17 +168,10 @@ public class ShowAction implements HotspotsWsAction { .setSecurityCategory(sqCategory.getKey()) .setVulnerabilityProbability(sqCategory.getVulnerability().name()); - if (ruleDefinitionDto.isCustomRule()) { - String htmlDescription = RuleDescriptionFormatter.getDescriptionAsHtml(ruleDefinitionDto); - if (htmlDescription != null) { - ruleBuilder.setRiskDescription(macroInterpreter.interpret(htmlDescription)); - } - } else { - HotspotRuleDescription hotspotRuleDescription = HotspotRuleDescription.from(ruleDefinitionDto); - hotspotRuleDescription.getVulnerable().ifPresent(ruleBuilder::setVulnerabilityDescription); - hotspotRuleDescription.getRisk().ifPresent(ruleBuilder::setRiskDescription); - hotspotRuleDescription.getFixIt().ifPresent(ruleBuilder::setFixRecommendations); - } + HotspotRuleDescription hotspotRuleDescription = HotspotRuleDescription.from(ruleDefinitionDto); + hotspotRuleDescription.getVulnerable().ifPresent(ruleBuilder::setVulnerabilityDescription); + hotspotRuleDescription.getRisk().ifPresent(ruleBuilder::setRiskDescription); + hotspotRuleDescription.getFixIt().ifPresent(ruleBuilder::setFixRecommendations); responseBuilder.setRule(ruleBuilder.build()); } @@ -232,7 +224,7 @@ public class ShowAction implements HotspotsWsAction { boolean hotspotOnProject = Objects.equals(project.uuid(), componentUuid); ComponentDto component = hotspotOnProject ? project : dbClient.componentDao().selectByUuid(dbSession, componentUuid) - .orElseThrow(() -> new NotFoundException(format("Component with uuid '%s' does not exist", componentUuid))); + .orElseThrow(() -> new NotFoundException(format("Component with uuid '%s' does not exist", componentUuid))); return new Components(project, component); } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java index 13ff6d1b162..dfc9a5cfaa5 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/ShowActionTest.java @@ -387,24 +387,20 @@ public class ShowActionTest { userSessionRule.logIn().addProjectPermission(UserRole.USER, project); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); - String description = "
line1\nline2
"; - String parsedDescription = "<div>line1
line2</div>"; - String resultingDescription = "!" + parsedDescription + "!"; + String description = "== Title\n
line1\nline2
"; RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT, r -> r.setTemplateUuid("123") .setDescription(description) .setDescriptionFormat(MARKDOWN)); - doReturn(resultingDescription).when(macroInterpreter).interpret(parsedDescription); - IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file); mockChangelogAndCommentsFormattingContext(); Hotspots.ShowWsResponse response = newRequest(hotspot) .executeProtobuf(Hotspots.ShowWsResponse.class); - assertThat(response.getRule().getRiskDescription()).isEqualTo(resultingDescription); + assertThat(response.getRule().getRiskDescription()).isEqualTo("

Title

<div>line1
line2</div>"); } @Test diff --git a/sonar-markdown/src/main/java/org/sonar/markdown/HtmlHeadingChannel.java b/sonar-markdown/src/main/java/org/sonar/markdown/HtmlHeadingChannel.java index 808e79e0300..fbd1dd71021 100644 --- a/sonar-markdown/src/main/java/org/sonar/markdown/HtmlHeadingChannel.java +++ b/sonar-markdown/src/main/java/org/sonar/markdown/HtmlHeadingChannel.java @@ -71,7 +71,7 @@ public class HtmlHeadingChannel extends RegexChannel { CharSequence headingText = token.subSequence(index, token.length()); output.append(""); - output.append(headingText); + output.append(headingText.toString().trim()); output.append(""); } } diff --git a/sonar-markdown/src/test/java/org/sonar/markdown/MarkdownTest.java b/sonar-markdown/src/test/java/org/sonar/markdown/MarkdownTest.java index 865c2281aeb..553aae54adf 100644 --- a/sonar-markdown/src/test/java/org/sonar/markdown/MarkdownTest.java +++ b/sonar-markdown/src/test/java/org/sonar/markdown/MarkdownTest.java @@ -61,8 +61,8 @@ public class MarkdownTest { @Test public void shouldDecorateHeadings() { - assertThat(Markdown.convertToHtml(" = Top\r== Sub\r\n=== Subsub\n ==== \n 1.five")) - .isEqualTo("

Top\r

Sub\r\n

Subsub\n

1.five"); + assertThat(Markdown.convertToHtml(" = Top\r== Sub\r\n=== Sub sub\n ==== \n 1.five")) + .isEqualTo("

Top

Sub

Sub sub

1.five"); } @Test -- 2.39.5