@@ -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, ""}; | |||
} | |||
} |
@@ -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 + "<br/>" | |||
+ "<h2>Exceptions</h2>" | |||
+ exceptionsContent + "<br/>" | |||
); | |||
assertThat(result.getVulnerable().get()).hasToString( | |||
"<h2>Ask Yourself Whether</h2>" | |||
+ askContent + "<br/>" | |||
); | |||
assertThat(result.getFixIt().get()).hasToString( | |||
"<h2>Recommended Secure Coding Practices</h2>" | |||
+ recommendedContent + "<br/>" | |||
); | |||
} | |||
/* | |||
* Bunch of static constant to create rule description. | |||
*/ |
@@ -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); | |||
} |
@@ -387,24 +387,20 @@ public class ShowActionTest { | |||
userSessionRule.logIn().addProjectPermission(UserRole.USER, project); | |||
ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); | |||
String description = "<div>line1\nline2</div>"; | |||
String parsedDescription = "<div>line1<br/>line2</div>"; | |||
String resultingDescription = "!" + parsedDescription + "!"; | |||
String description = "== Title\n<div>line1\nline2</div>"; | |||
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("<h2>Title</h2><div>line1<br/>line2</div>"); | |||
} | |||
@Test |
@@ -71,7 +71,7 @@ public class HtmlHeadingChannel extends RegexChannel<MarkdownOutput> { | |||
CharSequence headingText = token.subSequence(index, token.length()); | |||
output.append("<h" + headingLevel + ">"); | |||
output.append(headingText); | |||
output.append(headingText.toString().trim()); | |||
output.append("</h" + headingLevel + ">"); | |||
} | |||
} |
@@ -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("<h1>Top\r</h1><h2>Sub\r\n</h2><h3>Subsub\n</h3><h4></h4> 1.five"); | |||
assertThat(Markdown.convertToHtml(" = Top\r== Sub\r\n=== Sub sub\n ==== \n 1.five")) | |||
.isEqualTo("<h1>Top</h1><h2>Sub</h2><h3>Sub sub</h3><h4></h4> 1.five"); | |||
} | |||
@Test |