--- /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.db.rule;
+
+import java.util.Objects;
+
+import static org.apache.commons.lang.StringUtils.isNotEmpty;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+
+public class RuleDescriptionSectionContextDto {
+
+ static final String KEY_MUST_BE_SET_ERROR = "key must be set";
+ static final String DISPLAY_NAME_MUST_BE_SET_ERROR = "displayName must be set";
+ private final String key;
+ private final String displayName;
+
+ private RuleDescriptionSectionContextDto(String key, String displayName) {
+ checkArgument(isNotEmpty(key), KEY_MUST_BE_SET_ERROR);
+ checkArgument(isNotEmpty(displayName), DISPLAY_NAME_MUST_BE_SET_ERROR);
+ this.key = key;
+ this.displayName = displayName;
+ }
+
+ public static RuleDescriptionSectionContextDto of(String key, String displayName) {
+ return new RuleDescriptionSectionContextDto(key, displayName);
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ RuleDescriptionSectionContextDto that = (RuleDescriptionSectionContextDto) o;
+ return getKey().equals(that.getKey()) && getDisplayName().equals(that.getDisplayName());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getKey(), getDisplayName());
+ }
+
+ @Override
+ public String toString() {
+ return "RuleDescriptionSectionContextDto[" +
+ "key='" + key + '\'' +
+ ", displayName='" + displayName + '\'' +
+ ']';
+ }
+}
package org.sonar.db.rule;
import java.util.StringJoiner;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import static org.sonar.api.utils.Preconditions.checkArgument;
public class RuleDescriptionSectionDto {
public static final String DEFAULT_KEY = "default";
- private final String uuid;
- private final String key;
- private final String content;
+ private String uuid;
+ private String key;
+ private String content;
+ private RuleDescriptionSectionContextDto context;
- private RuleDescriptionSectionDto(String uuid, String key, String content) {
+ private RuleDescriptionSectionDto() {
+ }
+
+ private RuleDescriptionSectionDto(String uuid, String key, String content, @Nullable RuleDescriptionSectionContextDto context) {
this.uuid = uuid;
this.key = key;
this.content = content;
+ this.context = context;
}
public String getUuid() {
return content;
}
+ @CheckForNull
+ public RuleDescriptionSectionContextDto getContext() {
+ return context;
+ }
+
public static RuleDescriptionSectionDto createDefaultRuleDescriptionSection(String uuid, String description) {
return RuleDescriptionSectionDto.builder()
.setDefault()
.add("uuid='" + uuid + "'")
.add("key='" + key + "'")
.add("content='" + content + "'")
+ .add("context='" + context + "'")
.toString();
}
+
+
public static final class RuleDescriptionSectionDtoBuilder {
private String uuid;
private String key = null;
private String content;
+ private RuleDescriptionSectionContextDto context;
private RuleDescriptionSectionDtoBuilder() {
}
return this;
}
+ public RuleDescriptionSectionDtoBuilder context(@Nullable RuleDescriptionSectionContextDto context) {
+ this.context = context;
+ return this;
+ }
+
public RuleDescriptionSectionDto build() {
- return new RuleDescriptionSectionDto(uuid, key, content);
+ return new RuleDescriptionSectionDto(uuid, key, content, context);
}
}
+
}
*/
package org.sonar.db.rule;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
+import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Collections.emptySet;
+import static java.util.Optional.ofNullable;
import static org.sonar.db.rule.RuleDescriptionSectionDto.DEFAULT_KEY;
public class RuleDto {
+ static final String ERROR_MESSAGE_SECTION_ALREADY_EXISTS = "A section with key '%s' and context key '%s' already exists";
+
public enum Format {
HTML, MARKDOWN
}
private String repositoryKey = null;
private String ruleKey = null;
- private Set<RuleDescriptionSectionDto> ruleDescriptionSectionDtos = new HashSet<>();
+ private final Set<RuleDescriptionSectionDto> ruleDescriptionSectionDtos = new HashSet<>();
/**
* Description format can be null on external rule, otherwise it should never be null
@CheckForNull
public RuleDescriptionSectionDto getDefaultRuleDescriptionSection() {
- return findExistingSectionWithSameKey(DEFAULT_KEY).orElse(null);
+ return ruleDescriptionSectionDtos.stream()
+ .filter(ruleDesc -> ruleDesc.getKey().equals(DEFAULT_KEY))
+ .findAny()
+ .orElse(null);
}
public RuleDto replaceRuleDescriptionSectionDtos(Collection<RuleDescriptionSectionDto> ruleDescriptionSectionDtos) {
return this;
}
+ @VisibleForTesting
+ public RuleDto replaceRuleDescriptionSectionDtos(RuleDescriptionSectionDto ruleDescriptionSectionDto) {
+ replaceRuleDescriptionSectionDtos(List.of(ruleDescriptionSectionDto));
+ return this;
+ }
+
public RuleDto addRuleDescriptionSectionDto(RuleDescriptionSectionDto ruleDescriptionSectionDto) {
- checkArgument(sectionWithSameKeyShouldNotExist(ruleDescriptionSectionDto),
- "A section with key %s already exists", ruleDescriptionSectionDto.getKey());
+ checkArgument(!hasDescriptionSectionWithSameKeyAndContext(ruleDescriptionSectionDto),
+ ERROR_MESSAGE_SECTION_ALREADY_EXISTS, ruleDescriptionSectionDto.getKey(),
+ Optional.ofNullable(ruleDescriptionSectionDto.getContext()).map(RuleDescriptionSectionContextDto::getKey).orElse(null));
ruleDescriptionSectionDtos.add(ruleDescriptionSectionDto);
return this;
}
- private boolean sectionWithSameKeyShouldNotExist(RuleDescriptionSectionDto ruleDescriptionSectionDto) {
- return findExistingSectionWithSameKey(ruleDescriptionSectionDto.getKey()).isEmpty();
+ private boolean hasDescriptionSectionWithSameKeyAndContext(RuleDescriptionSectionDto ruleDescriptionSectionDto) {
+ return ruleDescriptionSectionDtos.stream()
+ .anyMatch(ruleDesc -> hasSameKeyAndContextKey(ruleDescriptionSectionDto, ruleDesc));
}
- public RuleDto addOrReplaceRuleDescriptionSectionDto(RuleDescriptionSectionDto ruleDescriptionSectionDto) {
- Optional<RuleDescriptionSectionDto> existingSectionWithSameKey = findExistingSectionWithSameKey(ruleDescriptionSectionDto.getKey());
- existingSectionWithSameKey.ifPresent(ruleDescriptionSectionDtos::remove);
- ruleDescriptionSectionDtos.add(ruleDescriptionSectionDto);
- return this;
- }
+ private static boolean hasSameKeyAndContextKey(RuleDescriptionSectionDto ruleDescriptionSectionDto, RuleDescriptionSectionDto other) {
+ if (!ruleDescriptionSectionDto.getKey().equals(other.getKey())){
+ return false;
+ }
- private Optional<RuleDescriptionSectionDto> findExistingSectionWithSameKey(String ruleDescriptionSectionKey) {
- return ruleDescriptionSectionDtos.stream().filter(section -> section.getKey().equals(ruleDescriptionSectionKey)).findAny();
+ String contextKey = ofNullable(ruleDescriptionSectionDto.getContext()).map(RuleDescriptionSectionContextDto::getKey).orElse(null);
+ String otherContextKey = ofNullable(other.getContext()).map(RuleDescriptionSectionContextDto::getKey).orElse(null);
+ return Objects.equals(contextKey, otherContextKey);
}
@CheckForNull
rds.content as "rds_content",
rds.uuid as "rds_uuid",
rds.kee as "rds_kee",
+ rds.context_key as "rds_contextKey",
+ rds.context_display_name as "rds_contextDisplayName",
r.uuid as "r_uuid",
<include refid="ruleColumns"/>
<collection property="ruleDescriptionSectionDtos" ofType="org.sonar.db.rule.RuleDescriptionSectionDto" autoMapping="true"
columnPrefix="rds_">
+ <id property="uuid" column="uuid"/>
<result property="key" column="kee"/>
+ <association property="context" javaType="org.sonar.db.rule.RuleDescriptionSectionContextDto" autoMapping="false">
+ <constructor>
+ <arg column="contextKey" javaType="String"/>
+ <arg column="contextDisplayName" javaType="String"/>
+ </constructor>
+ </association>
</collection>
</resultMap>
<foreach collection="languages" item="language" separator="," open="(" close=")">#{language, jdbcType=VARCHAR}</foreach>
</select>
- <select id="selectByLanguage" parameterType="String" resultType="org.sonar.db.rule.RuleDto" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
+ <select id="selectByLanguage" parameterType="String" resultType="org.sonar.db.rule.RuleDto" fetchSize="${_scrollFetchSize}"
+ resultSetType="FORWARD_ONLY">
select
r.uuid as uuid,
<include refid="ruleColumns"/>
uuid,
rule_uuid,
kee,
- content
+ content,
+ context_key,
+ context_display_name
)
values (
#{dto.uuid,jdbcType=VARCHAR},
#{ruleUuid,jdbcType=VARCHAR},
#{dto.key,jdbcType=VARCHAR},
- #{dto.content,jdbcType=VARCHAR}
+ #{dto.content,jdbcType=VARCHAR},
+ #{dto.context.key,jdbcType=VARCHAR},
+ #{dto.context.displayName,jdbcType=VARCHAR}
)
</insert>
}
-
@Test
public void selectByUuid() {
RuleDto ruleDto = db.rules().insert();
}
private void assertEquals(RuleDto actual, RuleDto expected) {
+
assertThat(actual.getUuid()).isEqualTo(expected.getUuid());
assertThat(actual.getRepositoryKey()).isEqualTo(expected.getRepositoryKey());
assertThat(actual.getRuleKey()).isEqualTo(expected.getRuleKey());
assertThat(actual.getAdHocSeverity()).isEqualTo(expected.getAdHocSeverity());
assertThat(actual.getAdHocType()).isEqualTo(expected.getAdHocType());
assertThat(actual.getRuleDescriptionSectionDtos()).usingRecursiveFieldByFieldElementComparator()
- .isEqualTo(expected.getRuleDescriptionSectionDtos());
+ .containsExactlyInAnyOrderElementsOf(expected.getRuleDescriptionSectionDtos());
}
@Test
RuleQuery.create().withKey("S001").withConfigKey("S1").withRepositoryKey("java"))).hasSize(1);
}
+ @Test
+ public void insert_rule_with_description_section_context() {
+ RuleDto rule = db.rules().insert(r -> r
+ .addRuleDescriptionSectionDto(createDescriptionSectionWithContext("how_to_fix", "spring", "Spring")));
+
+ Optional<RuleDto> ruleDto = underTest.selectByUuid(rule.getUuid(), db.getSession());
+ assertEquals(ruleDto.get(), rule);
+ }
+
+ @NotNull
+ private static RuleDescriptionSectionDto createDescriptionSectionWithContext(String key, String contextKey, String contextDisplayName) {
+ return RuleDescriptionSectionDto.builder()
+ .uuid(UuidFactoryFast.getInstance().create())
+ .content("content")
+ .key(key)
+ .context(RuleDescriptionSectionContextDto.of(contextKey, contextDisplayName))
+ .build();
+ }
+
+ @Test
+ public void insert_rule_with_different_section_context() {
+ RuleDto rule = db.rules().insert(r -> r
+ .addRuleDescriptionSectionDto(createDescriptionSectionWithContext("how_to_fix", "spring", "Spring"))
+ .addRuleDescriptionSectionDto(createDescriptionSectionWithContext("how_to_fix", "myBatis", "My Batis")));
+
+ Optional<RuleDto> ruleDto = underTest.selectByUuid(rule.getUuid(), db.getSession());
+ assertEquals(ruleDto.get(), rule);
+ }
+
@Test
public void insert() {
RuleDescriptionSectionDto sectionDto = createDefaultRuleDescriptionSection();
.content(randomAlphanumeric(1000))
.build();
- rule.addOrReplaceRuleDescriptionSectionDto(replacingSection);
+ rule.replaceRuleDescriptionSectionDtos(replacingSection);
+
+ underTest.update(db.getSession(), rule);
+ db.getSession().commit();
+
+ RuleDto ruleDto = underTest.selectOrFailByKey(db.getSession(), RuleKey.of(rule.getRepositoryKey(), rule.getRuleKey()));
+
+ assertThat(ruleDto.getRuleDescriptionSectionDtos())
+ .usingRecursiveFieldByFieldElementComparator()
+ .containsOnly(replacingSection);
+ }
+
+ @Test
+ public void update_rule_sections_replaces_section_with_context() {
+ RuleDto rule = db.rules().insert();
+ RuleDescriptionSectionDto existingSection = rule.getRuleDescriptionSectionDtos().iterator().next();
+ RuleDescriptionSectionDto replacingSection = RuleDescriptionSectionDto.builder()
+ .uuid(randomAlphanumeric(20))
+ .key(existingSection.getKey())
+ .content(randomAlphanumeric(1000))
+ .build();
+
+ rule.replaceRuleDescriptionSectionDtos(replacingSection);
underTest.update(db.getSession(), rule);
db.getSession().commit();
.key("DESC")
.uuid("uuid")
.content("my description")
+ .context(RuleDescriptionSectionContextDto.of("context key", "context display name"))
.build();
RuleDto r1 = db.rules().insert(r -> {
r.addRuleDescriptionSectionDto(ruleDescriptionSectionDto);
assertThat(firstRule.getRuleDescriptionSectionsDtos().stream()
.filter(s -> s.getKey().equals(ruleDescriptionSectionDto.getKey()))
.collect(MoreCollectors.onlyElement()))
- .usingRecursiveComparison()
- .isEqualTo(ruleDescriptionSectionDto);
+ .usingRecursiveComparison()
+ .isEqualTo(ruleDescriptionSectionDto);
assertThat(firstRule.getDescriptionFormat()).isEqualTo(r1.getDescriptionFormat());
assertThat(firstRule.getSeverity()).isEqualTo(r1.getSeverity());
assertThat(firstRule.getStatus()).isEqualTo(r1.getStatus());
--- /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.db.rule;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.sonar.db.rule.RuleDescriptionSectionContextDto.DISPLAY_NAME_MUST_BE_SET_ERROR;
+import static org.sonar.db.rule.RuleDescriptionSectionContextDto.KEY_MUST_BE_SET_ERROR;
+
+public class RuleDescriptionSectionContextDtoTest {
+
+ private static final String CONTEXT_KEY = "key";
+ private static final String CONTEXT_DISPLAY_NAME = "displayName";
+
+ @Test
+ public void check_of_instantiate_object() {
+ RuleDescriptionSectionContextDto context = RuleDescriptionSectionContextDto.of(CONTEXT_KEY, CONTEXT_DISPLAY_NAME);
+
+ assertThat(context).extracting(RuleDescriptionSectionContextDto::getKey,
+ RuleDescriptionSectionContextDto::getDisplayName).contains(CONTEXT_KEY, CONTEXT_DISPLAY_NAME);
+ }
+
+ @Test
+ public void check_of_with_key_is_empty() {
+ assertThatThrownBy(() -> RuleDescriptionSectionContextDto.of("", CONTEXT_DISPLAY_NAME))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage(KEY_MUST_BE_SET_ERROR);
+ }
+
+ @Test
+ public void check_of_with_display_name_is_empty() {
+ assertThatThrownBy(() -> RuleDescriptionSectionContextDto.of(CONTEXT_KEY, ""))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage(DISPLAY_NAME_MUST_BE_SET_ERROR);
+ }
+
+ @Test
+ public void equals_with_equals_objects_should_return_true() {
+ RuleDescriptionSectionContextDto context1 = RuleDescriptionSectionContextDto.of(CONTEXT_KEY, CONTEXT_DISPLAY_NAME);
+ RuleDescriptionSectionContextDto context2 = RuleDescriptionSectionContextDto.of(CONTEXT_KEY, CONTEXT_DISPLAY_NAME);
+ assertThat(context1).isEqualTo(context2);
+ }
+
+ @Test
+ public void equals_with_same_objects_should_return_true() {
+ RuleDescriptionSectionContextDto context1 = RuleDescriptionSectionContextDto.of(CONTEXT_KEY, CONTEXT_DISPLAY_NAME);
+ assertThat(context1).isEqualTo(context1);
+ }
+
+ @Test
+ public void equals_with_one_null_objet_should_return_false() {
+ RuleDescriptionSectionContextDto context1 = RuleDescriptionSectionContextDto.of(CONTEXT_KEY, CONTEXT_DISPLAY_NAME);
+ assertThat(context1).isNotEqualTo(null);
+ }
+
+ @Test
+ public void equals_with_different_display_names_should_return_false() {
+ RuleDescriptionSectionContextDto context1 = RuleDescriptionSectionContextDto.of(CONTEXT_KEY, CONTEXT_DISPLAY_NAME);
+ RuleDescriptionSectionContextDto context2 = RuleDescriptionSectionContextDto.of(CONTEXT_KEY, CONTEXT_DISPLAY_NAME + "2");
+ assertThat(context1).isNotEqualTo(context2);
+ }
+
+ @Test
+ public void equals_with_different_context_keys_should_return_false() {
+ RuleDescriptionSectionContextDto context1 = RuleDescriptionSectionContextDto.of(CONTEXT_KEY, CONTEXT_DISPLAY_NAME);
+ RuleDescriptionSectionContextDto context2 = RuleDescriptionSectionContextDto.of(CONTEXT_KEY + "2", CONTEXT_DISPLAY_NAME);
+ assertThat(context1).isNotEqualTo(context2);
+ }
+
+ @Test
+ public void hashcode_with_equals_objects_should_return_same_hash() {
+ RuleDescriptionSectionContextDto context1 = RuleDescriptionSectionContextDto.of(CONTEXT_KEY, CONTEXT_DISPLAY_NAME);
+ RuleDescriptionSectionContextDto context2 = RuleDescriptionSectionContextDto.of(CONTEXT_KEY, CONTEXT_DISPLAY_NAME);
+ assertThat(context1).hasSameHashCodeAs(context2);
+ }
+
+
+}
private static final RuleDescriptionSectionDto SECTION = RuleDescriptionSectionDto.builder()
.key("key")
.uuid("uuid")
+ .context(RuleDescriptionSectionContextDto.of("key", "displayName"))
.content("desc").build();
.withMessage("Only one of setDefault and key methods can be called");
}
-
@Test
public void testToString() {
- Assertions.assertThat(SECTION).hasToString("RuleDescriptionSectionDto[uuid='uuid', key='key', content='desc']");
+ Assertions.assertThat(SECTION)
+ .hasToString("RuleDescriptionSectionDto[uuid='uuid', key='key', content='desc', context='RuleDescriptionSectionContextDto[key='key', displayName='displayName']']");
}
}
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
+import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import org.sonar.core.util.Uuids;
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.apache.commons.lang.StringUtils.repeat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.sonar.db.rule.RuleDto.ERROR_MESSAGE_SECTION_ALREADY_EXISTS;
import static org.sonar.db.rule.RuleTesting.newRule;
public class RuleDtoTest {
+ public static final String SECTION_KEY = "section key";
@Test
public void fail_if_key_is_too_long() {
assertThatThrownBy(() -> new RuleDto().setRuleKey(repeat("x", 250)))
.isNotEqualTo(newRule().setRuleKey(dto.getRuleKey()).setUuid(Uuids.createFast()).hashCode())
.isNotEqualTo(newRule().setUuid(Uuids.createFast()).hashCode());
}
+
+ @Test
+ public void add_rule_description_section_same_key_should_throw_error() {
+ RuleDto dto = new RuleDto();
+
+ RuleDescriptionSectionDto section1 = createSection(SECTION_KEY);
+ dto.addRuleDescriptionSectionDto(section1);
+
+ RuleDescriptionSectionDto section2 = createSection(SECTION_KEY);
+ assertThatThrownBy(() -> dto.addRuleDescriptionSectionDto(section2))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage(String.format(ERROR_MESSAGE_SECTION_ALREADY_EXISTS, SECTION_KEY, "null"));
+ }
+
+ @Test
+ public void add_rule_description_section_with_different_context() {
+ RuleDto dto = new RuleDto();
+
+ RuleDescriptionSectionDto section1 = createSection(RuleDtoTest.SECTION_KEY, "context key 1", "context display Name 1");
+ dto.addRuleDescriptionSectionDto(section1);
+
+ RuleDescriptionSectionDto section2 = createSection(RuleDtoTest.SECTION_KEY, "context key 2", "context display Name 2");
+ dto.addRuleDescriptionSectionDto(section2);
+
+ assertThat(dto.getRuleDescriptionSectionDtos())
+ .usingRecursiveFieldByFieldElementComparator()
+ .containsExactlyInAnyOrder(section1, section2);
+
+ }
+
+ @Test
+ public void add_rule_description_section_with_same_section_and_context_should_throw_error() {
+ RuleDto dto = new RuleDto();
+ String contextKey = randomAlphanumeric(50);
+ String displayName = randomAlphanumeric(50);
+ RuleDescriptionSectionDto section1 = createSection(SECTION_KEY, contextKey, displayName);
+ dto.addRuleDescriptionSectionDto(section1);
+ RuleDescriptionSectionDto section2 = createSection(SECTION_KEY, contextKey, displayName);
+
+ assertThatThrownBy(() -> dto.addRuleDescriptionSectionDto(section2))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage(String.format(ERROR_MESSAGE_SECTION_ALREADY_EXISTS, SECTION_KEY, contextKey));
+
+ }
+
+ @NotNull
+ private static RuleDescriptionSectionDto createSection(String section_key, String contextKey, String contextDisplayName) {
+ return RuleDescriptionSectionDto.builder()
+ .key(section_key)
+ .context(RuleDescriptionSectionContextDto.of(contextKey, contextDisplayName))
+ .build();
+ }
+
+ @NotNull
+ private static RuleDescriptionSectionDto createSection(String section_key) {
+ return RuleDescriptionSectionDto.builder()
+ .key(section_key)
+ .build();
+ }
}
// otherwise the generated random values may raise false-positives
RuleDto rule1 = createJavaRule(rule -> rule.setRuleKey("123")
.setName("rule 123")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "My great rule CWE-123 which makes your code 1000 times better!")));
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "My great rule CWE-123 which makes your code 1000 times better!")));
RuleDto rule2 = createJavaRule(rule -> rule.setRuleKey("124")
.setName("rule 124")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Another great and shiny rule CWE-124")));
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "Another great and shiny rule CWE-124")));
RuleDto rule3 = createJavaRule(rule -> rule.setRuleKey("1000")
.setName("rule 1000")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Another great rule CWE-1000")));
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "Another great rule CWE-1000")));
RuleDto rule4 = createJavaRule(rule -> rule.setRuleKey("404")
.setName("rule 404")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(),
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(),
"<h1>HTML-Geeks</h1><p style=\"color:blue\">special formatting!</p><table><tr><td>inside</td><td>tables</td></tr></table>")));
RuleDto rule5 = createJavaRule(rule -> rule.setRuleKey("405")
.setName("rule 405")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "internationalization missunderstandings alsdkjfnadklsjfnadkdfnsksdjfn")));
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "internationalization missunderstandings alsdkjfnadklsjfnadkdfnsksdjfn")));
index();
// partial match at word boundary
public void index_long_rule_description() {
String description = IntStream.range(0, 100000).map(i -> i % 100).mapToObj(Integer::toString).collect(joining(" "));
RuleDescriptionSectionDto ruleDescriptionSectionDto = createDefaultRuleDescriptionSection(uuidFactory.create(), description);
- RuleDto rule = dbTester.rules().insert(r -> r.addOrReplaceRuleDescriptionSectionDto(ruleDescriptionSectionDto));
+
+ RuleDto rule = dbTester.rules().insert(r -> r.replaceRuleDescriptionSectionDtos(ruleDescriptionSectionDto));
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
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.replaceRuleDescriptionSectionDtos(RULE_DESCRIPTION_SECTION_DTO);
r.addRuleDescriptionSectionDto(RULE_DESCRIPTION_SECTION_DTO2);
});
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);
+ r.replaceRuleDescriptionSectionDtos(RULE_DESCRIPTION_SECTION_DTO);
});
underTest.commitAndIndex(dbTester.getSession(), rule.getUuid());
}
private static boolean ruleDescriptionSectionsUnchanged(RuleDto ruleDto, Set<RuleDescriptionSectionDto> newRuleDescriptionSectionDtos) {
- Map<String, String> oldKeysToSections = toMap(ruleDto.getRuleDescriptionSectionDtos());
- Map<String, String> newKeysToSections = toMap(newRuleDescriptionSectionDtos);
- return oldKeysToSections.equals(newKeysToSections);
+ if (ruleDto.getRuleDescriptionSectionDtos().size() != newRuleDescriptionSectionDtos.size()) {
+ return false;
+ }
+ return ruleDto.getRuleDescriptionSectionDtos().stream()
+ .allMatch(sectionDto -> contains(newRuleDescriptionSectionDtos, sectionDto));
}
- private static Map<String, String> toMap(Set<RuleDescriptionSectionDto> ruleDto) {
- return ruleDto
- .stream()
- .collect(Collectors.toMap(RuleDescriptionSectionDto::getKey, RuleDescriptionSectionDto::getContent));
+ private static boolean contains(Set<RuleDescriptionSectionDto> sectionDtos, RuleDescriptionSectionDto sectionDto) {
+ return sectionDtos.stream()
+ .filter(s -> s.getKey().equals(sectionDto.getKey()) && s.getContent().equals(sectionDto.getContent()))
+ .anyMatch(s -> Objects.equals(s.getContext(), sectionDto.getContext()));
}
private static boolean mergeDebtDefinitions(RulesDefinition.Rule def, RuleDto dto) {
.setRepositoryKey("repo")
.setRuleKey("ruleKey")
.setDescriptionFormat(RuleDto.Format.MARKDOWN)
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("uuid", "<div>line1\nline2</div>"));
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection("uuid", "<div>line1\nline2</div>"));
db.rules().insert(rule1);
ActiveRuleDto activeRuleDto = ActiveRuleDto.createFor(qualityProfileDto, rule1);
}
RuleDescriptionSectionDto descriptionSectionDto = createDefaultRuleDescriptionSection(uuidFactory.create(), description);
rule.setDescriptionFormat(RuleDto.Format.MARKDOWN);
- rule.addOrReplaceRuleDescriptionSectionDto(descriptionSectionDto);
+ rule.replaceRuleDescriptionSectionDtos(List.of(descriptionSectionDto));
}
private static void updateSeverity(RuleUpdate update, RuleDto rule) {
private RuleDto newIssueRule() {
RuleDto rule = RuleTesting.newXooX1()
.setName("Rule name")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Rule desc"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "Rule desc"))
.setStatus(RuleStatus.READY);
db.rules().insert(rule);
return rule;
private RuleDto newHotspotRule() {
RuleDto rule = RuleTesting.newXooX2()
.setName("Rule name")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Rule desc"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "Rule desc"))
.setStatus(RuleStatus.READY)
.setType(SECURITY_HOTSPOT_VALUE);
db.rules().insert(rule);
RuleDto templateRule = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto
.setIsTemplate(true));
RuleDto rule = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(UuidFactoryFast.getInstance().create(), "custom rule description"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(UuidFactoryFast.getInstance().create(), "custom rule description"))
.setName("custom rule name")
.setStatus(RuleStatus.READY)
.setTemplateUuid(templateRule.getUuid()));
RuleDto templateRule = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto
.setIsTemplate(true));
RuleDto rule = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(UuidFactoryFast.getInstance().create(), "custom rule description"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(UuidFactoryFast.getInstance().create(), "custom rule description"))
.setName("custom rule name")
.setStatus(RuleStatus.READY)
.setTemplateUuid(templateRule.getUuid()));
.setRuleKey(key)
.setStatus(RuleStatus.REMOVED)
.setName("Old name")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description"))
.setDescriptionFormat(Format.MARKDOWN)
.setSeverity(Severity.INFO);
dbTester.rules().insert(rule);
.setRuleKey(key)
.setStatus(RuleStatus.REMOVED)
.setName("Old name")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description"))
.setSeverity(Severity.INFO);
dbTester.rules().insert(rule);
dbTester.rules().insertRuleParam(rule, param -> param.setDefaultValue("a.*"));
// Create custom rule
RuleDto customRule = newCustomRule(templateRule)
.setName("Old name")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description"))
.setSeverity(Severity.MINOR)
.setStatus(RuleStatus.BETA)
;
// Create custom rule
RuleDto customRule = newCustomRule(templateRule)
.setName("Old name")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "Old description"))
.setSeverity(Severity.MINOR)
.setStatus(RuleStatus.BETA);
db.rules().insert(customRule);
.setRuleKey("MY_CUSTOM")
.setStatus(RuleStatus.REMOVED)
.setName("My custom rule")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Description"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "Description"))
.setDescriptionFormat(RuleDto.Format.MARKDOWN)
.setSeverity(Severity.MAJOR);
db.rules().insert(customRule);
import static org.mockito.Mockito.mock;
import static org.sonar.api.rule.Severity.BLOCKER;
import static org.sonar.db.rule.RuleDescriptionSectionDto.createDefaultRuleDescriptionSection;
+import static org.sonar.db.rule.RuleTesting.newRuleWithoutDescriptionSection;
import static org.sonar.db.rule.RuleTesting.setSystemTags;
import static org.sonar.db.rule.RuleTesting.setTags;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION;
RuleDto rule1 = db.rules()
.insert(
r1 -> r1
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is the <bold>best</bold> rule now&for<b>ever</b>"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is the <bold>best</bold> rule now&for<b>ever</b>"))
.setNoteUserUuid(null));
db.rules().insert(r1 -> r1.setName("Some other stuff").setNoteUserUuid(null));
indexRules();
@Test
public void filter_by_rule_name_or_descriptions_requires_all_words_to_match_anywhere() {
- RuleDto rule1 = db.rules().insert(r1 -> r1.setName("Best rule ever").setNoteUserUuid(null)
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is a good rule")));
- db.rules().insert(r1 -> r1.setName("Another thing").setNoteUserUuid(null)
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Another thing")));
+ RuleDto rule1 = db.rules().insert(newRuleWithoutDescriptionSection().setName("Best rule ever").setNoteUserUuid(null)
+ .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is a good rule")));
+ db.rules().insert(newRuleWithoutDescriptionSection().setName("Another thing").setNoteUserUuid(null)
+ .addRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "Another thing")));
indexRules();
verify(r -> r.setParam("q", "Best good"), rule1);
db.rules().insert(templateRule);
// Custom rule
RuleDto customRule = newCustomRule(templateRule)
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "<div>line1\nline2</div>"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "<div>line1\nline2</div>"))
.setDescriptionFormat(MARKDOWN)
.setNoteUserUuid(userDto.getUuid());
db.rules().insert(customRule);
.setIsExternal(true)
.setIsAdHoc(true)
.setName("predefined name")
- .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "<div>predefined desc</div>"))
+ .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "<div>predefined desc</div>"))
.setSeverity(Severity.BLOCKER)
.setType(RuleType.VULNERABILITY)
.setAdHocName("adhoc name")
RuleDto customRule = db.rules().insert(
r -> r.setRuleKey(RuleKey.of("java", "MY_CUSTOM")),
r -> r.setName("Old custom"),
- r -> r.addOrReplaceRuleDescriptionSectionDto(createRuleDescriptionSectionDto()),
+ r -> r.replaceRuleDescriptionSectionDtos(createRuleDescriptionSectionDto()),
r -> r.setSeverity(Severity.MINOR),
r -> r.setStatus(RuleStatus.BETA),
r -> r.setTemplateUuid(templateRule.getUuid()),
RuleDto customRule = db.rules().insert(
r -> r.setRuleKey(RuleKey.of("java", "MY_CUSTOM")),
r -> r.setName("Old custom"),
- r -> r.addOrReplaceRuleDescriptionSectionDto(createRuleDescriptionSectionDto()),
+ r -> r.replaceRuleDescriptionSectionDtos(createRuleDescriptionSectionDto()),
r -> r.setTemplateUuid(templateRule.getUuid()),
r -> r.setCreatedAt(PAST),
r -> r.setUpdatedAt(PAST));