aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/rule/RuleDescriptionFormatter.java8
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java24
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java14
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java3
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java44
5 files changed, 78 insertions, 15 deletions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/RuleDescriptionFormatter.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/RuleDescriptionFormatter.java
index 9492aaa3f1c..da691f81916 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/RuleDescriptionFormatter.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/RuleDescriptionFormatter.java
@@ -23,6 +23,7 @@ import com.google.common.collect.MoreCollectors;
import java.util.Collection;
import java.util.Objects;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import org.sonar.db.rule.RuleDescriptionSectionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.markdown.Markdown;
@@ -41,7 +42,7 @@ public class RuleDescriptionFormatter {
}
@CheckForNull
- private static String retrieveDescription(Collection<RuleDescriptionSectionDto> ruleDescriptionSectionDtos, RuleDto.Format descriptionFormat) {
+ private String retrieveDescription(Collection<RuleDescriptionSectionDto> ruleDescriptionSectionDtos, RuleDto.Format descriptionFormat) {
return ruleDescriptionSectionDtos.stream()
.filter(RuleDescriptionSectionDto::isDefault)
.collect(MoreCollectors.toOptional())
@@ -49,12 +50,11 @@ public class RuleDescriptionFormatter {
.orElse(null);
}
- private static String toHtml(RuleDto.Format descriptionFormat, RuleDescriptionSectionDto ruleDescriptionSectionDto) {
+ public String toHtml(@Nullable RuleDto.Format descriptionFormat, RuleDescriptionSectionDto ruleDescriptionSectionDto) {
if (MARKDOWN.equals(descriptionFormat)) {
return Markdown.convertToHtml(ruleDescriptionSectionDto.getContent());
- } else {
- return ruleDescriptionSectionDto.getContent();
}
+ return ruleDescriptionSectionDto.getContent();
}
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java
index 2268e2e408b..9a061046efe 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/RuleDescriptionFormatterTest.java
@@ -27,7 +27,10 @@ import org.sonar.db.rule.RuleDto;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ASSESS_THE_PROBLEM_SECTION_KEY;
import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ROOT_CAUSE_SECTION_KEY;
+import static org.sonar.db.rule.RuleDescriptionSectionDto.DEFAULT_KEY;
import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection;
+import static org.sonar.db.rule.RuleDto.Format.HTML;
+import static org.sonar.db.rule.RuleDto.Format.MARKDOWN;
public class RuleDescriptionFormatterTest {
@@ -37,7 +40,7 @@ public class RuleDescriptionFormatterTest {
@Test
public void getMarkdownDescriptionAsHtml() {
- RuleDto rule = new RuleDto().setDescriptionFormat(RuleDto.Format.MARKDOWN).addRuleDescriptionSectionDto(MARKDOWN_SECTION).setType(RuleType.BUG);
+ RuleDto rule = new RuleDto().setDescriptionFormat(MARKDOWN).addRuleDescriptionSectionDto(MARKDOWN_SECTION).setType(RuleType.BUG);
String html = ruleDescriptionFormatter.getDescriptionAsHtml(rule);
assertThat(html).isEqualTo("<strong>md</strong> <code>description</code>");
}
@@ -78,6 +81,25 @@ public class RuleDescriptionFormatterTest {
assertThat(result).isNull();
}
+ @Test
+ public void toHtmlWithNullFormat() {
+ RuleDescriptionSectionDto section = createRuleDescriptionSection(DEFAULT_KEY, "whatever");
+ String result = ruleDescriptionFormatter.toHtml(null, section);
+ assertThat(result).isEqualTo(section.getContent());
+ }
+
+ @Test
+ public void toHtmlWithMarkdownFormat() {
+ String result = ruleDescriptionFormatter.toHtml(MARKDOWN, MARKDOWN_SECTION);
+ assertThat(result).isEqualTo("<strong>md</strong> <code>description</code>");
+ }
+
+ @Test
+ public void toHtmlWithHtmlFormat() {
+ String result = ruleDescriptionFormatter.toHtml(HTML, HTML_SECTION);
+ assertThat(result).isEqualTo(HTML_SECTION.getContent());
+ }
+
private static RuleDescriptionSectionDto createRuleDescriptionSection(String key, String content) {
return RuleDescriptionSectionDto.builder().key(key).content(content).build();
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java
index 18c7ff3cfba..e1c09617814 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleMapper.java
@@ -376,18 +376,16 @@ public class RuleMapper {
return ruleDescriptionSectionDtos.size() > 1 && s.isDefault();
}
- private static Rules.Rule.DescriptionSection toDescriptionSection(RuleDto ruleDto, RuleDescriptionSectionDto section) {
+ private Rules.Rule.DescriptionSection toDescriptionSection(RuleDto ruleDto, RuleDescriptionSectionDto section) {
+ String htmlContent = ruleDescriptionFormatter.toHtml(ruleDto.getDescriptionFormat(), section);
+ String interpretedHtmlContent = macroInterpreter.interpret(htmlContent);
+
Rules.Rule.DescriptionSection.Builder sectionBuilder = Rules.Rule.DescriptionSection.newBuilder()
.setKey(section.getKey())
- .setContent(retrieveDescriptionContent(ruleDto.getDescriptionFormat(), section));
+ .setContent(interpretedHtmlContent);
toProtobufContext(section.getContext()).ifPresent(sectionBuilder::setContext);
- return sectionBuilder.build();
- }
- private static String retrieveDescriptionContent(@Nullable RuleDto.Format format, RuleDescriptionSectionDto sectionDto) {
- return MARKDOWN.equals(format) ?
- Markdown.convertToHtml(sectionDto.getContent()) :
- sectionDto.getContent();
+ return sectionBuilder.build();
}
private void setNotesFields(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Map<String, UserDto> usersByUuid, Set<String> fieldsToReturn) {
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java
index 12de1415f02..da911be2d8e 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java
@@ -86,6 +86,7 @@ import static org.assertj.guava.api.Assertions.entry;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import static org.sonar.api.rule.Severity.BLOCKER;
import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.RESOURCES_SECTION_KEY;
import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection;
@@ -463,6 +464,8 @@ public class SearchActionTest {
@Test
public void should_return_specified_fields() {
+ when(macroInterpreter.interpret(anyString())).thenAnswer(invocation -> invocation.getArgument(0));
+
RuleDescriptionSectionDto section1context1 = createRuleDescriptionSectionWithContext(RESOURCES_SECTION_KEY, "<div>I want to fix with Spring</div>", "ctx1");
RuleDescriptionSectionDto section1context2 = createRuleDescriptionSectionWithContext(RESOURCES_SECTION_KEY, "<div>Another context</div>", "ctx2");
RuleDto rule = newRuleWithoutDescriptionSection()
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java
index 0b0dd9fc73f..e8ea3918686 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java
@@ -54,6 +54,7 @@ import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ASSESS_THE_PROBLEM_SECTION_KEY;
@@ -313,7 +314,7 @@ public class ShowActionTest {
assertThat(result.getRule().getHtmlDesc()).isEqualTo(INTERPRETED);
assertThat(result.getRule().getTemplateKey()).isEqualTo(templateRule.getKey().toString());
- verify(macroInterpreter).interpret("&lt;div&gt;line1<br/>line2&lt;/div&gt;");
+ verify(macroInterpreter, times(2)).interpret("&lt;div&gt;line1<br/>line2&lt;/div&gt;");
}
@Test
@@ -395,6 +396,45 @@ public class ShowActionTest {
}
@Test
+ public void show_rule_desc_sections_and_html_desc_with_macro() {
+ RuleDescriptionSectionDto section = createRuleDescriptionSection(DEFAULT_KEY, "<div>Testing macro: {rule:java:S001}</div>");
+ RuleDto rule = createRuleWithDescriptionSections(section);
+ rule.setType(RuleType.SECURITY_HOTSPOT);
+ rule.setNoteUserUuid(userDto.getUuid());
+ db.rules().insert(rule);
+
+ ShowResponse result = ws.newRequest()
+ .setParam(PARAM_KEY, rule.getKey().toString())
+ .executeProtobuf(ShowResponse.class);
+ Rule resultRule = result.getRule();
+
+ assertThat(resultRule.getHtmlDesc()).isEqualTo(INTERPRETED);
+ assertThat(resultRule.getDescriptionSections().getDescriptionSectionsList())
+ .extracting(Rule.DescriptionSection::getKey, Rule.DescriptionSection::getContent)
+ .containsExactly(tuple(DEFAULT_KEY, INTERPRETED));
+ }
+
+ @Test
+ public void show_rule_desc_sections_and_markdown_desc_with_macro() {
+ RuleDescriptionSectionDto section = createRuleDescriptionSection(DEFAULT_KEY, "Testing macro: {rule:java:S001}");
+ RuleDto rule = createRuleWithDescriptionSections(section);
+ rule.setDescriptionFormat(MARKDOWN);
+ rule.setType(RuleType.SECURITY_HOTSPOT);
+ rule.setNoteUserUuid(userDto.getUuid());
+ db.rules().insert(rule);
+
+ ShowResponse result = ws.newRequest()
+ .setParam(PARAM_KEY, rule.getKey().toString())
+ .executeProtobuf(ShowResponse.class);
+ Rule resultRule = result.getRule();
+
+ assertThat(resultRule.getHtmlDesc()).isEqualTo(INTERPRETED);
+ assertThat(resultRule.getDescriptionSections().getDescriptionSectionsList())
+ .extracting(Rule.DescriptionSection::getKey, Rule.DescriptionSection::getContent)
+ .containsExactly(tuple(DEFAULT_KEY, INTERPRETED));
+ }
+
+ @Test
public void show_if_advanced_sections_and_default_filters_out_default() {
when(macroInterpreter.interpret(anyString())).thenAnswer(invocation -> invocation.getArgument(0));
@@ -424,7 +464,7 @@ public class ShowActionTest {
public void show_rule_markdown_description() {
when(macroInterpreter.interpret(anyString())).thenAnswer(invocation -> invocation.getArgument(0));
- var section = createRuleDescriptionSection("default", "*toto is toto*");
+ var section = createRuleDescriptionSection(DEFAULT_KEY, "*toto is toto*");
RuleDto rule = createRuleWithDescriptionSections(section);
rule.setDescriptionFormat(MARKDOWN);