From: Léo Geoffroy Date: Thu, 23 Jun 2022 10:21:38 +0000 (+0200) Subject: SONAR-16518 Add context to RuleDescriptionSectionDto X-Git-Tag: 9.6.0.59041~311 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b2079411492f9c056c92c619d2ccf08e86e88e5c;p=sonarqube.git SONAR-16518 Add context to RuleDescriptionSectionDto --- diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionContextDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionContextDto.java new file mode 100644 index 00000000000..632c2355ff3 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionContextDto.java @@ -0,0 +1,77 @@ +/* + * 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 + '\'' + + ']'; + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionDto.java index b1da5553845..f443d88be78 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionDto.java @@ -20,20 +20,27 @@ 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() { @@ -48,6 +55,11 @@ public class RuleDescriptionSectionDto { return content; } + @CheckForNull + public RuleDescriptionSectionContextDto getContext() { + return context; + } + public static RuleDescriptionSectionDto createDefaultRuleDescriptionSection(String uuid, String description) { return RuleDescriptionSectionDto.builder() .setDefault() @@ -70,13 +82,17 @@ public class RuleDescriptionSectionDto { .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() { } @@ -103,8 +119,14 @@ public class RuleDescriptionSectionDto { 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); } } + } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java index eda4dc4a533..907f8ab6079 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java @@ -19,11 +19,13 @@ */ 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; @@ -38,10 +40,13 @@ import org.sonar.api.rules.RuleType; 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 } @@ -56,7 +61,7 @@ public class RuleDto { private String repositoryKey = null; private String ruleKey = null; - private Set ruleDescriptionSectionDtos = new HashSet<>(); + private final Set ruleDescriptionSectionDtos = new HashSet<>(); /** * Description format can be null on external rule, otherwise it should never be null @@ -198,7 +203,10 @@ public class RuleDto { @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 ruleDescriptionSectionDtos) { @@ -207,26 +215,33 @@ public class RuleDto { 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 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 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 diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml index cc70d9a3a3f..643343da0bd 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml @@ -50,6 +50,8 @@ 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", @@ -68,7 +70,14 @@ + + + + + + + @@ -195,7 +204,8 @@ #{language, jdbcType=VARCHAR} - select r.uuid as uuid, @@ -212,13 +222,17 @@ 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} ) diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java index 881ebde36e0..9f3a728b5f5 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java @@ -83,7 +83,6 @@ public class RuleDaoTest { } - @Test public void selectByUuid() { RuleDto ruleDto = db.rules().insert(); @@ -202,6 +201,7 @@ public class RuleDaoTest { } 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()); @@ -236,7 +236,7 @@ public class RuleDaoTest { assertThat(actual.getAdHocSeverity()).isEqualTo(expected.getAdHocSeverity()); assertThat(actual.getAdHocType()).isEqualTo(expected.getAdHocType()); assertThat(actual.getRuleDescriptionSectionDtos()).usingRecursiveFieldByFieldElementComparator() - .isEqualTo(expected.getRuleDescriptionSectionDtos()); + .containsExactlyInAnyOrderElementsOf(expected.getRuleDescriptionSectionDtos()); } @Test @@ -401,6 +401,35 @@ public class RuleDaoTest { 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 = 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 = underTest.selectByUuid(rule.getUuid(), db.getSession()); + assertEquals(ruleDto.get(), rule); + } + @Test public void insert() { RuleDescriptionSectionDto sectionDto = createDefaultRuleDescriptionSection(); @@ -552,7 +581,29 @@ public class RuleDaoTest { .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(); @@ -816,6 +867,7 @@ public class RuleDaoTest { .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); @@ -838,8 +890,8 @@ public class RuleDaoTest { 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()); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDescriptionSectionContextDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDescriptionSectionContextDtoTest.java new file mode 100644 index 00000000000..a175f184ea8 --- /dev/null +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDescriptionSectionContextDtoTest.java @@ -0,0 +1,97 @@ +/* + * 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); + } + + +} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDescriptionSectionDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDescriptionSectionDtoTest.java index f10fb58419b..d34f7ea55cf 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDescriptionSectionDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDescriptionSectionDtoTest.java @@ -28,6 +28,7 @@ public class RuleDescriptionSectionDtoTest { private static final RuleDescriptionSectionDto SECTION = RuleDescriptionSectionDto.builder() .key("key") .uuid("uuid") + .context(RuleDescriptionSectionContextDto.of("key", "displayName")) .content("desc").build(); @@ -49,9 +50,9 @@ public class RuleDescriptionSectionDtoTest { .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']']"); } } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java index e1d0ee61ee7..223efa1000d 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java @@ -23,17 +23,21 @@ import com.google.common.collect.ImmutableSet; 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))) @@ -115,4 +119,63 @@ public class RuleDtoTest { .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(); + } } diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java index 41b786e2751..94f38180b32 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java @@ -216,20 +216,20 @@ public class RuleIndexTest { // 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(), "

HTML-Geeks

special formatting!

insidetables
"))); 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 diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java index c47c8ab560c..348a1f4c3d3 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java @@ -139,7 +139,8 @@ public class RuleIndexerTest { 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(); @@ -148,7 +149,7 @@ public class RuleIndexerTest { @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); }); @@ -166,7 +167,7 @@ public class RuleIndexerTest { 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()); diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java index 38c0c810cfa..fc3463987b6 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java @@ -517,15 +517,17 @@ public class RegisterRules implements Startable { } private static boolean ruleDescriptionSectionsUnchanged(RuleDto ruleDto, Set newRuleDescriptionSectionDtos) { - Map oldKeysToSections = toMap(ruleDto.getRuleDescriptionSectionDtos()); - Map 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 toMap(Set ruleDto) { - return ruleDto - .stream() - .collect(Collectors.toMap(RuleDescriptionSectionDto::getKey, RuleDescriptionSectionDto::getContent)); + private static boolean contains(Set 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) { diff --git a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImplTest.java b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImplTest.java index 1b4c10e0fc9..f2413b3d519 100644 --- a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImplTest.java +++ b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImplTest.java @@ -71,7 +71,7 @@ public class QualityProfileChangeEventServiceImplTest { .setRepositoryKey("repo") .setRuleKey("ruleKey") .setDescriptionFormat(RuleDto.Format.MARKDOWN) - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection("uuid", "
line1\nline2
")); + .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection("uuid", "
line1\nline2
")); db.rules().insert(rule1); ActiveRuleDto activeRuleDto = ActiveRuleDto.createFor(qualityProfileDto, rule1); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java index 37e75095506..a6b3692d93b 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java @@ -142,7 +142,7 @@ public class RuleUpdater { } 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) { diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java index 1f3bdad7a8d..21fbd555e27 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java @@ -1489,7 +1489,7 @@ public class SearchActionTest { 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; @@ -1498,7 +1498,7 @@ public class SearchActionTest { 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); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java index 52f573821d4..d9fe3768c0b 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java @@ -145,7 +145,7 @@ public class QProfileBackuperImplTest { 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())); @@ -404,7 +404,7 @@ public class QProfileBackuperImplTest { 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())); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleCreatorTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleCreatorTest.java index 41cf430db08..76729573d0b 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleCreatorTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleCreatorTest.java @@ -323,7 +323,7 @@ public class RuleCreatorTest { .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); @@ -363,7 +363,7 @@ public class RuleCreatorTest { .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.*")); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java index c0a447fe454..87740b34044 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java @@ -338,7 +338,7 @@ public class RuleUpdaterTest { // 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) ; @@ -386,7 +386,7 @@ public class RuleUpdaterTest { // 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); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/CreateActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/CreateActionTest.java index bcb20ba7d4a..224ded60971 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/CreateActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/CreateActionTest.java @@ -140,7 +140,7 @@ public class CreateActionTest { .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); 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 1d071bc6629..73caabab1d8 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 @@ -84,6 +84,7 @@ import static org.mockito.Mockito.doReturn; 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; @@ -239,7 +240,7 @@ public class SearchActionTest { RuleDto rule1 = db.rules() .insert( r1 -> r1 - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is the best rule now&forever")) + .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is the best rule now&forever")) .setNoteUserUuid(null)); db.rules().insert(r1 -> r1.setName("Some other stuff").setNoteUserUuid(null)); indexRules(); @@ -251,10 +252,10 @@ public class SearchActionTest { @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); 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 6d4bddd79ff..3528492a834 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 @@ -297,7 +297,7 @@ public class ShowActionTest { db.rules().insert(templateRule); // Custom rule RuleDto customRule = newCustomRule(templateRule) - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "
line1\nline2
")) + .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "
line1\nline2
")) .setDescriptionFormat(MARKDOWN) .setNoteUserUuid(userDto.getUuid()); db.rules().insert(customRule); @@ -435,7 +435,7 @@ public class ShowActionTest { .setIsExternal(true) .setIsAdHoc(true) .setName("predefined name") - .addOrReplaceRuleDescriptionSectionDto(createDefaultRuleDescriptionSection(uuidFactory.create(), "
predefined desc
")) + .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "
predefined desc
")) .setSeverity(Severity.BLOCKER) .setType(RuleType.VULNERABILITY) .setAdHocName("adhoc name") diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/UpdateActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/UpdateActionTest.java index c5dc656057e..c2c6065d7e4 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/UpdateActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/UpdateActionTest.java @@ -113,7 +113,7 @@ public class UpdateActionTest { 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()), @@ -249,7 +249,7 @@ public class UpdateActionTest { 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));