]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6906 Filter rules on profile language when bulk active rules 938/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 4 May 2016 15:31:53 +0000 (17:31 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 10 May 2016 08:57:16 +0000 (10:57 +0200)
13 files changed:
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java
server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleQueryFactoryTest.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/bulk_activate_rule.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/bulk_activate_rule_not_all.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json [new file with mode: 0644]
sonar-ws/src/main/java/org/sonarqube/ws/client/rule/RulesService.java
sonar-ws/src/test/java/org/sonarqube/ws/client/rule/RulesServiceTest.java

index b617008eb74eb8433e83fd1837ce54d1a0a6d99c..40de895205699048fd1be6d057c8cd357ffcc71d 100644 (file)
@@ -251,6 +251,7 @@ import org.sonar.server.rule.index.RuleIndexer;
 import org.sonar.server.rule.ws.ActiveRuleCompleter;
 import org.sonar.server.rule.ws.RepositoriesAction;
 import org.sonar.server.rule.ws.RuleMapper;
+import org.sonar.server.rule.ws.RuleQueryFactory;
 import org.sonar.server.rule.ws.RulesWs;
 import org.sonar.server.rule.ws.TagsAction;
 import org.sonar.server.source.HtmlSourceDecorator;
@@ -442,6 +443,7 @@ public class PlatformLevel4 extends PlatformLevel {
       RuleMapper.class,
       ActiveRuleCompleter.class,
       RepositoriesAction.class,
+      RuleQueryFactory.class,
       org.sonar.server.rule.ws.AppAction.class,
 
       // languages
index 82fc1c3ce764e11f6dfcd41c20532f8ffa3473b8..bb48610221af8c4c7844d0b35dae7ed63e855518 100644 (file)
 package org.sonar.server.qualityprofile.ws;
 
 import org.sonar.api.i18n.I18n;
-import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
-import org.sonar.api.rules.RuleType;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.RequestHandler;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.db.DbClient;
 import org.sonar.server.qualityprofile.BulkChangeResult;
 import org.sonar.server.qualityprofile.QProfileService;
-import org.sonar.server.rule.RuleService;
-import org.sonar.server.rule.index.RuleQuery;
-import org.sonar.server.rule.ws.SearchAction;
+import org.sonar.server.rule.ws.RuleQueryFactory;
 import org.sonar.server.user.UserSession;
 
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVATION;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_INHERITANCE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_IS_TEMPLATE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_REPOSITORIES;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_SEVERITIES;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_STATUSES;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TAGS;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TEMPLATE_KEY;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TYPES;
+import static org.sonar.server.rule.ws.SearchAction.defineRuleSearchParameters;
 
 @ServerSide
 public class BulkRuleActivationActions {
@@ -62,16 +43,14 @@ public class BulkRuleActivationActions {
   public static final String BULK_ACTIVATE_ACTION = "activate_rules";
   public static final String BULK_DEACTIVATE_ACTION = "deactivate_rules";
 
-  private final DbClient dbClient;
   private final QProfileService profileService;
-  private final RuleService ruleService;
+  private final RuleQueryFactory ruleQueryFactory;
   private final I18n i18n;
   private final UserSession userSession;
 
-  public BulkRuleActivationActions(DbClient dbClient, QProfileService profileService, RuleService ruleService, I18n i18n, UserSession userSession) {
-    this.dbClient = dbClient;
+  public BulkRuleActivationActions(QProfileService profileService, RuleQueryFactory ruleQueryFactory, I18n i18n, UserSession userSession) {
     this.profileService = profileService;
-    this.ruleService = ruleService;
+    this.ruleQueryFactory = ruleQueryFactory;
     this.i18n = i18n;
     this.userSession = userSession;
   }
@@ -94,7 +73,7 @@ public class BulkRuleActivationActions {
         }
       });
 
-    SearchAction.defineRuleSearchParameters(activate);
+    defineRuleSearchParameters(activate);
     defineProfileKeyParameter(activate);
 
     activate.createParam(SEVERITY)
@@ -115,7 +94,7 @@ public class BulkRuleActivationActions {
         }
       });
 
-    SearchAction.defineRuleSearchParameters(deactivate);
+    defineRuleSearchParameters(deactivate);
     defineProfileKeyParameter(deactivate);
   }
 
