]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6857 Rename WS components/search -> components/search_view_components
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Wed, 30 Sep 2015 08:30:33 +0000 (10:30 +0200)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Fri, 2 Oct 2015 07:23:01 +0000 (09:23 +0200)
24 files changed:
server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWs.java
server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWsAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchViewComponentsAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/test/java/org/sonar/server/component/ws/AppActionTest.java
server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java
server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchViewComponentsActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_only_authorized_projects_from_view.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_only_authorized_projects_from_view.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_only_first_page.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_paged_result.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_projects_from_subview.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_projects_from_view.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/shared.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_only_authorized_projects_from_view.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_only_authorized_projects_from_view.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_only_first_page.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_paged_result.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_projects_from_subview.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_projects_from_view.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/shared.xml [new file with mode: 0644]
sonar-db/src/main/resources/org/sonar/db/component/ResourceMapper.xml

index aba52c5b1bb278b1dfa741e5c9a76180beca49af..f4c83e3b18c872cd7a50446500874c68a8d37b02 100644 (file)
@@ -27,11 +27,13 @@ import org.sonar.api.server.ws.WebService;
 public class ComponentsWs implements WebService {
 
   private final AppAction appAction;
-  private final SearchAction searchAction;
+  private final SearchViewComponentsAction searchViewComponentsAction;
+  private final ComponentsWsAction[] actions;
 
-  public ComponentsWs(AppAction appAction, SearchAction searchAction) {
+  public ComponentsWs(AppAction appAction, SearchViewComponentsAction searchViewComponentsAction, ComponentsWsAction... actions) {
     this.appAction = appAction;
-    this.searchAction = searchAction;
+    this.searchViewComponentsAction = searchViewComponentsAction;
+    this.actions = actions;
   }
 
   @Override
@@ -40,8 +42,11 @@ public class ComponentsWs implements WebService {
       .setSince("4.2")
       .setDescription("Components management");
 
+    for (ComponentsWsAction action : actions) {
+      action.define(controller);
+    }
     appAction.define(controller);
-    searchAction.define(controller);
+    searchViewComponentsAction.define(controller);
     defineSuggestionsAction(controller);
 
     controller.done();
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWsAction.java
new file mode 100644 (file)
index 0000000..58266ab
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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.component.ws;
+
+import org.sonar.server.ws.WsAction;
+
+public interface ComponentsWsAction extends WsAction {
+  // marker interface
+}
index cc01d7470b61f491e68c9e342e6fe3701df44b4f..36bb872266906c13fa60a779bdf2fb8b463eef33 100644 (file)
 
 package org.sonar.server.component.ws;
 
-import com.google.common.collect.Sets;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
 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.api.web.UserRole;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.MyBatis;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.es.SearchOptions;
-import org.sonar.server.user.UserSession;
 
-import static com.google.common.collect.Sets.newLinkedHashSet;
-import static org.sonar.api.server.ws.WebService.Param.PAGE;
-import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
-
-public class SearchAction implements RequestHandler {
-
-  private static final short MINIMUM_SEARCH_CHARACTERS = 2;
-
-  private static final String PARAM_COMPONENT_UUID = "componentUuid";
-
-  private final DbClient dbClient;
-  private final UserSession userSession;
-  private final ComponentFinder componentFinder;
-
-  public SearchAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder) {
-    this.dbClient = dbClient;
-    this.userSession = userSession;
-    this.componentFinder = componentFinder;
-  }
-
-  void define(WebService.NewController controller) {
-    WebService.NewAction action = controller.createAction("search")
-      .setDescription("Search for components. Currently limited to projects in a view or a sub-view")
-      .setSince("5.1")
-      .setInternal(true)
+public class SearchAction implements ComponentsWsAction {
+  @Override
+  public void define(WebService.NewController context) {
+    WebService.NewAction action = context.createAction("search")
+      .setSince("5.2")
+      .setDescription("Search for components")
+      .addPagingParams(100)
+      .addSearchQuery("sona", "project names")
+      .setResponseExample(getClass().getResource("search-example.json"))
       .setHandler(this);
-
-    action
-      .createParam(PARAM_COMPONENT_UUID)
-      .setRequired(true)
-      .setDescription("View or sub view UUID")
-      .setExampleValue("d6d9e1e5-5e13-44fa-ab82-3ec29efa8935");
-
-    action
-      .createParam(Param.TEXT_QUERY)
-      .setRequired(true)
-      .setDescription("UTF-8 search query")
-      .setExampleValue("sonar");
-
-    action.addPagingParams(10);
   }
 
   @Override
-  public void handle(Request request, Response response) {
-    String query = request.mandatoryParam(Param.TEXT_QUERY);
-    if (query.length() < MINIMUM_SEARCH_CHARACTERS) {
-      throw new IllegalArgumentException(String.format("Minimum search is %s characters", MINIMUM_SEARCH_CHARACTERS));
-    }
-    String componentUuid = request.mandatoryParam(PARAM_COMPONENT_UUID);
-
-    JsonWriter json = response.newJsonWriter();
-    json.beginObject();
-
-    DbSession session = dbClient.openSession(false);
-    try {
-      ComponentDto componentDto = componentFinder.getByUuid(session, componentUuid);
-      userSession.checkProjectUuidPermission(UserRole.USER, componentDto.projectUuid());
-
-      Set<Long> projectIds = newLinkedHashSet(dbClient.componentIndexDao().selectProjectIdsFromQueryAndViewOrSubViewUuid(session, query, componentDto.uuid()));
-      Collection<Long> authorizedProjectIds = dbClient.authorizationDao().keepAuthorizedProjectIds(session, projectIds, userSession.getUserId(), UserRole.USER);
-
-      SearchOptions options = new SearchOptions();
-      options.setPage(request.mandatoryParamAsInt(PAGE), request.mandatoryParamAsInt(PAGE_SIZE));
-      Set<Long> pagedProjectIds = pagedProjectIds(authorizedProjectIds, options);
-
-      List<ComponentDto> projects = dbClient.componentDao().selectByIds(session, pagedProjectIds);
-
-      options.writeJson(json, authorizedProjectIds.size());
-      json.name("components").beginArray();
-      for (ComponentDto project : projects) {
-        json.beginObject();
-        json.prop("uuid", project.uuid());
-        json.prop("name", project.name());
-        json.endObject();
-      }
-      json.endArray();
-    } finally {
-      MyBatis.closeQuietly(session);
-    }
-
-    json.endObject();
-    json.close();
-  }
+  public void handle(Request wsRequest, Response wsResponse) throws Exception {
 
-  private static Set<Long> pagedProjectIds(Collection<Long> projectIds, SearchOptions options) {
-    Set<Long> results = Sets.newLinkedHashSet();
-    int index = 0;
-    for (Long projectId : projectIds) {
-      if (index >= options.getOffset() && results.size() < options.getLimit()) {
-        results.add(projectId);
-      } else if (results.size() >= options.getLimit()) {
-        break;
-      }
-      index++;
-    }
-    return results;
   }
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchViewComponentsAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchViewComponentsAction.java
new file mode 100644 (file)
index 0000000..7474b2b
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * 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.component.ws;
+
+import com.google.common.collect.Sets;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+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.api.web.UserRole;
+import org.sonar.core.util.Uuids;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.MyBatis;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.es.SearchOptions;
+import org.sonar.server.user.UserSession;
+
+import static com.google.common.collect.Sets.newLinkedHashSet;
+import static org.sonar.api.server.ws.WebService.Param.PAGE;
+import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
+
+public class SearchViewComponentsAction implements RequestHandler {
+
+  private static final short MINIMUM_SEARCH_CHARACTERS = 2;
+
+  private static final String PARAM_COMPONENT_UUID = "componentId";
+
+  private final DbClient dbClient;
+  private final UserSession userSession;
+  private final ComponentFinder componentFinder;
+
+  public SearchViewComponentsAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder) {
+    this.dbClient = dbClient;
+    this.userSession = userSession;
+    this.componentFinder = componentFinder;
+  }
+
+  void define(WebService.NewController controller) {
+    WebService.NewAction action = controller.createAction("search_view_components")
+      .setDescription("Search for components. Currently limited to projects in a view or a sub-view")
+      .setSince("5.1")
+      .setInternal(true)
+      .setHandler(this);
+
+    action
+      .createParam(PARAM_COMPONENT_UUID)
+      .setRequired(true)
+      .setDescription("View or sub view UUID")
+      .setExampleValue(Uuids.UUID_EXAMPLE_01);
+
+    action
+      .createParam(Param.TEXT_QUERY)
+      .setRequired(true)
+      .setDescription("UTF-8 search query")
+      .setExampleValue("sonar");
+
+    action.addPagingParams(10);
+  }
+
+  @Override
+  public void handle(Request request, Response response) {
+    String query = request.mandatoryParam(Param.TEXT_QUERY);
+    if (query.length() < MINIMUM_SEARCH_CHARACTERS) {
+      throw new IllegalArgumentException(String.format("Minimum search is %s characters", MINIMUM_SEARCH_CHARACTERS));
+    }
+    String componentUuid = request.mandatoryParam(PARAM_COMPONENT_UUID);
+
+    JsonWriter json = response.newJsonWriter();
+    json.beginObject();
+
+    DbSession session = dbClient.openSession(false);
+    try {
+      ComponentDto componentDto = componentFinder.getByUuid(session, componentUuid);
+      userSession.checkProjectUuidPermission(UserRole.USER, componentDto.projectUuid());
+
+      Set<Long> projectIds = newLinkedHashSet(dbClient.componentIndexDao().selectProjectIdsFromQueryAndViewOrSubViewUuid(session, query, componentDto.uuid()));
+      Collection<Long> authorizedProjectIds = dbClient.authorizationDao().keepAuthorizedProjectIds(session, projectIds, userSession.getUserId(), UserRole.USER);
+
+      SearchOptions options = new SearchOptions();
+      options.setPage(request.mandatoryParamAsInt(PAGE), request.mandatoryParamAsInt(PAGE_SIZE));
+      Set<Long> pagedProjectIds = pagedProjectIds(authorizedProjectIds, options);
+
+      List<ComponentDto> projects = dbClient.componentDao().selectByIds(session, pagedProjectIds);
+
+      options.writeJson(json, authorizedProjectIds.size());
+      json.name("components").beginArray();
+      for (ComponentDto project : projects) {
+        json.beginObject();
+        json.prop("uuid", project.uuid());
+        json.prop("name", project.name());
+        json.endObject();
+      }
+      json.endArray();
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+
+    json.endObject();
+    json.close();
+  }
+
+  private static Set<Long> pagedProjectIds(Collection<Long> projectIds, SearchOptions options) {
+    Set<Long> results = Sets.newLinkedHashSet();
+    int index = 0;
+    for (Long projectId : projectIds) {
+      if (index >= options.getOffset() && results.size() < options.getLimit()) {
+        results.add(projectId);
+      } else if (results.size() >= options.getLimit()) {
+        break;
+      }
+      index++;
+    }
+    return results;
+  }
+}
index f21981e83802fe440ff94808c9c6d6de88e18e86..e0b8f64d16ef672cd3c0d603847c79f48f8b8080 100644 (file)
@@ -61,6 +61,7 @@ import org.sonar.server.component.DefaultRubyComponentService;
 import org.sonar.server.component.ws.ComponentsWs;
 import org.sonar.server.component.ws.EventsWs;
 import org.sonar.server.component.ws.ResourcesWs;
+import org.sonar.server.component.ws.SearchViewComponentsAction;
 import org.sonar.server.computation.CeModule;
 import org.sonar.server.computation.container.ReportProcessingModule;
 import org.sonar.server.computation.queue.CeQueueModule;
@@ -560,7 +561,7 @@ public class PlatformLevel4 extends PlatformLevel {
       ResourcesWs.class,
       ComponentsWs.class,
       org.sonar.server.component.ws.AppAction.class,
-      org.sonar.server.component.ws.SearchAction.class,
+      SearchViewComponentsAction.class,
       EventsWs.class,
       NewAlerts.class,
       NewAlerts.newMetadata(),
index aead84b80bc281f332f8284410a8defed4d9f408..376305e19c2fe984301774f93ce56f0a76801882 100644 (file)
@@ -108,7 +108,7 @@ public class AppActionTest {
 
     when(measureDao.selectByComponentKeyAndMetricKeys(eq(session), anyString(), anyListOf(String.class))).thenReturn(measures);
 
-    tester = new WsTester(new ComponentsWs(new AppAction(dbClient, durations, i18n, userSessionRule, new ComponentFinder(dbClient)), mock(SearchAction.class)));
+    tester = new WsTester(new ComponentsWs(new AppAction(dbClient, durations, i18n, userSessionRule, new ComponentFinder(dbClient)), mock(SearchViewComponentsAction.class)));
   }
 
   @Test
index 0f1ef335c944b777e1c187067084ccade13c1bed..0159481fafb030b84355e8855b737f95f7024c8f 100644 (file)
@@ -45,8 +45,8 @@ public class ComponentsWsTest {
   public void setUp() {
     WsTester tester = new WsTester(new ComponentsWs(
       new AppAction(mock(DbClient.class), mock(Durations.class), mock(I18n.class), userSessionRule, mock(ComponentFinder.class)),
-      new SearchAction(mock(DbClient.class), userSessionRule, mock(ComponentFinder.class)))
-    );
+      new SearchViewComponentsAction(mock(DbClient.class), userSessionRule, mock(ComponentFinder.class)))
+      );
     controller = tester.controller("api/components");
   }
 
@@ -81,7 +81,7 @@ public class ComponentsWsTest {
 
   @Test
   public void define_search_action() {
-    WebService.Action action = controller.action("search");
+    WebService.Action action = controller.action("search_view_components");
     assertThat(action).isNotNull();
     assertThat(action.isInternal()).isTrue();
     assertThat(action.isPost()).isFalse();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
deleted file mode 100644 (file)
index a5d6730..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.component.ws;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.server.ws.WebService.Param;
-import org.sonar.api.utils.System2;
-import org.sonar.api.web.UserRole;
-import org.sonar.db.DbTester;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
-import org.sonar.test.DbTests;
-
-import static org.mockito.Mockito.mock;
-
-@Category(DbTests.class)
-public class SearchActionTest {
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Rule
-  public DbTester dbTester = DbTester.create(System2.INSTANCE);
-
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.standalone();
-
-  WsTester tester;
-
-  @Before
-  public void setUp() {
-    dbTester.truncateTables();
-    tester = new WsTester(new ComponentsWs(mock(AppAction.class), new SearchAction(dbTester.getDbClient(), userSessionRule, new ComponentFinder(dbTester.getDbClient()))));
-  }
-
-  @Test
-  public void return_projects_from_view() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "shared.xml");
-    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
-
-    WsTester.TestRequest request = tester.newGetRequest("api/components", "search").setParam("componentUuid", "EFGH").setParam("q", "st");
-    request.execute().assertJson(getClass(), "return_projects_from_view.json");
-  }
-
-  @Test
-  public void return_projects_from_subview() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "shared.xml");
-    userSessionRule.login("john").addComponentUuidPermission(UserRole.USER, "EFGH", "FGHI");
-
-    WsTester.TestRequest request = tester.newGetRequest("api/components", "search").setParam("componentUuid", "FGHI").setParam("q", "st");
-    request.execute().assertJson(getClass(), "return_projects_from_subview.json");
-  }
-
-  @Test
-  public void return_only_authorized_projects_from_view() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "return_only_authorized_projects_from_view.xml");
-    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
-
-    WsTester.TestRequest request = tester.newGetRequest("api/components", "search").setParam("componentUuid", "EFGH").setParam("q", "st");
-    request.execute().assertJson(getClass(), "return_only_authorized_projects_from_view.json");
-  }
-
-  @Test
-  public void return_paged_result() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "shared.xml");
-    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
-
-    WsTester.TestRequest request = tester.newGetRequest("api/components", "search").setParam("componentUuid", "EFGH").setParam("q", "st").setParam(Param.PAGE, "2")
-      .setParam(Param.PAGE_SIZE, "1");
-    request.execute().assertJson(getClass(), "return_paged_result.json");
-  }
-
-  @Test
-  public void return_only_first_page() throws Exception {
-    dbTester.prepareDbUnit(getClass(), "shared.xml");
-    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
-
-    WsTester.TestRequest request = tester.newGetRequest("api/components", "search").setParam("componentUuid", "EFGH").setParam("q", "st").setParam(Param.PAGE, "1")
-      .setParam(Param.PAGE_SIZE, "1");
-    request.execute().assertJson(getClass(), "return_only_first_page.json");
-  }
-
-  @Test
-  public void fail_when_search_param_is_too_short() throws Exception {
-    thrown.expect(IllegalArgumentException.class);
-    thrown.expectMessage("Minimum search is 2 characters");
-
-
-    dbTester.prepareDbUnit(getClass(), "shared.xml");
-    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
-
-    WsTester.TestRequest request = tester.newGetRequest("api/components", "search").setParam("componentUuid", "EFGH").setParam("q", "s");
-    request.execute();
-  }
-
-  @Test
-  public void fail_when_project_uuid_does_not_exists() throws Exception {
-    thrown.expect(NotFoundException.class);
-    thrown.expectMessage("Component id 'UNKNOWN' not found");
-
-    dbTester.prepareDbUnit(getClass(), "shared.xml");
-    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
-
-    WsTester.TestRequest request = tester.newGetRequest("api/components", "search").setParam("componentUuid", "UNKNOWN").setParam("q", "st");
-    request.execute();
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchViewComponentsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchViewComponentsActionTest.java
new file mode 100644 (file)
index 0000000..1ad3bad
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * 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.component.ws;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.WebService.Param;
+import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
+import org.sonar.db.DbTester;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsTester;
+import org.sonar.test.DbTests;
+
+import static org.mockito.Mockito.mock;
+
+@Category(DbTests.class)
+public class SearchViewComponentsActionTest {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Rule
+  public DbTester db = DbTester.create(System2.INSTANCE);
+
+  @Rule
+  public UserSessionRule userSessionRule = UserSessionRule.standalone();
+
+  WsTester ws;
+
+  @Before
+  public void setUp() {
+    db.truncateTables();
+    ws = new WsTester(new ComponentsWs(mock(AppAction.class), new SearchViewComponentsAction(db.getDbClient(), userSessionRule, new ComponentFinder(db.getDbClient()))));
+  }
+
+  @Test
+  public void return_projects_from_view() throws Exception {
+    db.prepareDbUnit(getClass(), "shared.xml");
+    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
+
+    WsTester.TestRequest request = newRequest().setParam("componentId", "EFGH").setParam("q", "st");
+    request.execute().assertJson(getClass(), "return_projects_from_view.json");
+  }
+
+  @Test
+  public void return_projects_from_subview() throws Exception {
+    db.prepareDbUnit(getClass(), "shared.xml");
+    userSessionRule.login("john").addComponentUuidPermission(UserRole.USER, "EFGH", "FGHI");
+
+    WsTester.TestRequest request = newRequest().setParam("componentId", "FGHI").setParam("q", "st");
+    request.execute().assertJson(getClass(), "return_projects_from_subview.json");
+  }
+
+  @Test
+  public void return_only_authorized_projects_from_view() throws Exception {
+    db.prepareDbUnit(getClass(), "return_only_authorized_projects_from_view.xml");
+    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
+
+    WsTester.TestRequest request = newRequest().setParam("componentId", "EFGH").setParam("q", "st");
+    request.execute().assertJson(getClass(), "return_only_authorized_projects_from_view.json");
+  }
+
+  @Test
+  public void return_paged_result() throws Exception {
+    db.prepareDbUnit(getClass(), "shared.xml");
+    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
+
+    WsTester.TestRequest request = newRequest().setParam("componentId", "EFGH").setParam("q", "st").setParam(Param.PAGE, "2")
+      .setParam(Param.PAGE_SIZE, "1");
+    request.execute().assertJson(getClass(), "return_paged_result.json");
+  }
+
+  @Test
+  public void return_only_first_page() throws Exception {
+    db.prepareDbUnit(getClass(), "shared.xml");
+    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
+
+    WsTester.TestRequest request = newRequest().setParam("componentId", "EFGH").setParam("q", "st").setParam(Param.PAGE, "1")
+      .setParam(Param.PAGE_SIZE, "1");
+    request.execute().assertJson(getClass(), "return_only_first_page.json");
+  }
+
+  @Test
+  public void fail_when_search_param_is_too_short() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Minimum search is 2 characters");
+
+    db.prepareDbUnit(getClass(), "shared.xml");
+    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
+
+    WsTester.TestRequest request = newRequest().setParam("componentId", "EFGH").setParam("q", "s");
+    request.execute();
+  }
+
+  @Test
+  public void fail_when_project_uuid_does_not_exists() throws Exception {
+    thrown.expect(NotFoundException.class);
+    thrown.expectMessage("Component id 'UNKNOWN' not found");
+
+    db.prepareDbUnit(getClass(), "shared.xml");
+    userSessionRule.login("john").addProjectUuidPermissions(UserRole.USER, "EFGH");
+
+    WsTester.TestRequest request = newRequest().setParam("componentId", "UNKNOWN").setParam("q", "st");
+    request.execute();
+  }
+
+  private WsTester.TestRequest newRequest() {
+    return ws.newGetRequest("api/components", "search_view_components");
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_only_authorized_projects_from_view.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_only_authorized_projects_from_view.json
deleted file mode 100644 (file)
index 9676629..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "total": 1,
-  "p": 1,
-  "ps": 10,
-  "components": [
-    {
-      "uuid": "JKLM",
-      "name": "Struts"
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_only_authorized_projects_from_view.xml b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_only_authorized_projects_from_view.xml
deleted file mode 100644 (file)
index 0b5c034..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<dataset>
-
-  <!-- Only struts is authorized for all user -->
-  <group_roles id="1" group_id="[null]" resource_id="100" role="user"/>
-
-  <!-- View -->
-  <projects id="11" uuid="EFGH" project_uuid="EFGH" module_uuid="[null]" module_uuid_path="." copy_resource_id="[null]" enabled="[true]"
-            kee="LANGUAGE_VIEW" scope="PRJ" qualifier="VW" name="By Language" path="[null]"/>
-
-  <projects id="112" uuid="GHIJ" project_uuid="EFGH" module_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="101" enabled="[true]"
-            kee="VIEW2org.elasticsearch:elasticsearch" scope="FIL" qualifier="TRK" name="Elasticsearch" path="[null]"/>
-
-  <projects id="113" uuid="HIJK" project_uuid="EFGH" module_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="100" enabled="[true]"
-            kee="VIEW2org.struts:struts" scope="FIL" qualifier="TRK" name="Struts" path="[null]"/>
-
-  <!-- Real projects -->
-
-  <projects id="100" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
-            uuid="JKLM" project_uuid="JKLM" module_uuid="[null]" module_uuid_path="."
-            enabled="[true]" copy_resource_id="[null]" path="[null]"/>
-
-  <projects id="101" scope="PRJ" qualifier="TRK" kee="org.elasticsearch:elasticsearch" name="Elasticsearch"
-            uuid="KLMN" project_uuid="KLMN" module_uuid="[null]" module_uuid_path="."
-            enabled="[true]" copy_resource_id="[null]" path="[null]"/>
-
-  <resource_index id="1" kee="struts" resource_id="100" root_project_id="100" position="0" name_size="6" qualifier="TRK"/>
-  <resource_index id="2" kee="elasticsearch" resource_id="101" root_project_id="1" position="0" name_size="13" qualifier="TRK"/>
-  <resource_index id="3" kee="sticsearch" resource_id="101" root_project_id="1" position="1" name_size="13" qualifier="TRK"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_only_first_page.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_only_first_page.json
deleted file mode 100644 (file)
index e913f5e..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "total": 2,
-  "p": 1,
-  "ps": 1
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_paged_result.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_paged_result.json
deleted file mode 100644 (file)
index d871108..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "total": 2,
-  "p": 2,
-  "ps": 1
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_projects_from_subview.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_projects_from_subview.json
deleted file mode 100644 (file)
index 9676629..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "total": 1,
-  "p": 1,
-  "ps": 10,
-  "components": [
-    {
-      "uuid": "JKLM",
-      "name": "Struts"
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_projects_from_view.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/return_projects_from_view.json
deleted file mode 100644 (file)
index f7f99cc..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "total": 2,
-  "p": 1,
-  "ps": 10,
-  "components": [
-    {
-      "uuid": "JKLM",
-      "name": "Struts"
-    },
-    {
-      "uuid": "KLMN",
-      "name": "Elasticsearch"
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/shared.xml b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchActionTest/shared.xml
deleted file mode 100644 (file)
index 687ef3d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<dataset>
-
-  <!-- Projects is authorized for all user -->
-  <group_roles id="1" group_id="[null]" resource_id="100" role="user"/>
-  <group_roles id="2" group_id="[null]" resource_id="101" role="user"/>
-
-  <!-- View with sub view -->
-  <projects id="11" uuid="EFGH" project_uuid="EFGH" module_uuid="[null]" module_uuid_path="." copy_resource_id="[null]" enabled="[true]"
-            kee="LANGUAGE_VIEW" scope="PRJ" qualifier="VW" name="By Language" path="[null]"/>
-
-  <projects id="112" uuid="GHIJ" project_uuid="EFGH" module_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="101" enabled="[true]"
-            kee="VIEW2org.elasticsearch:elasticsearch" scope="FIL" qualifier="TRK" name="Elasticsearch" path="[null]"/>
-
-  <!-- Sub view -->
-  <projects id="13" uuid="FGHI" project_uuid="EFGH" module_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="[null]" enabled="[true]"
-            kee="JAVA_PROJECTS" scope="PRJ" qualifier="SVW" name="Java projects" path="[null]"/>
-
-  <projects id="113" uuid="HIJK" project_uuid="EFGH" module_uuid="FGHI" module_uuid_path=".EFGH.FGHI." copy_resource_id="100" enabled="[true]"
-            kee="VIEW2org.struts:struts" scope="FIL" qualifier="TRK" name="Struts" path="[null]"/>
-
-  <!-- Real projects -->
-
-  <projects id="100" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
-            uuid="JKLM" project_uuid="JKLM" module_uuid="[null]" module_uuid_path="."
-            enabled="[true]" copy_resource_id="[null]" path="[null]"/>
-
-  <projects id="101" scope="PRJ" qualifier="TRK" kee="org.elasticsearch:elasticsearch" name="Elasticsearch"
-            uuid="KLMN" project_uuid="KLMN" module_uuid="[null]" module_uuid_path="."
-            enabled="[true]" copy_resource_id="[null]" path="[null]"/>
-
-  <resource_index id="1" kee="struts" resource_id="100" root_project_id="100" position="0" name_size="6" qualifier="TRK"/>
-  <resource_index id="2" kee="elasticsearch" resource_id="101" root_project_id="1" position="0" name_size="13" qualifier="TRK"/>
-  <resource_index id="3" kee="sticsearch" resource_id="101" root_project_id="1" position="1" name_size="13" qualifier="TRK"/>
-
-</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_only_authorized_projects_from_view.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_only_authorized_projects_from_view.json
new file mode 100644 (file)
index 0000000..9676629
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "total": 1,
+  "p": 1,
+  "ps": 10,
+  "components": [
+    {
+      "uuid": "JKLM",
+      "name": "Struts"
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_only_authorized_projects_from_view.xml b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_only_authorized_projects_from_view.xml
new file mode 100644 (file)
index 0000000..0b5c034
--- /dev/null
@@ -0,0 +1,30 @@
+<dataset>
+
+  <!-- Only struts is authorized for all user -->
+  <group_roles id="1" group_id="[null]" resource_id="100" role="user"/>
+
+  <!-- View -->
+  <projects id="11" uuid="EFGH" project_uuid="EFGH" module_uuid="[null]" module_uuid_path="." copy_resource_id="[null]" enabled="[true]"
+            kee="LANGUAGE_VIEW" scope="PRJ" qualifier="VW" name="By Language" path="[null]"/>
+
+  <projects id="112" uuid="GHIJ" project_uuid="EFGH" module_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="101" enabled="[true]"
+            kee="VIEW2org.elasticsearch:elasticsearch" scope="FIL" qualifier="TRK" name="Elasticsearch" path="[null]"/>
+
+  <projects id="113" uuid="HIJK" project_uuid="EFGH" module_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="100" enabled="[true]"
+            kee="VIEW2org.struts:struts" scope="FIL" qualifier="TRK" name="Struts" path="[null]"/>
+
+  <!-- Real projects -->
+
+  <projects id="100" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+            uuid="JKLM" project_uuid="JKLM" module_uuid="[null]" module_uuid_path="."
+            enabled="[true]" copy_resource_id="[null]" path="[null]"/>
+
+  <projects id="101" scope="PRJ" qualifier="TRK" kee="org.elasticsearch:elasticsearch" name="Elasticsearch"
+            uuid="KLMN" project_uuid="KLMN" module_uuid="[null]" module_uuid_path="."
+            enabled="[true]" copy_resource_id="[null]" path="[null]"/>
+
+  <resource_index id="1" kee="struts" resource_id="100" root_project_id="100" position="0" name_size="6" qualifier="TRK"/>
+  <resource_index id="2" kee="elasticsearch" resource_id="101" root_project_id="1" position="0" name_size="13" qualifier="TRK"/>
+  <resource_index id="3" kee="sticsearch" resource_id="101" root_project_id="1" position="1" name_size="13" qualifier="TRK"/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_only_first_page.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_only_first_page.json
new file mode 100644 (file)
index 0000000..e913f5e
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "total": 2,
+  "p": 1,
+  "ps": 1
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_paged_result.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_paged_result.json
new file mode 100644 (file)
index 0000000..d871108
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "total": 2,
+  "p": 2,
+  "ps": 1
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_projects_from_subview.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_projects_from_subview.json
new file mode 100644 (file)
index 0000000..9676629
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "total": 1,
+  "p": 1,
+  "ps": 10,
+  "components": [
+    {
+      "uuid": "JKLM",
+      "name": "Struts"
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_projects_from_view.json b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/return_projects_from_view.json
new file mode 100644 (file)
index 0000000..f7f99cc
--- /dev/null
@@ -0,0 +1,15 @@
+{
+  "total": 2,
+  "p": 1,
+  "ps": 10,
+  "components": [
+    {
+      "uuid": "JKLM",
+      "name": "Struts"
+    },
+    {
+      "uuid": "KLMN",
+      "name": "Elasticsearch"
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/shared.xml b/server/sonar-server/src/test/resources/org/sonar/server/component/ws/SearchViewComponentsActionTest/shared.xml
new file mode 100644 (file)
index 0000000..687ef3d
--- /dev/null
@@ -0,0 +1,35 @@
+<dataset>
+
+  <!-- Projects is authorized for all user -->
+  <group_roles id="1" group_id="[null]" resource_id="100" role="user"/>
+  <group_roles id="2" group_id="[null]" resource_id="101" role="user"/>
+
+  <!-- View with sub view -->
+  <projects id="11" uuid="EFGH" project_uuid="EFGH" module_uuid="[null]" module_uuid_path="." copy_resource_id="[null]" enabled="[true]"
+            kee="LANGUAGE_VIEW" scope="PRJ" qualifier="VW" name="By Language" path="[null]"/>
+
+  <projects id="112" uuid="GHIJ" project_uuid="EFGH" module_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="101" enabled="[true]"
+            kee="VIEW2org.elasticsearch:elasticsearch" scope="FIL" qualifier="TRK" name="Elasticsearch" path="[null]"/>
+
+  <!-- Sub view -->
+  <projects id="13" uuid="FGHI" project_uuid="EFGH" module_uuid="EFGH" module_uuid_path=".EFGH." copy_resource_id="[null]" enabled="[true]"
+            kee="JAVA_PROJECTS" scope="PRJ" qualifier="SVW" name="Java projects" path="[null]"/>
+
+  <projects id="113" uuid="HIJK" project_uuid="EFGH" module_uuid="FGHI" module_uuid_path=".EFGH.FGHI." copy_resource_id="100" enabled="[true]"
+            kee="VIEW2org.struts:struts" scope="FIL" qualifier="TRK" name="Struts" path="[null]"/>
+
+  <!-- Real projects -->
+
+  <projects id="100" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+            uuid="JKLM" project_uuid="JKLM" module_uuid="[null]" module_uuid_path="."
+            enabled="[true]" copy_resource_id="[null]" path="[null]"/>
+
+  <projects id="101" scope="PRJ" qualifier="TRK" kee="org.elasticsearch:elasticsearch" name="Elasticsearch"
+            uuid="KLMN" project_uuid="KLMN" module_uuid="[null]" module_uuid_path="."
+            enabled="[true]" copy_resource_id="[null]" path="[null]"/>
+
+  <resource_index id="1" kee="struts" resource_id="100" root_project_id="100" position="0" name_size="6" qualifier="TRK"/>
+  <resource_index id="2" kee="elasticsearch" resource_id="101" root_project_id="1" position="0" name_size="13" qualifier="TRK"/>
+  <resource_index id="3" kee="sticsearch" resource_id="101" root_project_id="1" position="1" name_size="13" qualifier="TRK"/>
+
+</dataset>
index 39339fe5ec2eb40e4a2f80eda597824034b4d83d..9c86d2c4e7f99ee6ec02e6541dbe1a591964a08c 100644 (file)
@@ -64,7 +64,8 @@
     <where>
       <if test="qualifiers != null and qualifiers.length!=0">
         and p.qualifier in
-        <foreach item="qualifier" index="index" collection="qualifiers" open="(" separator="," close=")">#{qualifier}
+        <foreach item="qualifier" index="index" collection="qualifiers" open="(" separator="," close=")">
+          #{qualifier}
         </foreach>
       </if>
       <if test="key != null">