From 3254f4804263e94f81d696e717322c1460d5b737 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Wed, 4 May 2016 17:31:53 +0200 Subject: [PATCH] SONAR-6906 Filter rules on profile language when bulk active rules --- .../platformlevel/PlatformLevel4.java | 2 + .../ws/BulkRuleActivationActions.java | 65 +----- .../server/rule/ws/RuleQueryFactory.java | 114 ++++++++++ .../sonar/server/rule/ws/SearchAction.java | 70 +----- .../ws/QProfilesWsMediumTest.java | 55 +++-- .../qualityprofile/ws/QProfilesWsTest.java | 31 +-- .../server/rule/index/RuleIndexTest.java | 57 +++-- .../server/rule/ws/RuleQueryFactoryTest.java | 200 ++++++++++++++++++ .../bulk_activate_rule.json | 4 + .../bulk_activate_rule_not_all.json | 4 + ...xist_on_another_language_than_profile.json | 4 + .../ws/client/rule/RulesService.java | 2 +- .../ws/client/rule/RulesServiceTest.java | 2 +- 13 files changed, 437 insertions(+), 173 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleQueryFactoryTest.java create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/bulk_activate_rule.json create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/bulk_activate_rule_not_all.json create mode 100644 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 diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index b617008eb74..40de8952056 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -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 diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java index 82fc1c3ce76..bb48610221a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java @@ -20,38 +20,19 @@ 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 index 00000000000..746bd3c6381 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java @@ -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(); + } + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java index f59dd90752c..ac49acb76e6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java @@ -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 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 { - INSTANCE; - - @Override - public String apply(@Nonnull RuleType input) { - return input.name(); - } - - } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java index c7bb601ad53..975d3fc9f80 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java @@ -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 diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java index 2e7597413a0..3ae6c310731 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java @@ -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"); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java index 6ac245f2339..2f0fb5e6f5b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java @@ -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 index 00000000000..524ba146f29 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RuleQueryFactoryTest.java @@ -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 index 00000000000..fc904cd1ca9 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/bulk_activate_rule.json @@ -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 index 00000000000..5c9511a9ea8 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest/bulk_activate_rule_not_all.json @@ -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 index 00000000000..5c9511a9ea8 --- /dev/null +++ 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 @@ -0,0 +1,4 @@ +{ + "succeeded": 2, + "failed": 0 +} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/rule/RulesService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/rule/RulesService.java index 3fa569bfcca..e624b5c00ea 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/rule/RulesService.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/rule/RulesService.java @@ -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; diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/rule/RulesServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/rule/RulesServiceTest.java index 211de126eb0..8be893f9259 100644 --- a/sonar-ws/src/test/java/org/sonarqube/ws/client/rule/RulesServiceTest.java +++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/rule/RulesServiceTest.java @@ -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; -- 2.39.5