]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16518 Add context to RuleDescriptionSectionDto
authorLéo Geoffroy <leo.geoffroy@sonarsource.com>
Thu, 23 Jun 2022 10:21:38 +0000 (12:21 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 30 Jun 2022 20:03:09 +0000 (20:03 +0000)
21 files changed:
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionContextDto.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDescriptionSectionDto.java
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java
server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDescriptionSectionContextDtoTest.java [new file with mode: 0644]
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDescriptionSectionDtoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java
server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java
server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java
server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java
server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImplTest.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/RuleUpdater.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/qualityprofile/QProfileBackuperImplTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleCreatorTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/RuleUpdaterTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/CreateActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/rule/ws/UpdateActionTest.java

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 (file)
index 0000000..632c235
--- /dev/null
@@ -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 + '\'' +
+      ']';
+  }
+}
index b1da5553845af8970589254cce7bb1ac5f818e99..f443d88be78c108d52299c3adcec0a036aaf87a3 100644 (file)
 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);
     }
   }
+
 }
index eda4dc4a5335cb3fcc06915867480b0be2a0101d..907f8ab607998017e77fa55ac88715e1c2821dc7 100644 (file)
  */
 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<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
@@ -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<RuleDescriptionSectionDto> 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<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
index cc70d9a3a3f282d6be24b61904029da449c11a15..643343da0bd6c35c9ac5f9836f57150a9e5cfc6f 100644 (file)
@@ -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",
 
     <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>
 
index 881ebde36e01db43dba5252a40d4d174a063e529..9f3a728b5f5e52e4e2401145c9120c17c0d2ac2d 100644 (file)
@@ -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> 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();
@@ -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 (file)
index 0000000..a175f18
--- /dev/null
@@ -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);
+  }
+
+
+}
index f10fb58419bb2a09e5dacea3e287f214b308bec0..d34f7ea55cf5bcbc8a3c228eb09aeeefe7b215a4 100644 (file)
@@ -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']']");
   }
 }
index e1d0ee61ee7fa733c50ae28cd80461f47f0cfd34..223efa1000d980a4101d1d6bc8a1fa6bb301d056 100644 (file)
@@ -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();
+  }
 }
index 41b786e2751b0ff994673503d747902cbf813f65..94f38180b324b00947e38a4da01beb704829a041 100644 (file)
@@ -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(),
         "<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
index c47c8ab560cfeec1118545b4c83694af59e0642b..348a1f4c3d31b44cb6a6d9057982f945077d97a2 100644 (file)
@@ -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());
index 38c0c810cfa9acfd491424af66b6ab631eb6efff..fc3463987b61d5fd93cb5ec6e0816d7b19099b46 100644 (file)
@@ -517,15 +517,17 @@ public class RegisterRules implements Startable {
   }
 
   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) {
index 1b4c10e0fc902f54fe43b511b31b90eec340d62c..f2413b3d519ce9a55640b4392795c42d416e0bc0 100644 (file)
@@ -71,7 +71,7 @@ public class QualityProfileChangeEventServiceImplTest {
       .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);
index 37e750955060ff6d02edfbffb1f3e05bfe4329ce..a6b3692d93bb20c32949c0a185e9dc190bd481fc 100644 (file)
@@ -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) {
index 1f3bdad7a8da3b46da95cccd32f38db908e2f6e6..21fbd555e27704ea74f0314f6162051a517a11d4 100644 (file)
@@ -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);
index 52f573821d48c5cbb57cd045879fcc4bb6effbcd..d9fe3768c0b4506408ed81c31c04b206facec554 100644 (file)
@@ -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()));
index 41cf430db08c983df093afed04a665bf242e2a12..76729573d0b3d9bc3fe75c8cfada28894402c073 100644 (file)
@@ -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.*"));
index c0a447fe45449164c3a7ad51fb41f4fe484c8934..87740b34044772ccf9238f190a86e2fa258fe091 100644 (file)
@@ -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);
index bcb20ba7d4a0fd883b963da19653275286bfc12b..224ded60971c865a58928cc924044368528c366e 100644 (file)
@@ -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);
index 1d071bc66292e328934fdb4fd03f6a84defbc796..73caabab1d8e75a4c606ce4c78fb0174bc91f0a9 100644 (file)
@@ -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 <bold>best</bold> rule now&amp;for<b>ever</b>"))
+          .replaceRuleDescriptionSectionDtos(createDefaultRuleDescriptionSection(uuidFactory.create(), "This is the <bold>best</bold> rule now&amp;for<b>ever</b>"))
           .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);
index 6d4bddd79ff07d327b3b67331e38f7c6e2db755c..3528492a834194994b4c66349f0445c7cfd38dd9 100644 (file)
@@ -297,7 +297,7 @@ public class ShowActionTest {
     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);
@@ -435,7 +435,7 @@ public class ShowActionTest {
       .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")
index c5dc656057e38caa3e12ac9a7c59994c37c36edd..c2c6065d7e40364550847ed49aeba51b96d35195 100644 (file)
@@ -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));