import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.HashSet;
-import java.util.Optional;
import java.util.Set;
import javax.annotation.CheckForNull;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rules.RuleType;
-import static org.sonar.db.rule.RuleDescriptionSectionDto.DEFAULT_KEY;
-
public class RuleForIndexingDto {
private String uuid;
this.ruleDescriptionSectionsDtos = ruleDescriptionSectionsDtos;
}
- private Optional<RuleDescriptionSectionDto> findExistingSectionWithSameKey(String ruleDescriptionSectionKey) {
- return ruleDescriptionSectionsDtos.stream().filter(section -> section.getKey().equals(ruleDescriptionSectionKey)).findAny();
- }
-
- @CheckForNull
- public RuleDescriptionSectionDto getDefaultRuleDescriptionSectionDto() {
- return findExistingSectionWithSameKey(DEFAULT_KEY).orElse(null);
- }
-
public void setTemplateRuleKey(String templateRuleKey) {
this.templateRuleKey = templateRuleKey;
}
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.db.rule.RuleDto;
-import org.sonar.db.rule.RuleForIndexingDto;
import static java.util.Optional.ofNullable;
return from(description);
}
- public static HotspotRuleDescription from(RuleForIndexingDto dto) {
- return from(RuleDescriptionFormatter.getDescriptionAsHtml(dto));
- }
-
private static HotspotRuleDescription from(@Nullable String description) {
if (description == null) {
return NO_DESCRIPTION;
import java.util.Optional;
import org.sonar.db.rule.RuleDescriptionSectionDto;
import org.sonar.db.rule.RuleDto;
-import org.sonar.db.rule.RuleForIndexingDto;
import org.sonar.markdown.Markdown;
import static com.google.common.collect.MoreCollectors.toOptional;
return retrieveDescription(ruleDescriptionSectionDtos, ruleDto.getRuleKey(), Objects.requireNonNull(ruleDto.getDescriptionFormat()));
}
- public static String getDescriptionAsHtml(RuleForIndexingDto ruleForIndexingDto) {
- if (ruleForIndexingDto.getDescriptionFormat() == null) {
- return null;
- }
- Collection<RuleDescriptionSectionDto> ruleDescriptionSectionDtos = ruleForIndexingDto.getRuleDescriptionSectionsDtos();
- return retrieveDescription(ruleDescriptionSectionDtos, ruleForIndexingDto.getRuleKey().toString(), ruleForIndexingDto.getDescriptionFormat());
- }
-
private static String retrieveDescription(Collection<RuleDescriptionSectionDto> ruleDescriptionSectionDtos,
String ruleKey, RuleDto.Format descriptionFormat) {
Optional<RuleDescriptionSectionDto> ruleDescriptionSectionDto = findDefaultDescription(ruleDescriptionSectionDtos);
.orElse(null);
}
-
private static Optional<RuleDescriptionSectionDto> findDefaultDescription(Collection<RuleDescriptionSectionDto> ruleDescriptionSectionDtos) {
return ruleDescriptionSectionDtos.stream()
.filter(RuleDescriptionSectionDto::isDefault)
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rules.RuleType;
+import org.sonar.db.rule.RuleDescriptionSectionDto;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleForIndexingDto;
import org.sonar.markdown.Markdown;
import org.sonar.server.es.BaseDoc;
-import org.sonar.server.rule.RuleDescriptionFormatter;
import org.sonar.server.security.SecurityStandards;
import org.sonar.server.security.SecurityStandards.SQCategory;
+import static java.util.stream.Collectors.joining;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;
/**
@CheckForNull
public RuleType type() {
- return RuleType.valueOfNullable(getNullableField(RuleIndexDefinition.FIELD_RULE_TYPE));
+ String type = getNullableField(RuleIndexDefinition.FIELD_RULE_TYPE);
+ if (type == null) {
+ return null;
+ }
+ return RuleType.valueOf(type);
}
public RuleDoc setType(@Nullable RuleType ruleType) {
}
public static RuleDoc of(RuleForIndexingDto dto, SecurityStandards securityStandards) {
- RuleDoc ruleDoc = new RuleDoc()
+ return new RuleDoc()
.setUuid(dto.getUuid())
.setKey(dto.getRuleKey().toString())
.setRepository(dto.getRepository())
.setType(dto.getTypeAsRuleType())
.setCreatedAt(dto.getCreatedAt())
.setTags(Sets.union(dto.getTags(), dto.getSystemTags()))
- .setUpdatedAt(dto.getUpdatedAt());
+ .setUpdatedAt(dto.getUpdatedAt())
+ .setHtmlDescription(getConcatenatedSectionsInHtml(dto))
+ .setTemplateKey(getRuleKey(dto));
+ }
+ @CheckForNull
+ private static String getRuleKey(RuleForIndexingDto dto) {
if (dto.getTemplateRuleKey() != null && dto.getTemplateRepository() != null) {
- ruleDoc.setTemplateKey(RuleKey.of(dto.getTemplateRepository(), dto.getTemplateRuleKey()).toString());
- } else {
- ruleDoc.setTemplateKey(null);
+ return RuleKey.of(dto.getTemplateRepository(), dto.getTemplateRuleKey()).toString();
}
+ return null;
+ }
- String descriptionAsHtml = RuleDescriptionFormatter.getDescriptionAsHtml(dto);
- ruleDoc.setHtmlDescription(descriptionAsHtml);
- return ruleDoc;
+ private static String getConcatenatedSectionsInHtml(RuleForIndexingDto dto) {
+ return dto.getRuleDescriptionSectionsDtos().stream()
+ .map(RuleDescriptionSectionDto::getContent)
+ .map(content -> convertToHtmlIfNecessary(dto.getDescriptionFormat(), content))
+ .collect(joining(" "));
+ }
+
+ private static String convertToHtmlIfNecessary(RuleDto.Format format, String content) {
+ if (RuleDto.Format.MARKDOWN.equals(format)) {
+ return Markdown.convertToHtml(content);
+ }
+ return content;
}
}
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
-import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.server.es.IndexingResult;
import org.sonar.server.es.OneToOneResilientIndexingListener;
import org.sonar.server.es.ResilientIndexer;
-import org.sonar.server.rule.HotspotRuleDescription;
import org.sonar.server.security.SecurityStandards;
import static java.util.Arrays.asList;
.sorted(SQ_CATEGORY_KEYS_ORDERING)
.collect(joining(", ")));
}
- if (dto.getTypeAsRuleType() == RuleType.SECURITY_HOTSPOT) {
- HotspotRuleDescription ruleDescription = HotspotRuleDescription.from(dto);
- if (!ruleDescription.isComplete()) {
- LOG.debug(
- "Description of Security Hotspot Rule {} can't be fully parsed: What is the risk?={}, Are you vulnerable?={}, How to fix it={}",
- dto.getRuleKey(),
- toOkMissing(ruleDescription.getRisk()), toOkMissing(ruleDescription.getVulnerable()),
- toOkMissing(ruleDescription.getFixIt()));
- }
- }
return RuleDoc.of(dto, securityStandards);
}
- private static String toOkMissing(Optional<String> field) {
- return field.map(t -> "ok").orElse("missing");
- }
private BulkIndexer createBulkIndexer(Size bulkSize, IndexingListener listener) {
return new BulkIndexer(esClient, TYPE_RULE, bulkSize, listener);
*/
package org.sonar.server.rule;
-import com.google.common.collect.Sets;
-import java.util.Collections;
-import java.util.Set;
-import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import org.sonar.db.rule.RuleDescriptionSectionDto;
import org.sonar.db.rule.RuleDto;
-import org.sonar.db.rule.RuleForIndexingDto;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection;
assertThat(result).isNull();
}
- @Test
- public void getHtmlDescriptionForRuleForIndexingDtoAsIs() {
- Set<RuleDescriptionSectionDto> sectionsDtos = Sets.newHashSet(
- createDefaultRuleDescriptionSection("uuid", HTML_SECTION.getContent()));
- RuleForIndexingDto rule = createRuleForIndexingDto(sectionsDtos, RuleDto.Format.HTML);
- String html = RuleDescriptionFormatter.getDescriptionAsHtml(rule);
- assertThat(html).isEqualTo(HTML_SECTION.getContent());
- }
-
- @Test
- public void handleEmptyDescriptionForRuleForIndexingDto() {
- RuleForIndexingDto rule = createRuleForIndexingDto(Collections.emptySet(), RuleDto.Format.HTML);
- String result = RuleDescriptionFormatter.getDescriptionAsHtml(rule);
- assertThat(result).isNull();
- }
-
- @Test
- public void handleNullDescriptionFormatForRuleForIndexingDto() {
- Set<RuleDescriptionSectionDto> sectionsDtos = Sets.newHashSet(
- createDefaultRuleDescriptionSection("uuid", HTML_SECTION.getContent()));
- RuleForIndexingDto rule = createRuleForIndexingDto(sectionsDtos, null);
- String result = RuleDescriptionFormatter.getDescriptionAsHtml(rule);
- assertThat(result).isNull();
- }
-
- @NotNull
- private static RuleForIndexingDto createRuleForIndexingDto(Set<RuleDescriptionSectionDto> sectionsDtos, RuleDto.Format format) {
- RuleForIndexingDto rule = new RuleForIndexingDto();
- rule.setRuleDescriptionSectionsDtos(sectionsDtos);
- rule.setDescriptionFormat(format);
- rule.setRepository("repository");
- rule.setPluginRuleKey("pluginKey");
- return rule;
- }
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.rule.index;
+
+import org.junit.Test;
+import org.sonar.db.rule.RuleDescriptionSectionDto;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleForIndexingDto;
+import org.sonar.db.rule.RuleTesting;
+import org.sonar.server.security.SecurityStandards;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.markdown.Markdown.convertToHtml;
+import static org.sonar.server.security.SecurityStandards.fromSecurityStandards;
+
+public class RuleDocTest {
+
+ @Test
+ public void ruleDocOf_mapsFieldCorrectly() {
+ RuleDto ruleDto = RuleTesting.newRule();
+ RuleForIndexingDto ruleForIndexingDto = RuleForIndexingDto.fromRuleDto(ruleDto);
+ ruleForIndexingDto.setTemplateRuleKey("templateKey");
+ ruleForIndexingDto.setTemplateRepository("repoKey");
+ SecurityStandards securityStandards = fromSecurityStandards(ruleDto.getSecurityStandards());
+
+ RuleDoc ruleDoc = RuleDoc.of(ruleForIndexingDto, securityStandards);
+
+ assertThat(ruleDoc.getId()).isEqualTo(ruleDto.getUuid());
+ assertThat(ruleDoc.key()).isEqualTo(ruleForIndexingDto.getRuleKey());
+ assertThat(ruleDoc.repository()).isEqualTo(ruleForIndexingDto.getRepository());
+ assertThat(ruleDoc.internalKey()).isEqualTo(ruleForIndexingDto.getInternalKey());
+ assertThat(ruleDoc.isExternal()).isEqualTo(ruleForIndexingDto.isExternal());
+ assertThat(ruleDoc.language()).isEqualTo(ruleForIndexingDto.getLanguage());
+ assertThat(ruleDoc.getCwe()).isEqualTo(securityStandards.getCwe());
+ assertThat(ruleDoc.getOwaspTop10()).isEqualTo(securityStandards.getOwaspTop10());
+ assertThat(ruleDoc.getOwaspTop10For2021()).isEqualTo(securityStandards.getOwaspTop10For2021());
+ assertThat(ruleDoc.getSansTop25()).isEqualTo(securityStandards.getSansTop25());
+ assertThat(ruleDoc.getSonarSourceSecurityCategory()).isEqualTo(securityStandards.getSqCategory());
+ assertThat(ruleDoc.name()).isEqualTo(ruleForIndexingDto.getName());
+ assertThat(ruleDoc.ruleKey()).isEqualTo(ruleForIndexingDto.getPluginRuleKey());
+ assertThat(ruleDoc.severity()).isEqualTo(ruleForIndexingDto.getSeverityAsString());
+ assertThat(ruleDoc.status()).isEqualTo(ruleForIndexingDto.getStatus());
+ assertThat(ruleDoc.type().name()).isEqualTo(ruleForIndexingDto.getTypeAsRuleType().name());
+ assertThat(ruleDoc.createdAt()).isEqualTo(ruleForIndexingDto.getCreatedAt());
+ assertThat(ruleDoc.getTags()).isEqualTo(ruleForIndexingDto.getSystemTags());
+ assertThat(ruleDoc.updatedAt()).isEqualTo(ruleForIndexingDto.getUpdatedAt());
+ assertThat(ruleDoc.templateKey().repository()).isEqualTo(ruleForIndexingDto.getTemplateRepository());
+ assertThat(ruleDoc.templateKey().rule()).isEqualTo(ruleForIndexingDto.getTemplateRuleKey());
+
+ }
+
+ @Test
+ public void ruleDocOf_whenGivenNoHtmlSections_hasEmptyStringInHtmlDescription() {
+ RuleDto ruleDto = RuleTesting.newRule();
+ ruleDto.setDescriptionFormat(RuleDto.Format.HTML);
+ ruleDto.getRuleDescriptionSectionDtos().clear();
+
+ RuleForIndexingDto ruleForIndexingDto = RuleForIndexingDto.fromRuleDto(ruleDto);
+ SecurityStandards securityStandards = fromSecurityStandards(ruleDto.getSecurityStandards());
+
+ RuleDoc ruleDoc = RuleDoc.of(ruleForIndexingDto, securityStandards);
+ assertThat(ruleDoc.htmlDescription()).isEmpty();
+ }
+
+ @Test
+ public void ruleDocOf_whenGivenMultipleHtmlSections_hasConcatenationInHtmlDescription() {
+ RuleDto ruleDto = RuleTesting.newRule();
+ ruleDto.setDescriptionFormat(RuleDto.Format.HTML);
+ ruleDto.getRuleDescriptionSectionDtos().clear();
+ RuleDescriptionSectionDto section1 = buildRuleDescriptionSectionDto("section1", "<p>html content 1</p>");
+ RuleDescriptionSectionDto section2 = buildRuleDescriptionSectionDto("section2", "<p>html content 2</p>");
+ ruleDto.addRuleDescriptionSectionDto(section1);
+ ruleDto.addRuleDescriptionSectionDto(section2);
+
+ RuleForIndexingDto ruleForIndexingDto = RuleForIndexingDto.fromRuleDto(ruleDto);
+ SecurityStandards securityStandards = fromSecurityStandards(ruleDto.getSecurityStandards());
+
+ RuleDoc ruleDoc = RuleDoc.of(ruleForIndexingDto, securityStandards);
+ assertThat(ruleDoc.htmlDescription())
+ .contains(section1.getContent())
+ .contains(section2.getContent())
+ .hasSameSizeAs(section1.getContent() + " " + section2.getContent());
+ }
+
+ @Test
+ public void ruleDocOf_whenGivenMultipleMarkdownSections_transformToHtmlAndConcatenatesInHtmlDescription() {
+ RuleDto ruleDto = RuleTesting.newRule();
+ ruleDto.setDescriptionFormat(RuleDto.Format.MARKDOWN);
+ ruleDto.getRuleDescriptionSectionDtos().clear();
+ RuleDescriptionSectionDto section1 = buildRuleDescriptionSectionDto("section1", "*html content 1*");
+ RuleDescriptionSectionDto section2 = buildRuleDescriptionSectionDto("section2", "*html content 2*");
+ ruleDto.addRuleDescriptionSectionDto(section1);
+ ruleDto.addRuleDescriptionSectionDto(section2);
+
+ RuleForIndexingDto ruleForIndexingDto = RuleForIndexingDto.fromRuleDto(ruleDto);
+ SecurityStandards securityStandards = fromSecurityStandards(ruleDto.getSecurityStandards());
+
+ RuleDoc ruleDoc = RuleDoc.of(ruleForIndexingDto, securityStandards);
+ assertThat(ruleDoc.htmlDescription())
+ .contains(convertToHtml(section1.getContent()))
+ .contains(convertToHtml(section2.getContent()))
+ .hasSameSizeAs(convertToHtml(section1.getContent()) + " " + convertToHtml(section2.getContent()));
+ }
+
+ private static RuleDescriptionSectionDto buildRuleDescriptionSectionDto(String key, String content) {
+ return RuleDescriptionSectionDto.builder().key(key).content(content).build();
+ }
+}
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.util.EnumSet;
+import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.stream.IntStream;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toSet;
-import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;
private static final UuidFactoryFast uuidFactory = UuidFactoryFast.getInstance();
private static final RuleDescriptionSectionDto RULE_DESCRIPTION_SECTION_DTO = createDefaultRuleDescriptionSection(uuidFactory.create(), VALID_HOTSPOT_RULE_DESCRIPTION);
+ private static final RuleDescriptionSectionDto RULE_DESCRIPTION_SECTION_DTO2 = RuleDescriptionSectionDto.builder()
+ .uuid(uuidFactory.create())
+ .key("section2")
+ .content("rule descriptions section 2")
+ .build();
@Rule
public EsTester es = EsTester.create();
assertThat(es.countDocuments(TYPE_RULE)).isOne();
}
+ @Test
+ public void index_long_rule_with_several_sections() {
+ RuleDto rule = dbTester.rules().insert(r -> {
+ r.addOrReplaceRuleDescriptionSectionDto(RULE_DESCRIPTION_SECTION_DTO);
+ r.addRuleDescriptionSectionDto(RULE_DESCRIPTION_SECTION_DTO2);
+ });
+
+ underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
+
+ List<RuleDoc> ruleDocs = es.getDocuments(TYPE_RULE, RuleDoc.class);
+ assertThat(ruleDocs).hasSize(1);
+ assertThat(ruleDocs.iterator().next().htmlDescription())
+ .isEqualTo(RULE_DESCRIPTION_SECTION_DTO.getContent() + " " + RULE_DESCRIPTION_SECTION_DTO2.getContent());
+ }
+
+ @Test
+ public void index_long_rule_with_section_in_markdown() {
+ RuleDto rule = dbTester.rules().insert(r -> {
+ r.setDescriptionFormat(RuleDto.Format.MARKDOWN);
+ r.addOrReplaceRuleDescriptionSectionDto(RULE_DESCRIPTION_SECTION_DTO);
+ });
+
+ underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
+
+ List<RuleDoc> ruleDocs = es.getDocuments(TYPE_RULE, RuleDoc.class);
+ assertThat(ruleDocs).hasSize(1);
+ assertThat(ruleDocs.iterator().next().htmlDescription())
+ .isEqualTo("acme<br/><h2>Ask Yourself Whether</h2><br/>bar<br/>"
+ + "<h2>Recommended Secure Coding Practices</h2><br/>foo");
+ }
+
@Test
@UseDataProvider("twoDifferentCategoriesButOTHERS")
public void log_debug_if_hotspot_rule_maps_to_multiple_SQCategories(SQCategory sqCategory1, SQCategory sqCategory2) {
};
}
- @Test
- public void log_debug_when_hotspot_rule_no_description () {
- RuleDto rule = dbTester.rules().insert(RuleTesting.newRuleWithoutDescriptionSection()
- .setType(RuleType.SECURITY_HOTSPOT));
- underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
-
- assertThat(logTester.getLogs()).hasSize(1);
- assertThat(logTester.logs(LoggerLevel.DEBUG).get(0))
- .isEqualTo(format(
- "Description of Security Hotspot Rule %s can't be fully parsed: What is the risk?=missing, Are you vulnerable?=missing, How to fix it=missing",
- rule.getKey()));
- }
-
- @Test
- public void log_debug_when_hotspot_rule_description_has_none_of_the_key_titles() {
- RuleDto rule = dbTester.rules().insert(RuleTesting.newRuleWithoutDescriptionSection()
- .setType(RuleType.SECURITY_HOTSPOT)
- .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), randomAlphabetic(30))));
- underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
-
- assertThat(logTester.getLogs()).hasSize(1);
- assertThat(logTester.logs(LoggerLevel.DEBUG).get(0))
- .isEqualTo(format(
- "Description of Security Hotspot Rule %s can't be fully parsed: What is the risk?=ok, Are you vulnerable?=missing, How to fix it=missing",
- rule.getKey()));
- }
-
- @Test
- public void log_debug_when_hotspot_rule_description_is_missing_fixIt_tab_content() {
- RuleDto rule = dbTester.rules().insert(RuleTesting.newRuleWithoutDescriptionSection()
- .setType(RuleType.SECURITY_HOTSPOT)
- .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "bar\n" +
- "<h2>Ask Yourself Whether</h2>\n" +
- "foo")));
- underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
-
- assertThat(logTester.getLogs()).hasSize(1);
- assertThat(logTester.logs(LoggerLevel.DEBUG).get(0))
- .isEqualTo(format(
- "Description of Security Hotspot Rule %s can't be fully parsed: What is the risk?=ok, Are you vulnerable?=ok, How to fix it=missing",
- rule.getKey()));
- }
-
- @Test
- public void log_debug_when_hotspot_rule_description_is_missing_risk_tab_content() {
- RuleDto rule = dbTester.rules().insert(RuleTesting.newRuleWithoutDescriptionSection()
- .setType(RuleType.SECURITY_HOTSPOT)
- .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "<h2>Ask Yourself Whether</h2>\n" +
- "bar\n" +
- "<h2>Recommended Secure Coding Practices</h2>\n" +
- "foo")));
- underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
-
- assertThat(logTester.getLogs()).hasSize(1);
- assertThat(logTester.logs(LoggerLevel.DEBUG).get(0))
- .isEqualTo(format(
- "Description of Security Hotspot Rule %s can't be fully parsed: What is the risk?=missing, Are you vulnerable?=ok, How to fix it=ok",
- rule.getKey()));
- }
-
- @Test
- public void log_debug_when_hotspot_rule_description_is_missing_vulnerable_tab_content() {
- RuleDto rule = dbTester.rules().insert(RuleTesting.newRuleWithoutDescriptionSection()
- .setType(RuleType.SECURITY_HOTSPOT)
- .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "bar\n" +
- "<h2>Recommended Secure Coding Practices</h2>\n" +
- "foo")));
- underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
-
- assertThat(logTester.getLogs()).hasSize(1);
- assertThat(logTester.logs(LoggerLevel.DEBUG).get(0))
- .isEqualTo(format(
- "Description of Security Hotspot Rule %s can't be fully parsed: What is the risk?=ok, Are you vulnerable?=missing, How to fix it=ok",
- rule.getKey()));
- }
}