@@ -128,45 +107,19 @@ public class BulkRuleActivationActions {
 
   private void bulkActivate(Request request, Response response) {
     BulkChangeResult result = profileService.bulkActivate(
-      createRuleQuery(ruleService.newRuleQuery(), request),
+      ruleQueryFactory.createRuleQuery(request),
       request.mandatoryParam(PROFILE_KEY),
       request.param(SEVERITY));
     writeResponse(result, response);
   }
 
   private void bulkDeactivate(Request request, Response response) {
-    // TODO filter on rule language
     BulkChangeResult result = profileService.bulkDeactivate(
-      createRuleQuery(ruleService.newRuleQuery(), request),
+      ruleQueryFactory.createRuleQuery(request),
       request.mandatoryParam(PROFILE_KEY));
     writeResponse(result, response);
   }
 
-  private static RuleQuery createRuleQuery(RuleQuery query, Request request) {
-    query.setQueryText(request.param(Param.TEXT_QUERY));
-    query.setSeverities(request.paramAsStrings(PARAM_SEVERITIES));
-    query.setRepositories(request.paramAsStrings(PARAM_REPOSITORIES));
-    query.setAvailableSince(request.hasParam(PARAM_AVAILABLE_SINCE) ? request.paramAsDate(PARAM_AVAILABLE_SINCE).getTime() : null);
-    query.setStatuses(request.paramAsEnums(PARAM_STATUSES, RuleStatus.class));
-    query.setLanguages(request.paramAsStrings(PARAM_LANGUAGES));
-    query.setActivation(request.paramAsBoolean(PARAM_ACTIVATION));
-    query.setQProfileKey(request.param(PARAM_QPROFILE));
-    query.setTags(request.paramAsStrings(PARAM_TAGS));
-    query.setInheritance(request.paramAsStrings(PARAM_INHERITANCE));
-    query.setActiveSeverities(request.paramAsStrings(PARAM_ACTIVE_SEVERITIES));
-    query.setIsTemplate(request.paramAsBoolean(PARAM_IS_TEMPLATE));
-    query.setTemplateKey(request.param(PARAM_TEMPLATE_KEY));
-    query.setTypes(request.paramAsEnums(PARAM_TYPES, RuleType.class));
-    query.setKey(request.param(PARAM_RULE_KEY));
-
-    String sortParam = request.param(Param.SORT);
-    if (sortParam != null) {
-      query.setSortField(sortParam);
-      query.setAscendingSort(request.mandatoryParamAsBoolean(Param.ASCENDING));
-    }
-    return query;
-  }
-
   private void writeResponse(BulkChangeResult result, Response response) {
     JsonWriter json = response.newJsonWriter().beginObject();
     json.prop("succeeded", result.countSucceeded());
diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java
new file mode 100644 (file)
index 0000000..746bd3c
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.rule.ws;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Date;
+import javax.annotation.CheckForNull;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rules.RuleType;
+import org.sonar.api.server.ServerSide;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.server.rule.index.RuleQuery;
+
+import static org.sonar.server.util.EnumUtils.toEnums;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVATION;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_INHERITANCE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_IS_TEMPLATE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_REPOSITORIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_SEVERITIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_STATUSES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TAGS;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TEMPLATE_KEY;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TYPES;
+
+@ServerSide
+public class RuleQueryFactory {
+
+  private final DbClient dbClient;
+
+  public RuleQueryFactory(DbClient dbClient) {
+    this.dbClient = dbClient;
+  }
+
+  /**
+   * Create a {@link RuleQuery} from a {@link Request}.
+   * When a profile key is set, the language of the profile is automatically set in the query
+   */
+  public RuleQuery createRuleQuery(Request request) {
+    RuleQuery ruleQuery = createRuleQuery(new RuleQuery(), request);
+
+    String qProfileKey = ruleQuery.getQProfileKey();
+    if (qProfileKey != null) {
+      QualityProfileDto qProfile = getProfileByKey(qProfileKey);
+      if (qProfile != null) {
+        ruleQuery.setLanguages(ImmutableList.of(qProfile.getLanguage()));
+      }
+    }
+    return ruleQuery;
+  }
+
+  private static RuleQuery createRuleQuery(RuleQuery query, Request request) {
+    query.setQueryText(request.param(WebService.Param.TEXT_QUERY));
+    query.setSeverities(request.paramAsStrings(PARAM_SEVERITIES));
+    query.setRepositories(request.paramAsStrings(PARAM_REPOSITORIES));
+    Date availableSince = request.paramAsDate(PARAM_AVAILABLE_SINCE);
+    query.setAvailableSince(availableSince != null ? availableSince.getTime() : null);
+    query.setStatuses(toEnums(request.paramAsStrings(PARAM_STATUSES), RuleStatus.class));
+    query.setLanguages(request.paramAsStrings(PARAM_LANGUAGES));
+    query.setActivation(request.paramAsBoolean(PARAM_ACTIVATION));
+    query.setQProfileKey(request.param(PARAM_QPROFILE));
+    query.setTags(request.paramAsStrings(PARAM_TAGS));
+    query.setInheritance(request.paramAsStrings(PARAM_INHERITANCE));
+    query.setActiveSeverities(request.paramAsStrings(PARAM_ACTIVE_SEVERITIES));
+    query.setIsTemplate(request.paramAsBoolean(PARAM_IS_TEMPLATE));
+    query.setTemplateKey(request.param(PARAM_TEMPLATE_KEY));
+    query.setTypes(toEnums(request.paramAsStrings(PARAM_TYPES), RuleType.class));
+    query.setKey(request.param(PARAM_RULE_KEY));
+
+    String sortParam = request.param(WebService.Param.SORT);
+    if (sortParam != null) {
+      query.setSortField(sortParam);
+      query.setAscendingSort(request.mandatoryParamAsBoolean(WebService.Param.ASCENDING));
+    }
+    return query;
+  }
+
+  @CheckForNull
+  private QualityProfileDto getProfileByKey(String key) {
+    DbSession dbSession = dbClient.openSession(false);
+    try {
+      return dbClient.qualityProfileDao().selectByKey(dbSession, key);
+    } finally {
+      dbSession.close();
+    }
+  }
+
+}
index f59dd90752c8788b036d0368e747c8c896c07ab7..ac49acb76e624aaae1f99b617eb388fed32bd314 100644 (file)
@@ -22,7 +22,6 @@ package org.sonar.server.rule.ws;
 import com.google.common.base.Function;
 import com.google.common.base.Predicates;
 import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Lists;
@@ -50,7 +49,6 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.db.qualityprofile.QualityProfileDto;
 import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleParamDto;
 import org.sonar.server.es.Facets;
@@ -65,7 +63,6 @@ import org.sonarqube.ws.Rules.SearchResponse;
 import org.sonarqube.ws.client.rule.SearchWsRequest;
 
 import static com.google.common.collect.FluentIterable.from;
-import static org.sonar.api.utils.DateUtils.parseDate;
 import static org.sonar.server.rule.index.RuleIndex.ALL_STATUSES_EXCEPT_REMOVED;
 import static org.sonar.server.rule.index.RuleIndex.FACET_ACTIVE_SEVERITIES;
 import static org.sonar.server.rule.index.RuleIndex.FACET_LANGUAGES;
@@ -75,7 +72,6 @@ import static org.sonar.server.rule.index.RuleIndex.FACET_SEVERITIES;
 import static org.sonar.server.rule.index.RuleIndex.FACET_STATUSES;
 import static org.sonar.server.rule.index.RuleIndex.FACET_TAGS;
 import static org.sonar.server.rule.index.RuleIndex.FACET_TYPES;
-import static org.sonar.server.util.EnumUtils.toEnums;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.OPTIONAL_FIELDS;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVATION;
@@ -101,14 +97,16 @@ public class SearchAction implements RulesWsAction {
 
   private static final Collection<String> DEFAULT_FACETS = ImmutableSet.of(PARAM_LANGUAGES, PARAM_REPOSITORIES, "tags");
 
+  private final RuleQueryFactory ruleQueryFactory;
   private final DbClient dbClient;
   private final RuleIndex ruleIndex;
   private final ActiveRuleCompleter activeRuleCompleter;
   private final RuleMapper mapper;
 
-  public SearchAction(RuleIndex ruleIndex, ActiveRuleCompleter activeRuleCompleter, DbClient dbClient, RuleMapper mapper) {
+  public SearchAction(RuleIndex ruleIndex, ActiveRuleCompleter activeRuleCompleter, RuleQueryFactory ruleQueryFactory, DbClient dbClient, RuleMapper mapper) {
     this.ruleIndex = ruleIndex;
     this.activeRuleCompleter = activeRuleCompleter;
+    this.ruleQueryFactory = ruleQueryFactory;
     this.dbClient = dbClient;
     this.mapper = mapper;
   }
@@ -150,19 +148,19 @@ public class SearchAction implements RulesWsAction {
     try {
       SearchWsRequest searchWsRequest = toSearchWsRequest(request);
       org.sonar.server.es.SearchOptions context = getQueryContext(searchWsRequest);
-      RuleQuery query = doQuery(searchWsRequest);
+      RuleQuery query = ruleQueryFactory.createRuleQuery(request);
       SearchResult searchResult = doSearch(dbSession, query, context);
-      SearchResponse responseBuilder = buildResponse(dbSession, searchWsRequest, context, searchResult);
+      SearchResponse responseBuilder = buildResponse(dbSession, searchWsRequest, context, searchResult, query);
       writeProtobuf(responseBuilder, request, response);
     } finally {
       dbClient.closeSession(dbSession);
     }
   }
 
-  private SearchResponse buildResponse(DbSession dbSession, SearchWsRequest request, SearchOptions context, SearchResult result) {
+  private SearchResponse buildResponse(DbSession dbSession, SearchWsRequest request, SearchOptions context, SearchResult result, RuleQuery query) {
     SearchResponse.Builder responseBuilder = SearchResponse.newBuilder();
     writeStatistics(responseBuilder, result, context);
-    doContextResponse(dbSession, request, result, responseBuilder);
+    doContextResponse(dbSession, request, result, responseBuilder, query);
     if (!context.getFacets().isEmpty()) {
       writeFacets(responseBuilder, request, context, result);
     }
@@ -311,31 +309,6 @@ public class SearchAction implements RulesWsAction {
       .setDefaultValue(true);
   }
 
-  private static RuleQuery createRuleQuery(RuleQuery query, SearchWsRequest request) {
-    query.setQueryText(request.getQuery());
-    query.setSeverities(request.getSeverities());
-    query.setRepositories(request.getRepositories());
-    query.setAvailableSince(request.getAvailableSince() != null ? parseDate(request.getAvailableSince()).getTime() : null);
-    query.setStatuses(toEnums(request.getStatuses(), RuleStatus.class));
-    query.setLanguages(request.getLanguages());
-    query.setActivation(request.getActivation());
-    query.setQProfileKey(request.getQProfile());
-    query.setTags(request.getTags());
-    query.setInheritance(request.getInheritance());
-    query.setActiveSeverities(request.getActiveSeverities());
-    query.setIsTemplate(request.getIsTemplate());
-    query.setTemplateKey(request.getTemplateKey());
-    query.setTypes(toEnums(request.getTypes(), RuleType.class));
-    query.setKey(request.getRuleKey());
-
-    String sortParam = request.getSort();
-    if (sortParam != null) {
-      query.setSortField(sortParam);
-      query.setAscendingSort(request.getAsc());
-    }
-    return query;
-  }
-
   private void writeRules(SearchResponse.Builder response, SearchResult result, org.sonar.server.es.SearchOptions context) {
     for (RuleDto rule : result.rules) {
       response.addRules(mapper.toWsRule(rule, result, context.getFields()));
@@ -343,7 +316,6 @@ public class SearchAction implements RulesWsAction {
   }
 
   protected org.sonar.server.es.SearchOptions getQueryContext(SearchWsRequest request) {
-    // TODO Get rid of this horrible hack: fields on request are not the same as fields for ES search ! 1/2
     org.sonar.server.es.SearchOptions context = loadCommonContext(request);
     org.sonar.server.es.SearchOptions searchQueryContext = new org.sonar.server.es.SearchOptions()
       .setLimit(context.getLimit())
@@ -404,26 +376,11 @@ public class SearchAction implements RulesWsAction {
       .setTotal(result.getTotal());
   }
 
-  protected RuleQuery doQuery(SearchWsRequest request) {
-    RuleQuery plainQuery = createRuleQuery(new RuleQuery(), request);
-
-    String qProfileKey = request.getQProfile();
-    if (qProfileKey != null) {
-      QualityProfileDto qProfile = activeRuleCompleter.loadProfile(qProfileKey);
-      if (qProfile != null) {
-        plainQuery.setLanguages(ImmutableList.of(qProfile.getLanguage()));
-      }
-    }
-
-    return plainQuery;
-  }
-
-  protected void doContextResponse(DbSession dbSession, SearchWsRequest request, SearchResult result, SearchResponse.Builder response) {
-    // TODO Get rid of this horrible hack: fields on request are not the same as fields for ES search ! 2/2
+  protected void doContextResponse(DbSession dbSession, SearchWsRequest request, SearchResult result, SearchResponse.Builder response, RuleQuery query) {
     org.sonar.server.es.SearchOptions contextForResponse = loadCommonContext(request);
     writeRules(response, result, contextForResponse);
     if (contextForResponse.getFields().contains("actives")) {
-      activeRuleCompleter.completeSearch(dbSession, doQuery(request), result.rules, response);
+      activeRuleCompleter.completeSearch(dbSession, query, result.rules, response);
     }
   }
 
@@ -600,13 +557,4 @@ public class SearchAction implements RulesWsAction {
     }
   }
 
-  private enum TypeToString implements Function<RuleType, String> {
-    INSTANCE;
-
-    @Override
-    public String apply(@Nonnull RuleType input) {
-      return input.name();
-    }
-
-  }
 }
index c7bb601ad5371b51acec7387a05d6f3cfc28f206..975d3fc9f80ed07c07286da982037bbdf62c7ee4 100644 (file)
@@ -56,6 +56,7 @@ import org.sonar.server.ws.WsTester;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
 
 public class QProfilesWsMediumTest {
 
@@ -269,10 +270,10 @@ public class QProfilesWsMediumTest {
   @Test
   public void bulk_activate_rule() throws Exception {
     QualityProfileDto profile = createProfile("java");
-    RuleDto rule0 = createRule(profile.getLanguage(), "toto");
-    RuleDto rule1 = createRule(profile.getLanguage(), "tata");
-    RuleDto rule2 = createRule(profile.getLanguage(), "hello");
-    RuleDto rule3 = createRule(profile.getLanguage(), "world");
+    createRule(profile.getLanguage(), "toto");
+    createRule(profile.getLanguage(), "tata");
+    createRule(profile.getLanguage(), "hello");
+    createRule(profile.getLanguage(), "world");
     session.commit();
     ruIndexer.index();
 
@@ -283,7 +284,7 @@ public class QProfilesWsMediumTest {
     WsTester.TestRequest request = wsTester.newPostRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION);
     request.setParam(RuleActivationActions.PROFILE_KEY, profile.getKey());
     request.setParam(PARAM_LANGUAGES, "java");
-    WsTester.Result result = request.execute();
+    request.execute().assertJson(getClass(), "bulk_activate_rule.json");
     session.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -294,10 +295,10 @@ public class QProfilesWsMediumTest {
   public void bulk_activate_rule_not_all() throws Exception {
     QualityProfileDto java = createProfile("java");
     QualityProfileDto php = createProfile("php");
-    RuleDto rule0 = createRule(java.getLanguage(), "toto");
-    RuleDto rule1 = createRule(java.getLanguage(), "tata");
-    RuleDto rule2 = createRule(php.getLanguage(), "hello");
-    RuleDto rule3 = createRule(php.getLanguage(), "world");
+    createRule(java.getLanguage(), "toto");
+    createRule(java.getLanguage(), "tata");
+    createRule(php.getLanguage(), "hello");
+    createRule(php.getLanguage(), "world");
     session.commit();
     ruIndexer.index();
 
@@ -308,7 +309,7 @@ public class QProfilesWsMediumTest {
     WsTester.TestRequest request = wsTester.newPostRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION);
     request.setParam(RuleActivationActions.PROFILE_KEY, php.getKey());
     request.setParam(PARAM_LANGUAGES, "php");
-    WsTester.Result result = request.execute();
+    request.execute().assertJson(getClass(), "bulk_activate_rule_not_all.json");
     session.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -318,10 +319,10 @@ public class QProfilesWsMediumTest {
   @Test
   public void bulk_activate_rule_by_query() throws Exception {
     QualityProfileDto profile = createProfile("java");
-    RuleDto rule0 = createRule(profile.getLanguage(), "toto");
-    RuleDto rule1 = createRule(profile.getLanguage(), "tata");
-    RuleDto rule2 = createRule(profile.getLanguage(), "hello");
-    RuleDto rule3 = createRule(profile.getLanguage(), "world");
+    createRule(profile.getLanguage(), "toto");
+    createRule(profile.getLanguage(), "tata");
+    createRule(profile.getLanguage(), "hello");
+    createRule(profile.getLanguage(), "world");
     session.commit();
     ruIndexer.index();
 
@@ -332,7 +333,7 @@ public class QProfilesWsMediumTest {
     WsTester.TestRequest request = wsTester.newPostRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION);
     request.setParam(RuleActivationActions.PROFILE_KEY, profile.getKey());
     request.setParam(WebService.Param.TEXT_QUERY, "php");
-    WsTester.Result result = request.execute();
+    request.execute();
     session.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -342,7 +343,7 @@ public class QProfilesWsMediumTest {
     request = wsTester.newPostRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION);
     request.setParam(RuleActivationActions.PROFILE_KEY, profile.getKey());
     request.setParam(WebService.Param.TEXT_QUERY, "world");
-    result = request.execute();
+    request.execute();
     session.commit();
 
     // 2. Assert ActiveRule in DAO
@@ -375,7 +376,29 @@ public class QProfilesWsMediumTest {
 
     // 2. Assert ActiveRule with MINOR severity
     assertThat(tester.get(ActiveRuleIndex.class).findByRule(rule0.getKey()).get(0).severity()).isEqualTo("MINOR");
+  }
 
+  @Test
+  public void does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile() throws Exception {
+    QualityProfileDto javaProfile = createProfile("java");
+    createRule(javaProfile.getLanguage(), "toto");
+    createRule(javaProfile.getLanguage(), "tata");
+    QualityProfileDto phpProfile = createProfile("php");
+    createRule(phpProfile.getLanguage(), "hello");
+    createRule(phpProfile.getLanguage(), "world");
+    session.commit();
+    ruIndexer.index();
+
+    // 1. Activate Rule
+    WsTester.TestRequest request = wsTester.newPostRequest(QProfilesWs.API_ENDPOINT, BulkRuleActivationActions.BULK_ACTIVATE_ACTION);
+    request.setParam(RuleActivationActions.PROFILE_KEY, javaProfile.getKey());
+    request.setParam(PARAM_QPROFILE, javaProfile.getKey());
+    request.setParam("activation", "false");
+    request.execute().assertJson(getClass(), "does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json");
+    session.clearCache();
+
+    // 2. Assert ActiveRule in DAO
+    assertThat(db.activeRuleDao().selectByProfileKey(session, javaProfile.getKey())).hasSize(2);
   }
 
   @Test
index 2e7597413a031bc18ca25df932a60c9d3c49dcf5..3ae6c3107312cabd66334ed483c9e13bcbe5750a 100644 (file)
@@ -33,7 +33,6 @@ import org.sonar.api.utils.ValidationMessages;
 import org.sonar.server.language.LanguageTesting;
 import org.sonar.server.qualityprofile.QProfileExporters;
 import org.sonar.server.qualityprofile.QProfileService;
-import org.sonar.server.rule.RuleService;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsTester;
 
@@ -52,7 +51,6 @@ public class QProfilesWsTest {
   @Before
   public void setUp() {
     QProfileService profileService = mock(QProfileService.class);
-    RuleService ruleService = mock(RuleService.class);
     I18n i18n = mock(I18n.class);
 
     Languages languages = LanguageTesting.newLanguages(xoo1Key, xoo2Key);
@@ -61,7 +59,7 @@ public class QProfilesWsTest {
 
     controller = new WsTester(new QProfilesWs(
       new RuleActivationActions(profileService),
-      new BulkRuleActivationActions(null, profileService, ruleService, i18n, userSessionRule),
+      new BulkRuleActivationActions(profileService, null, i18n, userSessionRule),
       new ProjectAssociationActions(null, null, null, languages, userSessionRule),
       new CreateAction(null, null, null, languages, importers, userSessionRule),
       new ImportersAction(importers),
@@ -79,8 +77,7 @@ public class QProfilesWsTest {
       new ExportAction(null, null, null, mock(QProfileExporters.class), languages),
       new ExportersAction(),
       new InheritanceAction(null, null, null, null, languages),
-      new RenameAction(null, userSessionRule)
-      )).controller(QProfilesWs.API_ENDPOINT);
+      new RenameAction(null, userSessionRule))).controller(QProfilesWs.API_ENDPOINT);
   }
 
   private ProfileImporter[] createImporters(Languages languages) {
@@ -236,8 +233,7 @@ public class QProfilesWsTest {
     assertThat(changelog).isNotNull();
     assertThat(changelog.isPost()).isFalse();
     assertThat(changelog.params()).hasSize(7).extracting("key").containsOnly(
-      "profileKey", "profileName", "language", "since", "to", "p", "ps"
-      );
+      "profileKey", "profileName", "language", "since", "to", "p", "ps");
     assertThat(changelog.responseExampleAsString()).isNotEmpty();
   }
 
@@ -247,8 +243,7 @@ public class QProfilesWsTest {
     assertThat(changeParent).isNotNull();
     assertThat(changeParent.isPost()).isTrue();
     assertThat(changeParent.params()).hasSize(5).extracting("key").containsOnly(
-      "profileKey", "profileName", "language", "parentKey", "parentName"
-      );
+      "profileKey", "profileName", "language", "parentKey", "parentName");
   }
 
   @Test
@@ -258,8 +253,7 @@ public class QProfilesWsTest {
     assertThat(compare.isPost()).isFalse();
     assertThat(compare.isInternal()).isTrue();
     assertThat(compare.params()).hasSize(2).extracting("key").containsOnly(
-      "leftKey", "rightKey"
-      );
+      "leftKey", "rightKey");
     assertThat(compare.responseExampleAsString()).isNotEmpty();
   }
 
@@ -269,8 +263,7 @@ public class QProfilesWsTest {
     assertThat(copy).isNotNull();
     assertThat(copy.isPost()).isTrue();
     assertThat(copy.params()).hasSize(2).extracting("key").containsOnly(
-      "fromKey", "toName"
-      );
+      "fromKey", "toName");
   }
 
   @Test
@@ -279,8 +272,7 @@ public class QProfilesWsTest {
     assertThat(delete).isNotNull();
     assertThat(delete.isPost()).isTrue();
     assertThat(delete.params()).hasSize(3).extracting("key").containsOnly(
-      "profileKey", "language", "profileName"
-      );
+      "profileKey", "language", "profileName");
   }
 
   @Test
@@ -289,8 +281,7 @@ public class QProfilesWsTest {
     assertThat(export).isNotNull();
     assertThat(export.isPost()).isFalse();
     assertThat(export.params()).hasSize(2).extracting("key").containsOnly(
-      "language", "name"
-      );
+      "language", "name");
   }
 
   @Test
@@ -308,8 +299,7 @@ public class QProfilesWsTest {
     assertThat(inheritance).isNotNull();
     assertThat(inheritance.isPost()).isFalse();
     assertThat(inheritance.params()).hasSize(3).extracting("key").containsOnly(
-      "profileKey", "language", "profileName"
-      );
+      "profileKey", "language", "profileName");
     assertThat(inheritance.responseExampleAsString()).isNotEmpty();
   }
 
@@ -319,7 +309,6 @@ public class QProfilesWsTest {
     assertThat(rename).isNotNull();
     assertThat(rename.isPost()).isTrue();
     assertThat(rename.params()).hasSize(2).extracting("key").containsOnly(
-      "key", "name"
-      );
+      "key", "name");
   }
 }
index 6ac245f23398368f1f2bf95092bbae18061af3a0..2f0fb5e6f5b3d861f899cd8efff6213b4c1a6465 100644 (file)
@@ -253,8 +253,7 @@ public class RuleIndexTest {
       newDoc(RULE_KEY_1).setType(CODE_SMELL),
       newDoc(RULE_KEY_2).setType(VULNERABILITY),
       newDoc(RULE_KEY_3).setType(BUG),
-      newDoc(RULE_KEY_4).setType(BUG)
-    );
+      newDoc(RULE_KEY_4).setType(BUG));
 
     // find all
     RuleQuery query = new RuleQuery();
@@ -265,7 +264,7 @@ public class RuleIndexTest {
     assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RULE_KEY_2);
 
     query = new RuleQuery().setTypes(ImmutableSet.of(BUG));
-    assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RULE_KEY_3,RULE_KEY_4);
+    assertThat(index.search(query, new SearchOptions()).getIds()).containsOnly(RULE_KEY_3, RULE_KEY_4);
 
     // types in query => nothing
     query = new RuleQuery().setQueryText("code smell bug vulnerability");
@@ -458,54 +457,54 @@ public class RuleIndexTest {
     // 1. get all active rules
     assertThat(index.search(new RuleQuery()
       .setActivation(true), new SearchOptions()).getIds())
-      .hasSize(3);
+        .hasSize(3);
 
     // 2. get all inactive rules.
     assertThat(index.search(new RuleQuery()
       .setActivation(false), new SearchOptions()).getIds())
-      .containsOnly(RULE_KEY_4);
+        .containsOnly(RULE_KEY_4);
 
     // 3. get Inherited Rules on profile1
     assertThat(index.search(new RuleQuery().setActivation(true)
       .setQProfileKey(QUALITY_PROFILE_KEY1)
       .setInheritance(ImmutableSet.of(INHERITED.name())),
       new SearchOptions()).getIds())
-      .isEmpty();
+        .isEmpty();
 
     // 4. get Inherited Rules on profile2
     assertThat(index.search(new RuleQuery().setActivation(true)
       .setQProfileKey(QUALITY_PROFILE_KEY2)
       .setInheritance(ImmutableSet.of(INHERITED.name())),
       new SearchOptions()).getIds())
-      .hasSize(2);
+        .hasSize(2);
 
     // 5. get Overridden Rules on profile1
     assertThat(index.search(new RuleQuery().setActivation(true)
       .setQProfileKey(QUALITY_PROFILE_KEY1)
       .setInheritance(ImmutableSet.of(OVERRIDES.name())),
       new SearchOptions()).getIds())
-      .isEmpty();
+        .isEmpty();
 
     // 6. get Overridden Rules on profile2
     assertThat(index.search(new RuleQuery().setActivation(true)
       .setQProfileKey(QUALITY_PROFILE_KEY2)
       .setInheritance(ImmutableSet.of(OVERRIDES.name())),
       new SearchOptions()).getIds())
-      .hasSize(1);
+        .hasSize(1);
 
     // 7. get Inherited AND Overridden Rules on profile1
     assertThat(index.search(new RuleQuery().setActivation(true)
       .setQProfileKey(QUALITY_PROFILE_KEY1)
       .setInheritance(ImmutableSet.of(INHERITED.name(), OVERRIDES.name())),
       new SearchOptions()).getIds())
-      .isEmpty();
+        .isEmpty();
 
     // 8. get Inherited AND Overridden Rules on profile2
     assertThat(index.search(new RuleQuery().setActivation(true)
       .setQProfileKey(QUALITY_PROFILE_KEY2)
       .setInheritance(ImmutableSet.of(INHERITED.name(), OVERRIDES.name())),
       new SearchOptions()).getIds())
-      .hasSize(3);
+        .hasSize(3);
   }
 
   @Test
@@ -623,8 +622,7 @@ public class RuleIndexTest {
 
     // 2 Facet with a language filter
     // -- lang facet should still have all language
-    result = index.search(new RuleQuery().setLanguages(ImmutableList.of("cpp"))
-      , new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
+    result = index.search(new RuleQuery().setLanguages(ImmutableList.of("cpp")), new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
     assertThat(result.getIds()).hasSize(3);
     assertThat(result.getFacets().getAll()).hasSize(3);
     assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java", "cobol");
@@ -635,8 +633,7 @@ public class RuleIndexTest {
     // -- repository for cpp & T2
     result = index.search(new RuleQuery()
       .setLanguages(ImmutableList.of("cpp"))
-      .setTags(ImmutableList.of("T2"))
-      , new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
+      .setTags(ImmutableList.of("T2")), new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS)));
     assertThat(result.getIds()).hasSize(1);
     assertThat(result.getFacets().getAll()).hasSize(3);
     assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java");
@@ -651,8 +648,7 @@ public class RuleIndexTest {
     result = index.search(new RuleQuery()
       .setLanguages(ImmutableList.of("cpp", "java"))
       .setTags(ImmutableList.of("T2"))
-      .setTypes(asList(BUG, CODE_SMELL))
-      , new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS, FACET_TYPES)));
+      .setTypes(asList(BUG, CODE_SMELL)), new SearchOptions().addFacets(asList(FACET_LANGUAGES, FACET_REPOSITORIES, FACET_TAGS, FACET_TYPES)));
     assertThat(result.getIds()).hasSize(2);
     assertThat(result.getFacets().getAll()).hasSize(4);
     assertThat(result.getFacets().get(FACET_LANGUAGES).keySet()).containsOnly("cpp", "java");
@@ -751,6 +747,33 @@ public class RuleIndexTest {
     assertThat(index.searchAll(new RuleQuery().setQueryText("javascript:X001"))).hasSize(1);
   }
 
+  @Test
+  public void search_all_keys_by_profile() {
+    indexRules(
+      newDoc(RULE_KEY_1),
+      newDoc(RULE_KEY_2),
+      newDoc(RULE_KEY_3));
+
+    indexActiveRules(
+      ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_1)),
+      ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY2, RULE_KEY_1)),
+      ActiveRuleDocTesting.newDoc(ActiveRuleKey.of(QUALITY_PROFILE_KEY1, RULE_KEY_2)));
+
+    assertThat(tester.countDocuments(INDEX, TYPE_ACTIVE_RULE)).isEqualTo(3);
+
+    // 1. get all active rules.
+    assertThat(index.searchAll(new RuleQuery().setActivation(true))).containsOnly(RULE_KEY_1, RULE_KEY_2);
+
+    // 2. get all inactive rules.
+    assertThat(index.searchAll(new RuleQuery().setActivation(false))).containsOnly(RULE_KEY_3);
+
+    // 3. get all rules not active on profile
+    assertThat(index.searchAll(new RuleQuery().setActivation(false).setQProfileKey(QUALITY_PROFILE_KEY2))).containsOnly(RULE_KEY_2, RULE_KEY_3);
+
+    // 4. get all active rules on profile
+    assertThat(index.searchAll(new RuleQuery().setActivation(true).setQProfileKey(QUALITY_PROFILE_KEY2))).containsOnly(RULE_KEY_1);
+  }
+
   private void indexRules(RuleDoc... rules) {
     ruleIndexer.index(asList(rules).iterator());
   }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleQueryFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleQueryFactoryTest.java
new file mode 100644 (file)
index 0000000..524ba14
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.rule.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.server.rule.index.RuleQuery;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.WsAction;
+import org.sonar.server.ws.WsActionTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.rule.RuleStatus.DEPRECATED;
+import static org.sonar.api.rule.RuleStatus.READY;
+import static org.sonar.api.rule.Severity.CRITICAL;
+import static org.sonar.api.rule.Severity.MAJOR;
+import static org.sonar.api.rule.Severity.MINOR;
+import static org.sonar.api.rules.RuleType.BUG;
+import static org.sonar.api.rules.RuleType.CODE_SMELL;
+import static org.sonar.api.server.ws.WebService.Param.ASCENDING;
+import static org.sonar.api.server.ws.WebService.Param.SORT;
+import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
+import static org.sonar.db.qualityprofile.ActiveRuleDto.INHERITED;
+import static org.sonar.db.qualityprofile.ActiveRuleDto.OVERRIDES;
+import static org.sonar.server.rule.ws.SearchAction.defineRuleSearchParameters;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVATION;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_INHERITANCE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_IS_TEMPLATE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_REPOSITORIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_SEVERITIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_STATUSES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TAGS;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TEMPLATE_KEY;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TYPES;
+
+public class RuleQueryFactoryTest {
+
+  @Rule
+  public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+  DbClient dbClient = dbTester.getDbClient();
+
+  DbSession dbSession = dbTester.getSession();
+
+  RuleQueryFactory underTest = new RuleQueryFactory(dbClient);
+
+  FakeAction fakeAction = new FakeAction(underTest);
+
+  @Test
+  public void create_empty_query() throws Exception {
+    RuleQuery result = execute();
+
+    assertThat(result.getKey()).isNull();
+
+    assertThat(result.getActivation()).isNull();
+    assertThat(result.getActiveSeverities()).isNull();
+    assertThat(result.isAscendingSort()).isTrue();
+    assertThat(result.getAvailableSinceLong()).isNull();
+    assertThat(result.getInheritance()).isNull();
+    assertThat(result.isTemplate()).isNull();
+    assertThat(result.getLanguages()).isNull();
+    assertThat(result.getQueryText()).isNull();
+    assertThat(result.getQProfileKey()).isNull();
+    assertThat(result.getRepositories()).isNull();
+    assertThat(result.getRuleKey()).isNull();
+    assertThat(result.getSeverities()).isNull();
+    assertThat(result.getStatuses()).isEmpty();
+    assertThat(result.getTags()).isNull();
+    assertThat(result.templateKey()).isNull();
+    assertThat(result.getTypes()).isEmpty();
+
+    assertThat(result.getSortField()).isNull();
+  }
+
+  @Test
+  public void create_query() throws Exception {
+    RuleQuery result = execute(
+      PARAM_RULE_KEY, "ruleKey",
+
+      PARAM_ACTIVATION, "true",
+      PARAM_ACTIVE_SEVERITIES, "MINOR,MAJOR",
+      PARAM_AVAILABLE_SINCE, "2016-01-01",
+      PARAM_INHERITANCE, "INHERITED,OVERRIDES",
+      PARAM_IS_TEMPLATE, "true",
+      PARAM_LANGUAGES, "java,js",
+      TEXT_QUERY, "S001",
+      PARAM_QPROFILE, "sonar-way",
+      PARAM_REPOSITORIES, "pmd,checkstyle",
+      PARAM_SEVERITIES, "MINOR,CRITICAL",
+      PARAM_STATUSES, "DEPRECATED,READY",
+      PARAM_TAGS, "tag1,tag2",
+      PARAM_TEMPLATE_KEY, "architectural",
+      PARAM_TYPES, "CODE_SMELL,BUG",
+
+      SORT, "updatedAt",
+      ASCENDING, "false");
+
+    assertThat(result.getKey()).isEqualTo("ruleKey");
+
+    assertThat(result.getActivation()).isTrue();
+    assertThat(result.getActiveSeverities()).containsOnly(MINOR, MAJOR);
+    assertThat(result.isAscendingSort()).isFalse();
+    assertThat(result.getAvailableSinceLong()).isNotNull();
+    assertThat(result.getInheritance()).containsOnly(INHERITED, OVERRIDES);
+    assertThat(result.isTemplate()).isTrue();
+    assertThat(result.getLanguages()).containsOnly("java", "js");
+    assertThat(result.getQueryText()).isEqualTo("S001");
+    assertThat(result.getQProfileKey()).isEqualTo("sonar-way");
+    assertThat(result.getRepositories()).containsOnly("pmd", "checkstyle");
+    assertThat(result.getRuleKey()).isNull();
+    assertThat(result.getSeverities()).containsOnly(MINOR, CRITICAL);
+    assertThat(result.getStatuses()).containsOnly(DEPRECATED, READY);
+    assertThat(result.getTags()).containsOnly("tag1", "tag2");
+    assertThat(result.templateKey()).isEqualTo("architectural");
+    assertThat(result.getTypes()).containsOnly(BUG, CODE_SMELL);
+
+    assertThat(result.getSortField()).isEqualTo("updatedAt");
+  }
+
+  @Test
+  public void create_query_add_language_from_profile() throws Exception {
+    String profileKey = "sonar-way";
+    dbClient.qualityProfileDao().insert(dbSession, QualityProfileDto.createFor(profileKey).setName("Sonar Way").setLanguage("xoo"));
+    dbSession.commit();
+
+    RuleQuery result = execute(
+      PARAM_QPROFILE, profileKey,
+      PARAM_LANGUAGES, "java,js");
+
+    assertThat(result.getQProfileKey()).isEqualTo(profileKey);
+    assertThat(result.getLanguages()).containsOnly("xoo");
+  }
+
+  private RuleQuery execute(String... paramsKeyAndValue) {
+    WsActionTester ws = new WsActionTester(fakeAction);
+    TestRequest request = ws.newRequest();
+    for (int i = 0; i < paramsKeyAndValue.length; i += 2) {
+      request.setParam(paramsKeyAndValue[i], paramsKeyAndValue[i + 1]);
+    }
+    request.execute();
+    return fakeAction.getRuleQuery();
+  }
+
+  private static class FakeAction implements WsAction {
+
+    private final RuleQueryFactory ruleQueryFactory;
+    private RuleQuery ruleQuery;
+
+    private FakeAction(RuleQueryFactory ruleQueryFactory) {
+      this.ruleQueryFactory = ruleQueryFactory;
+    }
+
+    @Override
+    public void define(WebService.NewController controller) {
+      WebService.NewAction action = controller.createAction("fake")
+        .setHandler(this);
+      defineRuleSearchParameters(action);
+    }
+
+    @Override
+    public void handle(Request request, Response response) throws Exception {
+      ruleQuery = ruleQueryFactory.createRuleQuery(request);
+    }
+
+    RuleQuery getRuleQuery() {
+      return ruleQuery;
+    }
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/bulk_activate_rule.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/bulk_activate_rule.json
new file mode 100644 (file)
index 0000000..fc904cd
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "succeeded": 4,
+  "failed": 0
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/bulk_activate_rule_not_all.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/bulk_activate_rule_not_all.json
new file mode 100644 (file)
index 0000000..5c9511a
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "succeeded": 2,
+  "failed": 0
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json
new file mode 100644 (file)
index 0000000..5c9511a
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "succeeded": 2,
+  "failed": 0
+}
index 3fa569bfcca1b62752033477b561a3fdcac6e892..e624b5c00ea3b6543643aa0307d9baa27c83db72 100644 (file)
@@ -30,10 +30,10 @@ import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVE_SEVERI
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_INHERITANCE;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_IS_TEMPLATE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_REPOSITORIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_SEVERITIES;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_STATUSES;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TAGS;
index 211de126eb075a1ef4a67ba2726fd6739c050e54..8be893f9259b2a9fcff503fd73021bdd96e96fd2 100644 (file)
@@ -37,10 +37,10 @@ import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_ACTIVE_SEVERI
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_AVAILABLE_SINCE;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_INHERITANCE;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_IS_TEMPLATE;
-import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_LANGUAGES;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_REPOSITORIES;
+import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_RULE_KEY;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_SEVERITIES;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_STATUSES;
 import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_TAGS;