From 0d24e1857064b3346461d77e7b53824c77cc7681 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Tue, 20 Jan 2015 15:56:12 +0100 Subject: [PATCH] SONAR-6017 Add api/rules/repositories action to list rule repositories (with criteria) --- .../server/platform/ServerComponents.java | 2 + .../org/sonar/server/rule/ws/AppAction.java | 6 +- .../sonar/server/rule/ws/CreateAction.java | 6 +- .../sonar/server/rule/ws/DeleteAction.java | 6 +- .../server/rule/ws/RepositoriesAction.java | 102 ++++++++++++++++++ .../org/sonar/server/rule/ws/RulesAction.java | 33 ++++++ .../sonar/server/rule/ws/RulesWebService.java | 29 ++--- .../sonar/server/rule/ws/SearchAction.java | 2 +- .../org/sonar/server/rule/ws/ShowAction.java | 6 +- .../org/sonar/server/rule/ws/TagsAction.java | 6 +- .../sonar/server/rule/ws/UpdateAction.java | 6 +- .../server/rule/ws/example-repositories.json | 27 +++++ .../sonar/server/rule/ws/AppActionTest.java | 4 +- .../server/rule/ws/DeleteActionTest.java | 4 +- .../rule/ws/RepositoriesActionTest.java | 86 +++++++++++++++ .../rule/ws/RulesWebServiceMediumTest.java | 3 +- .../RepositoriesActionTest/repositories.json | 19 ++++ .../repositories_common.json | 9 ++ .../repositories_limited.json | 14 +++ .../repositories_squid.json | 9 ++ .../repositories_ws.json | 14 +++ .../repositories_xoo.json | 9 ++ 22 files changed, 353 insertions(+), 49 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/rule/ws/RepositoriesAction.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesAction.java create mode 100644 server/sonar-server/src/main/resources/org/sonar/server/rule/ws/example-repositories.json create mode 100644 server/sonar-server/src/test/java/org/sonar/server/rule/ws/RepositoriesActionTest.java create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories.json create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_common.json create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_limited.json create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_squid.json create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_ws.json create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_xoo.json diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 5d21aaefe5d3..c0e2bfda799e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -264,6 +264,7 @@ import org.sonar.server.rule.ws.ActiveRuleCompleter; import org.sonar.server.rule.ws.AppAction; import org.sonar.server.rule.ws.DeleteAction; +import org.sonar.server.rule.ws.RepositoriesAction; import org.sonar.server.rule.ws.RuleMapping; import org.sonar.server.rule.ws.RulesWebService; import org.sonar.server.rule.ws.SearchAction; @@ -558,6 +559,7 @@ void startLevel4Components(ComponentContainer pico) { pico.addSingleton(TagsAction.class); pico.addSingleton(RuleMapping.class); pico.addSingleton(ActiveRuleCompleter.class); + pico.addSingleton(RepositoriesAction.class); pico.addSingleton(AppAction.class); // languages diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/AppAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/AppAction.java index 7ca17abfd905..25564e3a6184 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/AppAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/AppAction.java @@ -28,7 +28,6 @@ import org.sonar.api.server.debt.DebtModel; import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic; 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.utils.text.JsonWriter; @@ -45,7 +44,7 @@ /** * @since 4.4 */ -public class AppAction implements RequestHandler { +public class AppAction implements RulesAction { private final Languages languages; private final RuleRepositories ruleRepositories; @@ -148,7 +147,8 @@ private void addCharacteristics(JsonWriter json) { json.endArray(); } - void define(WebService.NewController controller) { + @Override + public void define(WebService.NewController controller) { controller.createAction("app") .setDescription("Data required for rendering the page 'Coding Rules'") .setInternal(true) diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/CreateAction.java index cf48eba28d86..20430e3daff5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/CreateAction.java @@ -25,7 +25,6 @@ import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; 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.utils.KeyValueFormat; @@ -42,7 +41,7 @@ /** * @since 4.4 */ -public class CreateAction implements RequestHandler { +public class CreateAction implements RulesAction { public static final String PARAM_CUSTOM_KEY = "custom_key"; public static final String PARAM_MANUAL_KEY = "manual_key"; @@ -63,7 +62,8 @@ public CreateAction(RuleService service, RuleMapping mapping) { this.mapping = mapping; } - void define(WebService.NewController controller) { + @Override + public void define(WebService.NewController controller) { WebService.NewAction action = controller .createAction("create") .setDescription("Create a custom rule or a manual rule") diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/DeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/DeleteAction.java index b81a8bdb6f96..5520761fc45d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/DeleteAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/DeleteAction.java @@ -22,7 +22,6 @@ import org.sonar.api.rule.RuleKey; 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.server.rule.RuleService; @@ -30,7 +29,7 @@ /** * @since 4.4 */ -public class DeleteAction implements RequestHandler { +public class DeleteAction implements RulesAction { public static final String PARAM_KEY = "key"; @@ -40,7 +39,8 @@ public DeleteAction(RuleService service) { this.service = service; } - void define(WebService.NewController controller) { + @Override + public void define(WebService.NewController controller) { WebService.NewAction action = controller .createAction("delete") .setDescription("Delete custom rule or manual rule") diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RepositoriesAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RepositoriesAction.java new file mode 100644 index 000000000000..55ff2345c37a --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RepositoriesAction.java @@ -0,0 +1,102 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.Lists; +import com.google.common.collect.Maps; +import com.google.common.io.Resources; +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.server.ws.WebService.NewAction; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.server.rule.RuleRepositories; +import org.sonar.server.rule.RuleRepositories.Repository; + +import javax.annotation.Nullable; + +import java.util.Collection; +import java.util.List; +import java.util.SortedMap; +import java.util.regex.Pattern; + +/** + * @since 5.1 + */ +public class RepositoriesAction implements RulesAction { + + private static final String MATCH_ALL = ".*"; + private final RuleRepositories repositories; + + public RepositoriesAction(RuleRepositories repositories) { + this.repositories = repositories; + } + + @Override + public void handle(Request request, Response response) throws Exception { + String query = request.param("q"); + String languageKey = request.param("language"); + int pageSize = request.mandatoryParamAsInt("ps"); + + JsonWriter json = response.newJsonWriter().beginObject().name("repositories").beginArray(); + for (Repository repo : listMatchingRepositories(query, languageKey, pageSize)) { + json.beginObject().prop("key", repo.key()).prop("name", repo.name()).prop("language", repo.language()).endObject(); + } + json.endArray().endObject().close(); + } + + private Collection listMatchingRepositories(@Nullable String query, @Nullable String languageKey, int pageSize) { + Pattern pattern = Pattern.compile(query == null ? MATCH_ALL : MATCH_ALL + query + MATCH_ALL, Pattern.CASE_INSENSITIVE); + + SortedMap reposByName = Maps.newTreeMap(); + Collection repos = languageKey == null ? repositories.repositories() : repositories.repositoriesForLang(languageKey); + + for (Repository repo : repos) { + if (pattern.matcher(repo.key()).matches() || pattern.matcher(repo.name()).matches()) { + reposByName.put(repo.name() + " -- " + repo.language(), repo); + } + } + List result = Lists.newArrayList(reposByName.values()); + if (pageSize > 0 && pageSize < result.size()) { + result = result.subList(0, pageSize); + } + return result; + } + + @Override + public void define(WebService.NewController controller) { + NewAction action = controller.createAction("repositories") + .setDescription("List available rule repositories") + .setHandler(this) + .setResponseExample(Resources.getResource(getClass(), "example-repositories.json")); + + action.createParam("q") + .setDescription("A pattern to match repository keys/names against") + .setExampleValue("squid"); + action.createParam("language") + .setDescription("A language key; if provided, only repositories for the given language will be returned") + .setExampleValue("java"); + action.createParam("ps") + .setDescription("The size of the list to return, 0 for all repositories") + .setExampleValue("25") + .setDefaultValue("0"); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesAction.java new file mode 100644 index 000000000000..ef563028c02a --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesAction.java @@ -0,0 +1,33 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.sonar.api.server.ws.RequestHandler; +import org.sonar.api.server.ws.WebService; + +/** + * Marker interface for coding rule related actions + * @author jblievremont + * + */ +interface RulesAction extends RequestHandler { + + void define(WebService.NewController controller); +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWebService.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWebService.java index b4a9ffc9cb4b..08b0374f84cd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWebService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWebService.java @@ -23,23 +23,10 @@ public class RulesWebService implements WebService { - private final SearchAction search; - private final ShowAction show; - private final TagsAction tags; - private final CreateAction create; - private final AppAction app; - private final UpdateAction update; - private final DeleteAction delete; + private final RulesAction[] actions; - public RulesWebService(SearchAction search, ShowAction show, TagsAction tags, CreateAction create, - AppAction app, UpdateAction update, DeleteAction delete) { - this.search = search; - this.show = show; - this.tags = tags; - this.create = create; - this.app = app; - this.update = update; - this.delete = delete; + public RulesWebService(RulesAction... actions) { + this.actions = actions; } @Override @@ -48,13 +35,9 @@ public void define(Context context) { .createController("api/rules") .setDescription("Coding rules"); - search.define(controller); - show.define(controller); - tags.define(controller); - app.define(controller); - update.define(controller); - create.define(controller); - delete.define(controller); + for (RulesAction action : actions) { + action.define(controller); + } controller.done(); } 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 3adbc00b4b44..f5f24a581ef8 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 @@ -47,7 +47,7 @@ /** * @since 4.4 */ -public class SearchAction extends SearchRequestHandler { +public class SearchAction extends SearchRequestHandler implements RulesAction { public static final String PARAM_REPOSITORIES = "repositories"; public static final String PARAM_KEY = "rule_key"; diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/ShowAction.java index fb2d98994f6d..2387e8db40e6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/ShowAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/ShowAction.java @@ -22,7 +22,6 @@ import com.google.common.io.Resources; import org.sonar.api.rule.RuleKey; 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.utils.text.JsonWriter; @@ -33,7 +32,7 @@ /** * @since 4.4 */ -public class ShowAction implements RequestHandler { +public class ShowAction implements RulesAction { public static final String PARAM_KEY = "key"; public static final String PARAM_ACTIVES = "actives"; @@ -48,7 +47,8 @@ public ShowAction(RuleService service, ActiveRuleCompleter activeRuleCompleter, this.activeRuleCompleter = activeRuleCompleter; } - void define(WebService.NewController controller) { + @Override + public void define(WebService.NewController controller) { WebService.NewAction action = controller .createAction("show") .setDescription("Get detailed information about a rule") diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/TagsAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/TagsAction.java index 8d4c3d037e47..4d20919f6ada 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/TagsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/TagsAction.java @@ -21,7 +21,6 @@ import com.google.common.io.Resources; 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.NewAction; @@ -30,7 +29,7 @@ import java.util.Set; -public class TagsAction implements RequestHandler { +public class TagsAction implements RulesAction { private final RuleService service; @@ -38,7 +37,8 @@ public TagsAction(RuleService service) { this.service = service; } - void define(WebService.NewController controller) { + @Override + public void define(WebService.NewController controller) { NewAction action = controller .createAction("tags") .setDescription("List rule tags") diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/UpdateAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/UpdateAction.java index 0eb7aee2f2a2..8ee0104e5125 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/UpdateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/UpdateAction.java @@ -28,7 +28,6 @@ import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction; 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.utils.KeyValueFormat; @@ -38,7 +37,7 @@ import org.sonar.server.rule.RuleService; import org.sonar.server.rule.RuleUpdate; -public class UpdateAction implements RequestHandler { +public class UpdateAction implements RulesAction { public static final String PARAM_KEY = "key"; public static final String PARAM_TAGS = "tags"; @@ -61,7 +60,8 @@ public UpdateAction(RuleService service, RuleMapping mapping) { this.mapping = mapping; } - void define(WebService.NewController controller) { + @Override + public void define(WebService.NewController controller) { WebService.NewAction action = controller .createAction("update") .setPost(true) diff --git a/server/sonar-server/src/main/resources/org/sonar/server/rule/ws/example-repositories.json b/server/sonar-server/src/main/resources/org/sonar/server/rule/ws/example-repositories.json new file mode 100644 index 000000000000..e73c41171c51 --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/rule/ws/example-repositories.json @@ -0,0 +1,27 @@ +{ + "repositories": [ + {"key": "clirr", "name": "Clirr", "language": "java"}, + {"key": "common-c", "name": "Common SonarQube", "language": "c"}, + {"key": "common-cpp", "name": "Common SonarQube", "language": "cpp"}, + {"key": "common-cs", "name": "Common SonarQube", "language": "cs"}, + {"key": "common-java", "name": "Common SonarQube", "language": "java"}, + {"key": "common-js", "name": "Common SonarQube", "language": "js"}, + {"key": "common-objc", "name": "Common SonarQube", "language": "objc"}, + {"key": "common-php", "name": "Common SonarQube", "language": "php"}, + {"key": "c-cppcheck", "name": "Cppcheck", "language": "c"}, + {"key": "cpp-cppcheck", "name": "Cppcheck", "language": "cpp"}, + {"key": "fb-contrib", "name": "fb-contrib", "language": "java"}, + {"key": "findbugs", "name": "FindBugs", "language": "java"}, + {"key": "fxcop", "name": "FxCop / Code Analysis", "language": "cs"}, + {"key": "resharper-cs", "name": "ReSharper", "language": "cs"}, + {"key": "resharper-vbnet", "name": "ReSharper", "language": "vbnet"}, + {"key": "c", "name": "SonarQube", "language": "c"}, + {"key": "cpp", "name": "SonarQube", "language": "cpp"}, + {"key": "csharpsquid", "name": "SonarQube", "language": "cs"}, + {"key": "javascript", "name": "SonarQube", "language": "js"}, + {"key": "objc", "name": "SonarQube", "language": "objc"}, + {"key": "php", "name": "SonarQube", "language": "php"}, + {"key": "squid", "name": "SonarQube", "language": "java"}, + {"key": "stylecop", "name": "StyleCop", "language": "cs"} + ] +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/AppActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/AppActionTest.java index c40bde946aea..c54a13586f5f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/AppActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/AppActionTest.java @@ -68,9 +68,7 @@ public class AppActionTest { @Test public void should_generate_app_init_info() throws Exception { AppAction app = new AppAction(languages, ruleRepositories, i18n, debtModel, profileLoader); - WsTester tester = new WsTester(new RulesWebService( - new SearchAction(null, null, null), mock(ShowAction.class), mock(TagsAction.class), mock(CreateAction.class), - app, mock(UpdateAction.class), mock(DeleteAction.class))); + WsTester tester = new WsTester(new RulesWebService(app)); MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/DeleteActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/DeleteActionTest.java index 5043126e12f1..002da0ff0ca9 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/DeleteActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/DeleteActionTest.java @@ -29,7 +29,6 @@ import org.sonar.server.rule.RuleService; import org.sonar.server.ws.WsTester; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) @@ -42,8 +41,7 @@ public class DeleteActionTest { @Before public void setUp() throws Exception { - tester = new WsTester(new RulesWebService(new SearchAction(null, null, null), mock(ShowAction.class), mock(TagsAction.class), mock(CreateAction.class), mock(AppAction.class), - mock(UpdateAction.class), new DeleteAction(ruleService))); + tester = new WsTester(new RulesWebService(new DeleteAction(ruleService))); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RepositoriesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RepositoriesActionTest.java new file mode 100644 index 000000000000..7f059beb9a90 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RepositoriesActionTest.java @@ -0,0 +1,86 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.server.rule.RuleRepositories; +import org.sonar.server.ws.WsTester; +import org.sonar.server.ws.WsTester.TestRequest; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class RepositoriesActionTest { + + private WsTester tester; + + @Mock + private RuleRepositories repositories; + + @Before + public void setUp() { + tester = new WsTester(new RulesWebService(new RepositoriesAction(repositories))); + + RuleRepositories.Repository repo1 = mock(RuleRepositories.Repository.class); + when(repo1.key()).thenReturn("xoo"); + when(repo1.name()).thenReturn("SonarQube"); + when(repo1.language()).thenReturn("xoo"); + + RuleRepositories.Repository repo2 = mock(RuleRepositories.Repository.class); + when(repo2.key()).thenReturn("squid"); + when(repo2.name()).thenReturn("SonarQube"); + when(repo2.language()).thenReturn("ws"); + + RuleRepositories.Repository repo3 = mock(RuleRepositories.Repository.class); + when(repo3.key()).thenReturn("common-ws"); + when(repo3.name()).thenReturn("SonarQube Common"); + when(repo3.language()).thenReturn("ws"); + + when(repositories.repositories()).thenReturn(ImmutableList.of(repo1, repo2, repo3)); + when(repositories.repositoriesForLang("xoo")).thenReturn(ImmutableList.of(repo1)); + when(repositories.repositoriesForLang("ws")).thenReturn(ImmutableList.of(repo2, repo3)); + } + + @Test + public void should_list_repositories() throws Exception { + + tester = new WsTester(new RulesWebService(new RepositoriesAction(repositories))); + + newRequest().execute().assertJson(this.getClass(), "repositories.json"); + newRequest().setParam("language", "xoo").execute().assertJson(this.getClass(), "repositories_xoo.json"); + newRequest().setParam("language", "ws").execute().assertJson(this.getClass(), "repositories_ws.json"); + newRequest().setParam("q", "common").execute().assertJson(this.getClass(), "repositories_common.json"); + newRequest().setParam("q", "squid").execute().assertJson(this.getClass(), "repositories_squid.json"); + newRequest().setParam("q", "sonar").execute().assertJson(this.getClass(), "repositories.json"); + newRequest().setParam("ps", "2").execute().assertJson(this.getClass(), "repositories_limited.json"); + newRequest().setParam("ps", "3").execute().assertJson(this.getClass(), "repositories.json"); + newRequest().setParam("ps", "100").execute().assertJson(this.getClass(), "repositories.json"); + } + + protected TestRequest newRequest() { + return tester.newGetRequest("api/rules", "repositories"); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWebServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWebServiceMediumTest.java index 97cb91a606b8..e20913952957 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWebServiceMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWebServiceMediumTest.java @@ -92,13 +92,14 @@ public void define() throws Exception { WebService.Controller controller = context.controller(API_ENDPOINT); assertThat(controller).isNotNull(); - assertThat(controller.actions()).hasSize(7); + assertThat(controller.actions()).hasSize(8); assertThat(controller.action(API_SEARCH_METHOD)).isNotNull(); assertThat(controller.action(API_SHOW_METHOD)).isNotNull(); assertThat(controller.action(API_TAGS_METHOD)).isNotNull(); assertThat(controller.action("update")).isNotNull(); assertThat(controller.action("create")).isNotNull(); assertThat(controller.action("delete")).isNotNull(); + assertThat(controller.action("repositories")).isNotNull(); assertThat(controller.action("app")).isNotNull(); } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories.json new file mode 100644 index 000000000000..3635fef8561d --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories.json @@ -0,0 +1,19 @@ +{ + "repositories": [ + { + "key": "squid", + "name": "SonarQube", + "language": "ws" + }, + { + "key": "xoo", + "name": "SonarQube", + "language": "xoo" + }, + { + "key": "common-ws", + "name": "SonarQube Common", + "language": "ws" + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_common.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_common.json new file mode 100644 index 000000000000..e572f3371533 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_common.json @@ -0,0 +1,9 @@ +{ + "repositories": [ + { + "key": "common-ws", + "name": "SonarQube Common", + "language": "ws" + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_limited.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_limited.json new file mode 100644 index 000000000000..bb30a982d520 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_limited.json @@ -0,0 +1,14 @@ +{ + "repositories": [ + { + "key": "squid", + "name": "SonarQube", + "language": "ws" + }, + { + "key": "xoo", + "name": "SonarQube", + "language": "xoo" + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_squid.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_squid.json new file mode 100644 index 000000000000..8e8a17083c68 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_squid.json @@ -0,0 +1,9 @@ +{ + "repositories": [ + { + "key": "squid", + "name": "SonarQube", + "language": "ws" + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_ws.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_ws.json new file mode 100644 index 000000000000..df797d1454e7 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_ws.json @@ -0,0 +1,14 @@ +{ + "repositories": [ + { + "key": "squid", + "name": "SonarQube", + "language": "ws" + }, + { + "key": "common-ws", + "name": "SonarQube Common", + "language": "ws" + } + ] +} \ No newline at end of file diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_xoo.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_xoo.json new file mode 100644 index 000000000000..f15c319b4fb3 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_xoo.json @@ -0,0 +1,9 @@ +{ + "repositories": [ + { + "key": "xoo", + "name": "SonarQube", + "language": "xoo" + } + ] +} \ No newline at end of file