]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-15919 improve test coverage
authorPierre <pierre.guillot@sonarsource.com>
Thu, 10 Feb 2022 12:54:47 +0000 (13:54 +0100)
committersonartech <sonartech@sonarsource.com>
Fri, 18 Feb 2022 15:48:04 +0000 (15:48 +0000)
server/sonar-webserver-pushapi/build.gradle
server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImpl.java
server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/sonarlint/SonarLintClientsRegistry.java
server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/sonarlint/SonarLintClientsRegistryTest.java
server/sonar-webserver-pushapi/src/test/java/org/sonar/server/qualityprofile/builtin/QualityProfileChangeEventServiceImplTest.java [new file with mode: 0644]
server/sonar-webserver-pushapi/src/test/resources/org/sonar/server/pushapi/sonarlint/rule-change-event.json [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/util/ParamChange.java
sonar-core/src/main/java/org/sonar/core/util/RuleChange.java

index 7be19a379bcce51059c113040fed2cc67f570c0a..b0625c4564a54178f322ad634f4d1c9f21440048 100644 (file)
@@ -15,6 +15,7 @@ dependencies {
     testCompile 'org.assertj:assertj-core'
     testCompile 'org.mockito:mockito-core'
     testCompile testFixtures(project(':server:sonar-webserver-ws'))
+    testCompile testFixtures(project(':server:sonar-db-dao'))
 
     testFixturesApi project(':sonar-testing-harness')
     testFixturesCompileOnly testFixtures(project(':server:sonar-webserver-ws'))
index fbd876309aec3d5bcf16aaed552912d0402b8f5a..6ada60df29659f94d6c1046049785c5337f67e27 100644 (file)
@@ -22,13 +22,13 @@ package org.sonar.server.pushapi.qualityprofile;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
 import org.jetbrains.annotations.NotNull;
 import org.sonar.api.server.ServerSide;
 import org.sonar.core.util.ParamChange;
@@ -37,24 +37,22 @@ import org.sonar.core.util.RuleSetChangeEvent;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.project.ProjectDto;
+import org.sonar.db.qualityprofile.ActiveRuleDto;
 import org.sonar.db.qualityprofile.ActiveRuleParamDto;
+import org.sonar.db.qualityprofile.OrgActiveRuleDto;
 import org.sonar.db.qualityprofile.ProjectQprofileAssociationDto;
 import org.sonar.db.qualityprofile.QProfileDto;
 import org.sonar.db.rule.RuleDto;
 import org.sonar.server.qualityprofile.ActiveRuleChange;
-import org.sonar.server.rule.index.RuleIndex;
-import org.sonar.server.rule.index.RuleQuery;
 
 @ServerSide
 public class QualityProfileChangeEventServiceImpl implements QualityProfileChangeEventService {
 
   private final DbClient dbClient;
-  private final RuleIndex ruleIndex;
   private final RuleActivatorEventsDistributor eventsDistributor;
 
-  public QualityProfileChangeEventServiceImpl(DbClient dbClient, RuleIndex ruleIndex, RuleActivatorEventsDistributor eventsDistributor) {
+  public QualityProfileChangeEventServiceImpl(DbClient dbClient, RuleActivatorEventsDistributor eventsDistributor) {
     this.dbClient = dbClient;
-    this.ruleIndex = ruleIndex;
     this.eventsDistributor = eventsDistributor;
   }
 
@@ -63,64 +61,55 @@ public class QualityProfileChangeEventServiceImpl implements QualityProfileChang
     List<RuleChange> activatedRules = new ArrayList<>();
     List<RuleChange> deactivatedRules = new ArrayList<>();
 
-    try (DbSession dbSession = dbClient.openSession(false)) {
+    if (activatedProfile != null) {
+      activatedRules.addAll(createRuleChanges(activatedProfile));
+    }
 
-      if (activatedProfile != null) {
-        RuleQuery query = new RuleQuery().setQProfile(activatedProfile).setActivation(true).setIncludeExternal(true);
-        Iterator<String> searchIdResult = ruleIndex.searchAll(query);
-        List<String> uuids = new ArrayList<>();
-        while (searchIdResult.hasNext()) {
-          uuids.add(searchIdResult.next());
-        }
+    if (deactivatedProfile != null) {
+      deactivatedRules.addAll(createRuleChanges(deactivatedProfile));
+    }
 
-        List<RuleDto> ruleDtos = dbClient.ruleDao().selectByUuids(dbSession, uuids);
-        Map<String, List<ActiveRuleParamDto>> paramsByRuleUuid = dbClient.activeRuleDao().selectParamsByActiveRuleUuids(dbSession, uuids)
-          .stream().collect(Collectors.groupingBy(ActiveRuleParamDto::getActiveRuleUuid));
+    if (activatedRules.isEmpty() && deactivatedRules.isEmpty()) {
+      return;
+    }
 
-        for (RuleDto ruleDto : ruleDtos) {
-          RuleChange ruleChange = toRuleChange(ruleDto, paramsByRuleUuid);
-          activatedRules.add(ruleChange);
-        }
-      }
+    RuleSetChangeEvent event = new RuleSetChangeEvent(new String[] {project.getKey()}, activatedRules.toArray(new RuleChange[0]), deactivatedRules.toArray(new RuleChange[0]));
+    eventsDistributor.pushEvent(event);
+  }
 
-      if (deactivatedProfile != null) {
-        RuleQuery query = new RuleQuery().setQProfile(deactivatedProfile).setActivation(true).setIncludeExternal(true);
-        // .setLanguages() ?
-        Iterator<String> searchIdResult = ruleIndex.searchAll(query);
-        List<String> uuids = new ArrayList<>();
-        while (searchIdResult.hasNext()) {
-          uuids.add(searchIdResult.next());
-        }
+  private List<RuleChange> createRuleChanges(@NotNull QProfileDto profileDto) {
+    List<RuleChange> ruleChanges = new ArrayList<>();
 
-        List<RuleDto> ruleDtos = dbClient.ruleDao().selectByUuids(dbSession, uuids);
-        Map<String, List<ActiveRuleParamDto>> paramsByRuleUuid = dbClient.activeRuleDao().selectParamsByActiveRuleUuids(dbSession, uuids)
-          .stream().collect(Collectors.groupingBy(ActiveRuleParamDto::getActiveRuleUuid));
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      List<OrgActiveRuleDto> activeRuleDtos = dbClient.activeRuleDao().selectByProfile(dbSession, profileDto);
+      List<String> activeRuleUuids = activeRuleDtos.stream().map(ActiveRuleDto::getUuid).collect(Collectors.toList());
 
-        for (RuleDto ruleDto : ruleDtos) {
-          RuleChange ruleChange = toRuleChange(ruleDto, paramsByRuleUuid);
-          deactivatedRules.add(ruleChange);
-        }
-      }
+      Map<String, List<ActiveRuleParamDto>> paramsByActiveRuleUuid = dbClient.activeRuleDao().selectParamsByActiveRuleUuids(dbSession, activeRuleUuids)
+        .stream().collect(Collectors.groupingBy(ActiveRuleParamDto::getActiveRuleUuid));
 
-    }
+      Map<String, String> activeRuleUuidByRuleUuid = activeRuleDtos.stream().collect(Collectors.toMap(ActiveRuleDto::getRuleUuid, ActiveRuleDto::getUuid));
 
-    if (activatedRules.isEmpty() && deactivatedRules.isEmpty()) {
-      return;
-    }
+      List<String> ruleUuids = activeRuleDtos.stream().map(ActiveRuleDto::getRuleUuid).collect(Collectors.toList());
+      List<RuleDto> ruleDtos = dbClient.ruleDao().selectByUuids(dbSession, ruleUuids);
 
-    RuleSetChangeEvent event = new RuleSetChangeEvent(new String[]{project.getKey()}, activatedRules.toArray(new RuleChange[0]), deactivatedRules.toArray(new RuleChange[0]));
-    eventsDistributor.pushEvent(event);
+      for (RuleDto ruleDto : ruleDtos) {
+        String activeRuleUuid = activeRuleUuidByRuleUuid.get(ruleDto.getUuid());
+        List<ActiveRuleParamDto> params = paramsByActiveRuleUuid.getOrDefault(activeRuleUuid, new ArrayList<>());
+        RuleChange ruleChange = toRuleChange(ruleDto, params);
+        ruleChanges.add(ruleChange);
+      }
+    }
+    return ruleChanges;
   }
 
   @NotNull
-  private RuleChange toRuleChange(RuleDto ruleDto, Map<String, List<ActiveRuleParamDto>> paramsByRuleUuid) {
+  private RuleChange toRuleChange(RuleDto ruleDto, List<ActiveRuleParamDto> activeRuleParamDtos) {
     RuleChange ruleChange = new RuleChange();
     ruleChange.setKey(ruleDto.getRuleKey());
     ruleChange.setLanguage(ruleDto.getLanguage());
     ruleChange.setSeverity(ruleDto.getSeverityString());
 
     List<ParamChange> paramChanges = new ArrayList<>();
-    List<ActiveRuleParamDto> activeRuleParamDtos = paramsByRuleUuid.getOrDefault(ruleDto.getUuid(), new ArrayList<>());
     for (ActiveRuleParamDto activeRuleParam : activeRuleParamDtos) {
       paramChanges.add(new ParamChange(activeRuleParam.getKey(), activeRuleParam.getValue()));
     }
@@ -130,7 +119,7 @@ public class QualityProfileChangeEventServiceImpl implements QualityProfileChang
     if (templateUuid != null && !"".equals(templateUuid)) {
       try (DbSession dbSession = dbClient.openSession(false)) {
         RuleDto templateRule = dbClient.ruleDao().selectByUuid(templateUuid, dbSession)
-          .orElseThrow(() -> new IllegalStateException(String.format("unknow Template Rule '%s'", templateUuid)));
+          .orElseThrow(() -> new IllegalStateException(String.format("Unknown Template Rule '%s'", templateUuid)));
         ruleChange.setTemplateKey(templateRule.getRuleKey());
       }
     }
@@ -192,9 +181,10 @@ public class QualityProfileChangeEventServiceImpl implements QualityProfileChang
       String ruleUuid = arc.getRuleUuid();
       RuleDto rule = dbClient.ruleDao().selectByUuid(ruleUuid, dbSession).orElseThrow(() -> new IllegalStateException("unknow rule"));
       String templateUuid = rule.getTemplateUuid();
-      if (templateUuid != null && !"".equals(templateUuid)) {
+
+      if (StringUtils.isNotEmpty(templateUuid)) {
         RuleDto templateRule = dbClient.ruleDao().selectByUuid(templateUuid, dbSession)
-          .orElseThrow(() -> new IllegalStateException(String.format("unknow Template Rule '%s'", templateUuid)));
+          .orElseThrow(() -> new IllegalStateException(String.format("Unknown Template Rule '%s'", templateUuid)));
         return Optional.of(templateRule.getRuleKey());
       }
     }
index bcf88efcad5f8f981c1f019bb82d4389c388e2f9..10af5984615b387c758f5e9c88df4b1886d3e7b0 100644 (file)
@@ -132,7 +132,7 @@ public class SonarLintClientsRegistry implements RuleActivationListener {
     return result.toString();
   }
 
-  private JSONObject toJson(RuleChange rule) {
+  private static JSONObject toJson(RuleChange rule) {
     JSONObject ruleJson = new JSONObject();
     ruleJson.put("key", rule.getKey());
     ruleJson.put("language", rule.getLanguage());
index 3021e0850b3fe000ab1465bc0b52ad0b5b3e2295..351ff62fb3ee56af53ddf6e312c59169f173f1dd 100644 (file)
@@ -27,13 +27,14 @@ import javax.servlet.ServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.sonar.api.rule.Severity;
+import org.sonar.core.util.ParamChange;
 import org.sonar.core.util.RuleChange;
 import org.sonar.core.util.RuleSetChangeEvent;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.pushapi.qualityprofile.StandaloneRuleActivatorEventsDistributor;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anySet;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doThrow;
@@ -41,6 +42,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
+import static org.sonar.test.JsonAssert.assertJson;
 
 public class SonarLintClientsRegistryTest {
 
@@ -94,17 +96,19 @@ public class SonarLintClientsRegistryTest {
 
     underTest.registerClient(sonarLintClient);
 
-    RuleChange javaRule = createRuleChange("java");
+    RuleChange javaRule = createRuleChange();
 
-    RuleChange[] activatedRules = {};
+    RuleChange[] activatedRules = {javaRule};
     RuleChange[] deactivatedRules = {javaRule};
     RuleSetChangeEvent ruleChangeEvent = new RuleSetChangeEvent(exampleKeys.toArray(String[]::new), activatedRules, deactivatedRules);
     underTest.listen(ruleChangeEvent);
 
     ArgumentCaptor<byte[]> captor = ArgumentCaptor.forClass(byte[].class);
     verify(outputStream).write(captor.capture());
-    String message = new String(captor.getValue());
-    assertThat(message).contains("java");
+    String json = new String(captor.getValue());
+    assertJson(json)
+      .withStrictArrayOrder()
+      .isSimilarTo(getClass().getResource("rule-change-event.json"));
   }
 
   @Test
@@ -116,7 +120,7 @@ public class SonarLintClientsRegistryTest {
 
     underTest.registerClient(sonarLintClient);
 
-    RuleChange javaRuleChange = createRuleChange("java");
+    RuleChange javaRuleChange = createRuleChange();
 
     RuleChange[] activatedRules = {};
     RuleChange[] deactivatedRules = {javaRuleChange};
@@ -136,7 +140,7 @@ public class SonarLintClientsRegistryTest {
 
     underTest.registerClient(sonarLintClient);
 
-    RuleChange javaRuleChange = createRuleChange("java");
+    RuleChange javaRuleChange = createRuleChange();
 
     RuleChange[] activatedRules = {};
     RuleChange[] deactivatedRules = {javaRuleChange};
@@ -150,7 +154,7 @@ public class SonarLintClientsRegistryTest {
 
   @Test
   public void listen_givenUserNotPermittedToReceiveEvent_closeConnection() {
-    RuleChange javaRuleChange = createRuleChange("java");
+    RuleChange javaRuleChange = createRuleChange();
     RuleChange[] activatedRules = {};
     RuleChange[] deactivatedRules = {javaRuleChange};
     RuleSetChangeEvent ruleChangeEvent = new RuleSetChangeEvent(exampleKeys.toArray(String[]::new), activatedRules, deactivatedRules);
@@ -172,10 +176,13 @@ public class SonarLintClientsRegistryTest {
     return mock;
   }
 
-  private RuleChange createRuleChange(String language) {
+  private RuleChange createRuleChange() {
     RuleChange javaRule = new RuleChange();
-    javaRule.setLanguage(language);
-
+    javaRule.setLanguage("java");
+    javaRule.setParams(new ParamChange[]{new ParamChange("param-key", "param-value")});
+    javaRule.setTemplateKey("template-key");
+    javaRule.setSeverity(Severity.CRITICAL);
+    javaRule.setKey("rule-key");
     return javaRule;
   }
 
diff --git a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/qualityprofile/builtin/QualityProfileChangeEventServiceImplTest.java b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/qualityprofile/builtin/QualityProfileChangeEventServiceImplTest.java
new file mode 100644 (file)
index 0000000..4d731df
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.qualityprofile.builtin;
+
+import java.util.Collection;
+import java.util.Collections;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.core.util.ParamChange;
+import org.sonar.core.util.RuleChange;
+import org.sonar.core.util.RuleSetChangeEvent;
+import org.sonar.db.DbTester;
+import org.sonar.db.project.ProjectDto;
+import org.sonar.db.qualityprofile.ActiveRuleDto;
+import org.sonar.db.qualityprofile.ActiveRuleParamDto;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.qualityprofile.QualityProfileTesting;
+import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleParamDto;
+import org.sonar.server.pushapi.qualityprofile.QualityProfileChangeEventServiceImpl;
+import org.sonar.server.pushapi.qualityprofile.RuleActivatorEventsDistributor;
+import org.sonar.server.qualityprofile.ActiveRuleChange;
+
+import static java.util.List.of;
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.sonar.db.rule.RuleDto.Format.MARKDOWN;
+import static org.sonar.db.rule.RuleTesting.newCustomRule;
+import static org.sonar.db.rule.RuleTesting.newTemplateRule;
+import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.ACTIVATED;
+
+public class QualityProfileChangeEventServiceImplTest {
+
+  @Rule
+  public DbTester db = DbTester.create();
+
+  RuleActivatorEventsDistributor eventsDistributor = mock(RuleActivatorEventsDistributor.class);
+
+  public final QualityProfileChangeEventServiceImpl underTest = new QualityProfileChangeEventServiceImpl(db.getDbClient(), eventsDistributor);
+
+  @Test
+  public void distributeRuleChangeEvent() {
+    QProfileDto qualityProfileDto = QualityProfileTesting.newQualityProfileDto();
+
+    // Template rule
+    RuleDto templateRule = newTemplateRule(RuleKey.of("xoo", "template-key"));
+    db.rules().insert(templateRule.getDefinition());
+    // Custom rule
+    RuleDefinitionDto rule1 = newCustomRule(templateRule.getDefinition())
+      .setLanguage("xoo")
+      .setDescription("<div>line1\nline2</div>")
+      .setDescriptionFormat(MARKDOWN);
+    db.rules().insert(rule1);
+
+    ActiveRuleDto activeRuleDto = ActiveRuleDto.createFor(qualityProfileDto, rule1);
+
+    ActiveRuleChange activeRuleChange = new ActiveRuleChange(ACTIVATED, activeRuleDto, rule1);
+    activeRuleChange.setParameter("paramChangeKey", "paramChangeValue");
+
+    Collection<QProfileDto> profiles = Collections.singleton(qualityProfileDto);
+
+    ProjectDto project = db.components().insertPrivateProjectDto();
+    db.qualityProfiles().associateWithProject(project, qualityProfileDto);
+
+    underTest.distributeRuleChangeEvent(profiles, of(activeRuleChange), "xoo");
+
+    ArgumentCaptor<RuleSetChangeEvent> eventCaptor = ArgumentCaptor.forClass(RuleSetChangeEvent.class);
+    verify(eventsDistributor).pushEvent(eventCaptor.capture());
+
+    RuleSetChangeEvent ruleSetChangeEvent = eventCaptor.getValue();
+    assertThat(ruleSetChangeEvent).isNotNull();
+    assertThat(ruleSetChangeEvent).extracting(RuleSetChangeEvent::getEvent,
+        RuleSetChangeEvent::getLanguage, RuleSetChangeEvent::getProjects)
+      .containsExactly("RuleSetChange", "xoo", new String[]{project.getKey()});
+
+    assertThat(ruleSetChangeEvent.getActivatedRules())
+      .extracting(RuleChange::getKey, RuleChange::getLanguage,
+        RuleChange::getSeverity, RuleChange::getTemplateKey)
+      .containsExactly(tuple(rule1.getRuleKey(), "xoo", null, "template-key"));
+
+    assertThat(ruleSetChangeEvent.getActivatedRules()[0].getParams()).hasSize(1);
+    ParamChange actualParamChange = ruleSetChangeEvent.getActivatedRules()[0].getParams()[0];
+    assertThat(actualParamChange)
+      .extracting(ParamChange::getKey, ParamChange::getValue)
+      .containsExactly("paramChangeKey", "paramChangeValue");
+
+    assertThat(ruleSetChangeEvent.getDeactivatedRules()).isEmpty();
+
+  }
+
+  @Test
+  public void publishRuleActivationToSonarLintClients() {
+    ProjectDto projectDao = new ProjectDto();
+    QProfileDto activatedQualityProfile = QualityProfileTesting.newQualityProfileDto();
+    db.qualityProfiles().insert(activatedQualityProfile);
+    RuleDefinitionDto rule1 = db.rules().insert(r -> r.setLanguage("xoo"));
+    RuleParamDto rule1Param = db.rules().insertRuleParam(rule1);
+
+    ActiveRuleDto activeRule1 = db.qualityProfiles().activateRule(activatedQualityProfile, rule1);
+    ActiveRuleParamDto activeRuleParam1 = ActiveRuleParamDto.createFor(rule1Param).setValue(randomAlphanumeric(20));
+    db.getDbClient().activeRuleDao().insertParam(db.getSession(), activeRule1, activeRuleParam1);
+    db.getSession().commit();
+
+    QProfileDto deactivatedQualityProfile = QualityProfileTesting.newQualityProfileDto();
+    db.qualityProfiles().insert(deactivatedQualityProfile);
+    RuleDefinitionDto rule2 = db.rules().insert(r -> r.setLanguage("xoo"));
+    RuleParamDto rule2Param = db.rules().insertRuleParam(rule2);
+
+    ActiveRuleDto activeRule2 = db.qualityProfiles().activateRule(deactivatedQualityProfile, rule2);
+    ActiveRuleParamDto activeRuleParam2 = ActiveRuleParamDto.createFor(rule2Param).setValue(randomAlphanumeric(20));
+    db.getDbClient().activeRuleDao().insertParam(db.getSession(), activeRule2, activeRuleParam2);
+    db.getSession().commit();
+
+    underTest.publishRuleActivationToSonarLintClients(projectDao, activatedQualityProfile, deactivatedQualityProfile);
+
+    ArgumentCaptor<RuleSetChangeEvent> eventCaptor = ArgumentCaptor.forClass(RuleSetChangeEvent.class);
+    verify(eventsDistributor).pushEvent(eventCaptor.capture());
+
+    RuleSetChangeEvent ruleSetChangeEvent = eventCaptor.getValue();
+    assertThat(ruleSetChangeEvent).isNotNull();
+    assertThat(ruleSetChangeEvent).extracting(RuleSetChangeEvent::getEvent,
+        RuleSetChangeEvent::getLanguage, RuleSetChangeEvent::getProjects)
+      .containsExactly("RuleSetChange", "xoo", new String[]{null});
+
+    // activated rule
+    assertThat(ruleSetChangeEvent.getActivatedRules())
+      .extracting(RuleChange::getKey, RuleChange::getLanguage,
+        RuleChange::getSeverity, RuleChange::getTemplateKey)
+      .containsExactly(tuple(rule1.getRuleKey(), "xoo", rule1.getSeverityString(), null));
+
+    assertThat(ruleSetChangeEvent.getActivatedRules()[0].getParams()).hasSize(1);
+    ParamChange actualParamChange = ruleSetChangeEvent.getActivatedRules()[0].getParams()[0];
+    assertThat(actualParamChange)
+      .extracting(ParamChange::getKey, ParamChange::getValue)
+      .containsExactly(activeRuleParam1.getKey(), activeRuleParam1.getValue());
+
+    // deactivated rule
+    assertThat(ruleSetChangeEvent.getDeactivatedRules())
+      .extracting(RuleChange::getKey, RuleChange::getLanguage,
+        RuleChange::getSeverity, RuleChange::getTemplateKey)
+      .containsExactly(tuple(rule2.getRuleKey(), "xoo", rule2.getSeverityString(), null));
+
+    assertThat(ruleSetChangeEvent.getDeactivatedRules()[0].getParams()).hasSize(1);
+    ParamChange actualParamChangeDeactivated = ruleSetChangeEvent.getDeactivatedRules()[0].getParams()[0];
+    assertThat(actualParamChangeDeactivated)
+      .extracting(ParamChange::getKey, ParamChange::getValue)
+      .containsExactly(activeRuleParam2.getKey(), activeRuleParam2.getValue());
+  }
+
+}
diff --git a/server/sonar-webserver-pushapi/src/test/resources/org/sonar/server/pushapi/sonarlint/rule-change-event.json b/server/sonar-webserver-pushapi/src/test/resources/org/sonar/server/pushapi/sonarlint/rule-change-event.json
new file mode 100644 (file)
index 0000000..b60f1b8
--- /dev/null
@@ -0,0 +1,38 @@
+{
+  "data": {
+    "projects": [
+      "project2",
+      "project1",
+      "project3"
+    ],
+    "activatedRules": [
+      {
+        "key": "rule-key",
+        "templateKey": "template-key",
+        "severity": "CRITICAL",
+        "language": "java",
+        "params": [
+          {
+            "value": "param-value",
+            "key": "param-key"
+          }
+        ]
+      }
+    ],
+    "deactivatedRules": [
+      {
+        "key": "rule-key",
+        "templateKey": "template-key",
+        "severity": "CRITICAL",
+        "language": "java",
+        "params": [
+          {
+            "value": "param-value",
+            "key": "param-key"
+          }
+        ]
+      }
+    ]
+  },
+  "event": "RuleSetChange"
+}
index cff868518376c3e34a4cf957e65e8b3ffadf3ea7..b0e282ef569ec43a78377e63285aece9cbe61b95 100644 (file)
@@ -19,7 +19,9 @@
  */
 package org.sonar.core.util;
 
-public class ParamChange {
+import java.io.Serializable;
+
+public class ParamChange implements Serializable {
   String key;
   String value;
 
index 60de8040b9763b95a24974aeb3e1d49441139972..3bb3af5b745e380b3e797d415ef7561a4b160815 100644 (file)
@@ -34,8 +34,9 @@ public class RuleChange implements Serializable {
     return key;
   }
 
-  public void setKey(String key) {
+  public RuleChange setKey(String key) {
     this.key = key;
+    return this;
   }
 
   @CheckForNull
@@ -43,16 +44,18 @@ public class RuleChange implements Serializable {
     return language;
   }
 
-  public void setLanguage(@Nullable String language) {
+  public RuleChange setLanguage(@Nullable String language) {
     this.language = language;
+    return this;
   }
 
   public String getTemplateKey() {
     return templateKey;
   }
 
-  public void setTemplateKey(String templateKey) {
+  public RuleChange setTemplateKey(String templateKey) {
     this.templateKey = templateKey;
+    return this;
   }
 
   @CheckForNull
@@ -60,15 +63,17 @@ public class RuleChange implements Serializable {
     return severity;
   }
 
-  public void setSeverity(@Nullable String severity) {
+  public RuleChange setSeverity(@Nullable String severity) {
     this.severity = severity;
+    return this;
   }
 
   public ParamChange[] getParams() {
     return params;
   }
 
-  public void setParams(ParamChange[] params) {
+  public RuleChange setParams(ParamChange[] params) {
     this.params = params;
+    return this;
   }
 }