diff options
author | Aurelien Poscia <aurelien.poscia@sonarsource.com> | 2022-06-24 17:15:42 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-06-30 20:03:09 +0000 |
commit | 923ec14b8ef55af36ff9bc45988b5c8fd51043bd (patch) | |
tree | 83d8796365c514c654de81ebf89e15454a77f7e8 /server/sonar-server-common | |
parent | b2079411492f9c056c92c619d2ccf08e86e88e5c (diff) | |
download | sonarqube-923ec14b8ef55af36ff9bc45988b5c8fd51043bd.tar.gz sonarqube-923ec14b8ef55af36ff9bc45988b5c8fd51043bd.zip |
SONAR-16518 support contextual section descriptions in /api/rules/search and /api/rules/show + adapt ES indexation
SONAR-16518 update api/rules/search, api/rules/show documentation
Update /api/rules/search and /api/rules/show to put change log in change logs entries rather than description
Diffstat (limited to 'server/sonar-server-common')
3 files changed, 37 insertions, 5 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 f3cbffeae39..ad34b1f81d4 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 @@ -26,10 +26,12 @@ import java.util.Objects; import java.util.Optional; import javax.annotation.CheckForNull; import org.sonar.api.rules.RuleType; +import org.sonar.db.rule.RuleDescriptionSectionContextDto; import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.db.rule.RuleDto; import org.sonar.markdown.Markdown; +import static java.util.Comparator.comparing; import static java.util.stream.Collectors.toMap; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ASSESS_THE_PROBLEM_SECTION_KEY; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.HOW_TO_FIX_SECTION_KEY; @@ -76,7 +78,9 @@ public class RuleDescriptionFormatter { return null; } Map<String, String> sectionKeyToHtml = ruleDescriptionSectionDtos.stream() - .collect(toMap(RuleDescriptionSectionDto::getKey, section -> toHtml(descriptionFormat, section))); + //TODO MMF-2765, merge operation on toMap should not be needed anymore + .sorted(comparing(RuleDescriptionSectionDto::getKey).thenComparing(s -> Optional.ofNullable(s.getContext()).map(RuleDescriptionSectionContextDto::getKey).orElse(null))) + .collect(toMap(RuleDescriptionSectionDto::getKey, section -> toHtml(descriptionFormat, section), (k1, k2) -> k1)); if (sectionKeyToHtml.containsKey(DEFAULT_KEY)) { return sectionKeyToHtml.get(DEFAULT_KEY); } else { 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 0a14950681e..8466dfaaa4f 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 @@ -19,8 +19,12 @@ */ package org.sonar.server.rule; +import java.util.Optional; +import org.apache.commons.lang.RandomStringUtils; +import org.jetbrains.annotations.Nullable; import org.junit.Test; import org.sonar.api.rules.RuleType; +import org.sonar.db.rule.RuleDescriptionSectionContextDto; import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.db.rule.RuleDto; @@ -28,6 +32,7 @@ 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.HOW_TO_FIX_SECTION_KEY; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.INTRODUCTION_SECTION_KEY; +import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.RESOURCES_SECTION_KEY; import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ROOT_CAUSE_SECTION_KEY; import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection; @@ -57,15 +62,19 @@ public class RuleDescriptionFormatterTest { var section2 = createRuleDescriptionSection(ASSESS_THE_PROBLEM_SECTION_KEY, "<div>This is not a problem</div>"); var section3 = createRuleDescriptionSection(HOW_TO_FIX_SECTION_KEY, "<div>I don't want to fix</div>"); var section4 = createRuleDescriptionSection(INTRODUCTION_SECTION_KEY, "<div>Introduction with no title</div>"); + var section5ctx1 = createRuleDescriptionSection(RESOURCES_SECTION_KEY, "<div>CTX_1</div>", "CTX_1"); + var section5ctx2 = createRuleDescriptionSection(RESOURCES_SECTION_KEY, "<div>CTX_2</div>", "CTX_2"); RuleDto rule = new RuleDto().setDescriptionFormat(RuleDto.Format.HTML) .setType(RuleType.SECURITY_HOTSPOT) .addRuleDescriptionSectionDto(section1) .addRuleDescriptionSectionDto(section2) .addRuleDescriptionSectionDto(section3) - .addRuleDescriptionSectionDto(section4); + .addRuleDescriptionSectionDto(section4) + .addRuleDescriptionSectionDto(section5ctx2) + .addRuleDescriptionSectionDto(section5ctx1); String html = ruleDescriptionFormatter.getDescriptionAsHtml(rule); assertThat(html) - .contains( + .isEqualTo( "<div>Introduction with no title</div><br/>" + "<h2>What is the risk?</h2>" + "<div>Root is Root</div><br/>" @@ -73,6 +82,7 @@ public class RuleDescriptionFormatterTest { + "<div>This is not a problem</div><br/>" + "<h2>How can you fix it?</h2>" + "<div>I don't want to fix</div><br/>" + + "<div>CTX_1</div><br/>" ); } @@ -92,6 +102,13 @@ public class RuleDescriptionFormatterTest { } private static RuleDescriptionSectionDto createRuleDescriptionSection(String key, String content) { - return RuleDescriptionSectionDto.builder().key(key).content(content).build(); + return createRuleDescriptionSection(key, content, null); + } + + private static RuleDescriptionSectionDto createRuleDescriptionSection(String key, String content, @Nullable String contextKey) { + RuleDescriptionSectionContextDto context = Optional.ofNullable(contextKey) + .map(c -> RuleDescriptionSectionContextDto.of(contextKey, contextKey + RandomStringUtils.randomAlphanumeric(20))) + .orElse(null); + return RuleDescriptionSectionDto.builder().key(key).content(content).context(context).build(); } } diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleDocTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleDocTest.java index 9d5dcf92920..26fa5c76cd4 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleDocTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleDocTest.java @@ -20,6 +20,7 @@ package org.sonar.server.rule.index; import org.junit.Test; +import org.sonar.db.rule.RuleDescriptionSectionContextDto; import org.sonar.db.rule.RuleDescriptionSectionDto; import org.sonar.db.rule.RuleDto; import org.sonar.db.rule.RuleForIndexingDto; @@ -89,8 +90,12 @@ public class RuleDocTest { ruleDto.getRuleDescriptionSectionDtos().clear(); RuleDescriptionSectionDto section1 = buildRuleDescriptionSectionDto("section1", "<p>html content 1</p>"); RuleDescriptionSectionDto section2 = buildRuleDescriptionSectionDto("section2", "<p>html content 2</p>"); + RuleDescriptionSectionDto section3ctx1 = buildRuleDescriptionSectionDtoWithContext("section3", "<p>html content 3.1</p>", "ctx1"); + RuleDescriptionSectionDto section3ctx2 = buildRuleDescriptionSectionDtoWithContext("section3", "<p>html content 3.2</p>", "ctx2"); ruleDto.addRuleDescriptionSectionDto(section1); ruleDto.addRuleDescriptionSectionDto(section2); + ruleDto.addRuleDescriptionSectionDto(section3ctx1); + ruleDto.addRuleDescriptionSectionDto(section3ctx2); RuleForIndexingDto ruleForIndexingDto = RuleForIndexingDto.fromRuleDto(ruleDto); SecurityStandards securityStandards = fromSecurityStandards(ruleDto.getSecurityStandards()); @@ -99,7 +104,9 @@ public class RuleDocTest { assertThat(ruleDoc.htmlDescription()) .contains(section1.getContent()) .contains(section2.getContent()) - .hasSameSizeAs(section1.getContent() + " " + section2.getContent()); + .contains(section3ctx1.getContent()) + .contains(section3ctx2.getContent()) + .hasSameSizeAs(section1.getContent() + " " + section2.getContent() + " " + section3ctx1.getContent() + " " + section3ctx2.getContent()); } @Test @@ -125,4 +132,8 @@ public class RuleDocTest { private static RuleDescriptionSectionDto buildRuleDescriptionSectionDto(String key, String content) { return RuleDescriptionSectionDto.builder().key(key).content(content).build(); } + + private static RuleDescriptionSectionDto buildRuleDescriptionSectionDtoWithContext(String key, String content, String contextKey) { + return RuleDescriptionSectionDto.builder().key(key).content(content).context(RuleDescriptionSectionContextDto.of(contextKey, contextKey)).build(); + } } |