aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Jambet <guillaume.jambet@sonarsource.com>2017-12-07 16:59:56 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2017-12-14 17:03:35 +0100
commit6c468901399f7ebfad132e66081c33f04f568735 (patch)
tree4dd1891feb6e12948b7cc66d78ce7283b30995e1
parent6de5e4f3d0630a7269625c5c855cbc7205e413d2 (diff)
downloadsonarqube-6c468901399f7ebfad132e66081c33f04f568735.tar.gz
sonarqube-6c468901399f7ebfad132e66081c33f04f568735.zip
SONAR-10134 Bringing Organization to Search Action
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/QgateProjectFinder.java23
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java69
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/search-example.json (renamed from server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-search.json)0
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java134
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java148
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SearchActionTest.java177
-rw-r--r--sonar-ws/src/main/protobuf/ws-qualitygates.proto12
7 files changed, 325 insertions, 238 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QgateProjectFinder.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QgateProjectFinder.java
index 4d9e79bd748..4f561bd8d5a 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QgateProjectFinder.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QgateProjectFinder.java
@@ -27,6 +27,7 @@ import org.sonar.api.web.UserRole;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
+import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualitygate.ProjectQgateAssociation;
import org.sonar.db.qualitygate.ProjectQgateAssociationDao;
import org.sonar.db.qualitygate.ProjectQgateAssociationDto;
@@ -52,21 +53,19 @@ public class QgateProjectFinder {
this.associationDao = dbClient.projectQgateAssociationDao();
}
- public Association find(ProjectQgateAssociationQuery query) {
- try (DbSession dbSession = dbClient.openSession(false)) {
- getQualityGateId(dbSession, query.gateId());
- List<ProjectQgateAssociationDto> projects = associationDao.selectProjects(dbSession, query);
- List<ProjectQgateAssociationDto> authorizedProjects = keepAuthorizedProjects(dbSession, projects);
+ public Association find(DbSession dbSession, OrganizationDto organization, ProjectQgateAssociationQuery query) {
+ getQualityGateId(dbSession, organization, query.gateId());
+ List<ProjectQgateAssociationDto> projects = associationDao.selectProjects(dbSession, query);
+ List<ProjectQgateAssociationDto> authorizedProjects = keepAuthorizedProjects(dbSession, projects);
- Paging paging = forPageIndex(query.pageIndex())
- .withPageSize(query.pageSize())
- .andTotal(authorizedProjects.size());
- return new Association(toProjectAssociations(getPaginatedProjects(authorizedProjects, paging)), paging.hasNextPage());
- }
+ Paging paging = forPageIndex(query.pageIndex())
+ .withPageSize(query.pageSize())
+ .andTotal(authorizedProjects.size());
+ return new Association(toProjectAssociations(getPaginatedProjects(authorizedProjects, paging)), paging.hasNextPage());
}
- private Long getQualityGateId(DbSession dbSession, String gateId) {
- return checkFound(qualitygateDao.selectById(dbSession, Long.valueOf(gateId)), "Quality gate '" + gateId + "' does not exists.").getId();
+ private Long getQualityGateId(DbSession dbSession, OrganizationDto organization, String gateId) {
+ return checkFound(qualitygateDao.selectByOrganizationAndId(dbSession, organization, Long.valueOf(gateId)), "Quality gate '" + gateId + "' does not exists.").getId();
}
private static List<ProjectQgateAssociationDto> getPaginatedProjects(List<ProjectQgateAssociationDto> projects, Paging paging) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java
index 285d723bec7..67d4e1b905c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java
@@ -23,18 +23,32 @@ 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.Param;
-import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualitygate.ProjectQgateAssociation;
import org.sonar.db.qualitygate.ProjectQgateAssociationQuery;
import org.sonar.server.qualitygate.QgateProjectFinder;
+import org.sonarqube.ws.Qualitygates;
+
+import static org.sonar.api.server.ws.WebService.Param.SELECTED;
+import static org.sonar.db.qualitygate.ProjectQgateAssociationQuery.ANY;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_ID;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PAGE;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PAGE_SIZE;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_QUERY;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
public class SearchAction implements QualityGatesWsAction {
+ private final DbClient dbClient;
private final QgateProjectFinder projectFinder;
+ private final QualityGatesWsSupport wsSupport;
- public SearchAction(QgateProjectFinder projectFinder) {
+ public SearchAction(DbClient dbClient, QgateProjectFinder projectFinder, QualityGatesWsSupport wsSupport) {
+ this.dbClient = dbClient;
this.projectFinder = projectFinder;
+ this.wsSupport = wsSupport;
}
@Override
@@ -43,47 +57,60 @@ public class SearchAction implements QualityGatesWsAction {
.setDescription("Search for projects associated (or not) to a quality gate.<br/>" +
"Only authorized projects for current user will be returned.")
.setSince("4.3")
- .setResponseExample(Resources.getResource(this.getClass(), "example-search.json"))
+ .setResponseExample(Resources.getResource(this.getClass(), "search-example.json"))
.setHandler(this);
- action.createParam(QualityGatesWsParameters.PARAM_GATE_ID)
+ action.createParam(PARAM_GATE_ID)
.setDescription("Quality Gate ID")
.setRequired(true)
.setExampleValue("1");
- action.createParam(QualityGatesWsParameters.PARAM_QUERY)
+ action.createParam(PARAM_QUERY)
.setDescription("To search for projects containing this string. If this parameter is set, \"selected\" is set to \"all\".")
.setExampleValue("abc");
action.addSelectionModeParam();
- action.createParam(QualityGatesWsParameters.PARAM_PAGE)
+ action.createParam(PARAM_PAGE)
.setDescription("Page number")
.setDefaultValue("1")
.setExampleValue("2");
- action.createParam(QualityGatesWsParameters.PARAM_PAGE_SIZE)
+ action.createParam(PARAM_PAGE_SIZE)
.setDescription("Page size")
.setExampleValue("10");
+
+ wsSupport.createOrganizationParam(action);
}
@Override
public void handle(Request request, Response response) {
- QgateProjectFinder.Association associations = projectFinder.find(ProjectQgateAssociationQuery.builder()
- .gateId(request.mandatoryParam(QualityGatesWsParameters.PARAM_GATE_ID))
- .membership(request.param(QualityGatesWsParameters.PARAM_QUERY) == null ? request.param(Param.SELECTED) : ProjectQgateAssociationQuery.ANY)
- .projectSearch(request.param(QualityGatesWsParameters.PARAM_QUERY))
- .pageIndex(request.paramAsInt(QualityGatesWsParameters.PARAM_PAGE))
- .pageSize(request.paramAsInt(QualityGatesWsParameters.PARAM_PAGE_SIZE))
- .build());
- try (JsonWriter writer = response.newJsonWriter()) {
- writer.beginObject().prop("more", associations.hasMoreResults());
- writer.name("results").beginArray();
+
+ try (DbSession dbSession = dbClient.openSession(false)) {
+
+ OrganizationDto organization = wsSupport.getOrganization(dbSession, request);
+
+ QgateProjectFinder.Association associations = projectFinder.find(dbSession, organization,
+ ProjectQgateAssociationQuery.builder()
+ .gateId(request.mandatoryParam(PARAM_GATE_ID))
+ .membership(request.param(PARAM_QUERY) == null ? request.param(SELECTED) : ANY)
+ .projectSearch(request.param(PARAM_QUERY))
+ .pageIndex(request.paramAsInt(PARAM_PAGE))
+ .pageSize(request.paramAsInt(PARAM_PAGE_SIZE))
+ .build());
+
+ Qualitygates.SearchResponse.Builder createResponse = Qualitygates.SearchResponse.newBuilder()
+ .setMore(associations.hasMoreResults());
+
for (ProjectQgateAssociation project : associations.projects()) {
- writer.beginObject().prop("id", project.id()).prop("name", project.name()).prop(Param.SELECTED, project.isMember()).endObject();
+ createResponse.addResultsBuilder()
+ .setId(project.id())
+ .setName(project.name())
+ .setSelected(project.isMember());
}
- writer.endArray().endObject().close();
+
+ writeProtobuf(createResponse.build(), request, response);
+
}
}
-
}
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-search.json b/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/search-example.json
index 7ad6eed5a24..7ad6eed5a24 100644
--- a/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-search.json
+++ b/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/search-example.json
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java
index fee90f42eba..2e0e79bafe0 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java
@@ -23,19 +23,16 @@ import com.google.common.base.Function;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
-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.DbTester;
import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.qualitygate.ProjectQgateAssociation;
@@ -48,6 +45,9 @@ import org.sonar.server.tester.UserSessionRule;
import static com.google.common.collect.FluentIterable.from;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
+import static org.sonar.db.component.ComponentTesting.newPublicProjectDto;
import static org.sonar.db.qualitygate.ProjectQgateAssociationQuery.IN;
import static org.sonar.db.qualitygate.ProjectQgateAssociationQuery.OUT;
import static org.sonar.db.qualitygate.ProjectQgateAssociationQuery.builder;
@@ -67,19 +67,16 @@ public class QgateProjectFinderTest {
private DbClient dbClient = dbTester.getDbClient();
private DbSession dbSession = dbTester.getSession();
private ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
- private QualityGateDto qGate;
private QgateProjectFinder underTest = new QgateProjectFinder(dbClient, userSession);
- @Before
- public void setUp() throws Exception {
- qGate = new QualityGateDto().setName("Default Quality Gate").setUuid(Uuids.createFast());
- dbClient.qualityGateDao().insert(dbSession, qGate);
- dbTester.commit();
- }
-
@Test
public void return_empty_association() {
- Association result = underTest.find(
+ OrganizationDto organization = dbTester.organizations().insert();
+ QualityGateDto qGate = dbTester.qualityGates().insertQualityGate(organization,
+ qualityGateDto -> qualityGateDto.setName("Default Quality Gate").setUuid(Uuids.createFast()));
+ dbTester.commit();
+
+ Association result = underTest.find(dbSession, organization,
builder()
.gateId(Long.toString(qGate.getId()))
.build());
@@ -89,12 +86,17 @@ public class QgateProjectFinderTest {
@Test
public void return_all_projects() {
- OrganizationDto org = dbTester.organizations().insert();
- ComponentDto associatedProject = insertProject(ComponentTesting.newPublicProjectDto(org));
- ComponentDto unassociatedProject = insertProject(ComponentTesting.newPublicProjectDto(org));
- associateProjectToQualitGate(associatedProject.getId());
+ OrganizationDto organization = dbTester.organizations().insert();
+ QualityGateDto qGate = dbTester.qualityGates().insertQualityGate(organization,
+ qualityGateDto -> qualityGateDto.setName("Default Quality Gate").setUuid(Uuids.createFast()));
+ dbTester.commit();
+ ComponentDto unassociatedProject = newPublicProjectDto(organization);
+ dbTester.components().insertComponent(unassociatedProject);
+ ComponentDto associatedProject = newPublicProjectDto(organization);
+ dbTester.components().insertComponent(associatedProject);
+ associateProjectToQualitGate(associatedProject, qGate);
- Association result = underTest.find(
+ Association result = underTest.find(dbSession, organization,
builder()
.gateId(Long.toString(qGate.getId()))
.build());
@@ -108,12 +110,18 @@ public class QgateProjectFinderTest {
@Test
public void return_only_associated_project() {
- OrganizationDto org = dbTester.organizations().insert();
- ComponentDto associatedProject = insertProject(ComponentTesting.newPublicProjectDto(org));
- insertProject(ComponentTesting.newPublicProjectDto(org));
- associateProjectToQualitGate(associatedProject.getId());
+ OrganizationDto organization = dbTester.organizations().insert();
+ QualityGateDto qGate = dbTester.qualityGates().insertQualityGate(organization,
+ qualityGateDto -> qualityGateDto.setName("Default Quality Gate").setUuid(Uuids.createFast()));
+ dbTester.commit();
+ ComponentDto project1 = newPublicProjectDto(organization);
+ dbTester.components().insertComponent(project1);
+ ComponentDto associatedProject = project1;
+ ComponentDto project = newPublicProjectDto(organization);
+ dbTester.components().insertComponent(project);
+ associateProjectToQualitGate(associatedProject, qGate);
- Association result = underTest.find(
+ Association result = underTest.find(dbSession, organization,
builder()
.membership(IN)
.gateId(Long.toString(qGate.getId()))
@@ -126,12 +134,17 @@ public class QgateProjectFinderTest {
@Test
public void return_only_unassociated_project() {
- OrganizationDto org = dbTester.organizations().insert();
- ComponentDto associatedProject = insertProject(ComponentTesting.newPublicProjectDto(org));
- ComponentDto unassociatedProject = insertProject(ComponentTesting.newPublicProjectDto(org));
- associateProjectToQualitGate(associatedProject.getId());
+ OrganizationDto organization = dbTester.organizations().insert();
+ QualityGateDto qGate = dbTester.qualityGates().insertQualityGate(organization,
+ qualityGateDto -> qualityGateDto.setName("Default Quality Gate").setUuid(Uuids.createFast()));
+ dbTester.commit();
+ ComponentDto unAssociatedProject = newPublicProjectDto(organization);
+ dbTester.components().insertComponent(unAssociatedProject);
+ ComponentDto associatedProject = newPublicProjectDto(organization);
+ dbTester.components().insertComponent(associatedProject);
+ associateProjectToQualitGate(associatedProject, qGate);
- Association result = underTest.find(
+ Association result = underTest.find(dbSession, organization,
builder()
.membership(OUT)
.gateId(Long.toString(qGate.getId()))
@@ -139,53 +152,65 @@ public class QgateProjectFinderTest {
Map<Long, ProjectQgateAssociation> projectsById = projectsById(result.projects());
assertThat(projectsById).hasSize(1);
- verifyProject(projectsById.get(unassociatedProject.getId()), false, unassociatedProject.name());
+ verifyProject(projectsById.get(unAssociatedProject.getId()), false, unAssociatedProject.name());
}
@Test
public void return_only_authorized_projects() {
+ OrganizationDto organization = dbTester.organizations().insert();
+ QualityGateDto qGate = dbTester.qualityGates().insertQualityGate(organization,
+ qualityGateDto -> qualityGateDto.setName("Default Quality Gate").setUuid(Uuids.createFast()));
+ dbTester.commit();
UserDto user = dbTester.users().insertUser("a_login");
- OrganizationDto organizationDto = dbTester.organizations().insert();
- ComponentDto project1 = componentDbTester.insertComponent(ComponentTesting.newPrivateProjectDto(organizationDto));
- componentDbTester.insertComponent(ComponentTesting.newPrivateProjectDto(organizationDto));
+ ComponentDto project = componentDbTester.insertComponent(newPrivateProjectDto(organization));
+ componentDbTester.insertComponent(newPrivateProjectDto(organization));
// User can only see project 1
- dbTester.users().insertProjectPermissionOnUser(user, UserRole.USER, project1);
+ dbTester.users().insertProjectPermissionOnUser(user, USER, project);
userSession.logIn(user.getLogin()).setUserId(user.getId());
- Association result = underTest.find(
+ Association result = underTest.find(dbSession, organization,
builder()
.gateId(Long.toString(qGate.getId()))
.build());
- verifyProjects(result, project1.getId());
+ verifyProjects(result, project.getId());
}
@Test
public void do_not_verify_permissions_if_user_is_root() {
- OrganizationDto org = dbTester.organizations().insert();
- ComponentDto project = componentDbTester.insertPrivateProject(org);
+ OrganizationDto organization = dbTester.organizations().insert();
+ QualityGateDto qGate = dbTester.qualityGates().insertQualityGate(organization,
+ qualityGateDto -> qualityGateDto.setName("Default Quality Gate").setUuid(Uuids.createFast()));
+ dbTester.commit();
+ ComponentDto project = componentDbTester.insertPrivateProject(organization);
ProjectQgateAssociationQuery query = builder()
.gateId(Long.toString(qGate.getId()))
.build();
userSession.logIn().setNonRoot();
- verifyProjects(underTest.find(query));
+ verifyProjects(underTest.find(dbSession, organization, query));
userSession.logIn().setRoot();
- verifyProjects(underTest.find(query), project.getId());
+ verifyProjects(underTest.find(dbSession, organization, query), project.getId());
}
@Test
public void test_paging() throws Exception {
- OrganizationDto org = dbTester.organizations().insert();
- ComponentDto project1 = insertProject(ComponentTesting.newPublicProjectDto(org).setName("Project 1"));
- ComponentDto project2 = insertProject(ComponentTesting.newPublicProjectDto(org).setName("Project 2"));
- ComponentDto project3 = insertProject(ComponentTesting.newPublicProjectDto(org).setName("Project 3"));
- associateProjectToQualitGate(project1.getId());
+ OrganizationDto organization = dbTester.organizations().insert();
+ QualityGateDto qGate = dbTester.qualityGates().insertQualityGate(organization,
+ qualityGateDto -> qualityGateDto.setName("Default Quality Gate").setUuid(Uuids.createFast()));
+ dbTester.commit();
+ ComponentDto project1 = newPublicProjectDto(organization).setName("Project 1");
+ dbTester.components().insertComponent(project1);
+ associateProjectToQualitGate(project1, qGate);
+ ComponentDto project2 = newPublicProjectDto(organization).setName("Project 2");
+ dbTester.components().insertComponent(project2);
+ ComponentDto project3 = newPublicProjectDto(organization).setName("Project 3");
+ dbTester.components().insertComponent(project3);
// Return partial result on first page
- verifyPaging(underTest.find(
+ verifyPaging(underTest.find(dbSession, organization,
builder().gateId(Long.toString(qGate.getId()))
.pageIndex(1)
.pageSize(1)
@@ -193,7 +218,7 @@ public class QgateProjectFinderTest {
true, project1.getId());
// Return partial result on second page
- verifyPaging(underTest.find(
+ verifyPaging(underTest.find(dbSession, organization,
builder().gateId(Long.toString(qGate.getId()))
.pageIndex(2)
.pageSize(1)
@@ -201,7 +226,7 @@ public class QgateProjectFinderTest {
true, project2.getId());
// Return partial result on first page
- verifyPaging(underTest.find(
+ verifyPaging(underTest.find(dbSession, organization,
builder().gateId(Long.toString(qGate.getId()))
.pageIndex(1)
.pageSize(2)
@@ -209,7 +234,7 @@ public class QgateProjectFinderTest {
true, project1.getId(), project2.getId());
// Return all result on first page
- verifyPaging(underTest.find(
+ verifyPaging(underTest.find(dbSession, organization,
builder().gateId(Long.toString(qGate.getId()))
.pageIndex(1)
.pageSize(3)
@@ -217,7 +242,7 @@ public class QgateProjectFinderTest {
false, project1.getId(), project2.getId(), project3.getId());
// Return no result as page index is off limit
- verifyPaging(underTest.find(
+ verifyPaging(underTest.find(dbSession, organization,
builder().gateId(Long.toString(qGate.getId()))
.pageIndex(3)
.pageSize(3)
@@ -228,7 +253,7 @@ public class QgateProjectFinderTest {
@Test
public void fail_on_unknown_quality_gate() {
expectedException.expect(NotFoundException.class);
- underTest.find(builder().gateId("123").build());
+ underTest.find(dbSession, dbTester.organizations().insert(), builder().gateId("123").build());
}
private void verifyProject(ProjectQgateAssociation project, boolean expectedMembership, String expectedName) {
@@ -245,19 +270,14 @@ public class QgateProjectFinderTest {
assertThat(association.projects()).extracting("id").containsOnly(expectedProjectIds);
}
- private void associateProjectToQualitGate(long projectId) {
+ private void associateProjectToQualitGate(ComponentDto component, QualityGateDto qualityGate) {
dbClient.propertiesDao().saveProperty(
new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY)
- .setResourceId(projectId)
- .setValue(Long.toString(qGate.getId())));
+ .setResourceId(component.getId())
+ .setValue(Long.toString(qualityGate.getId())));
dbTester.commit();
}
- private ComponentDto insertProject(ComponentDto project) {
- dbTester.components().insertComponent(project);
- return project;
- }
-
private static Map<Long, ProjectQgateAssociation> projectsById(List<ProjectQgateAssociation> projects) {
return from(projects).uniqueIndex(ProjectToId.INSTANCE);
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java
deleted file mode 100644
index 0a6b0377215..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.qualitygate.ws;
-
-import com.google.common.collect.ImmutableList;
-import java.util.List;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.server.ws.Change;
-import org.sonar.api.server.ws.WebService.Action;
-import org.sonar.api.server.ws.WebService.Controller;
-import org.sonar.db.qualitygate.ProjectQgateAssociation;
-import org.sonar.db.qualitygate.ProjectQgateAssociationQuery;
-import org.sonar.server.qualitygate.QgateProjectFinder;
-import org.sonar.server.qualitygate.QgateProjectFinder.Association;
-import org.sonar.server.qualitygate.QualityGates;
-import org.sonar.server.ws.RemovedWebServiceHandler;
-import org.sonar.server.ws.WsTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-// TODO split testcases in action tests
-// TODO restore
-@RunWith(MockitoJUnitRunner.class)
-@Ignore
-public class QualityGatesWsTest {
-
- @Mock
- private QualityGates qGates;
-
- @Mock
- private QgateProjectFinder projectFinder;
-
- WsTester tester;
-
- @Before
- public void setUp() {
- tester = new WsTester(new QualityGatesWs(
- new SearchAction(projectFinder),
- new CreateAction(null, null, null, null),
- new SetAsDefaultAction(qGates)));
- }
-
- @Test
- public void define_ws() {
- Controller controller = tester.controller("api/qualitygates");
- assertThat(controller).isNotNull();
- assertThat(controller.path()).isEqualTo("api/qualitygates");
- assertThat(controller.description()).isNotEmpty();
- assertThat(controller.actions()).hasSize(6);
-
- Action setDefault = controller.action("set_as_default");
- assertThat(setDefault).isNotNull();
- assertThat(setDefault.handler()).isNotNull();
- assertThat(setDefault.since()).isEqualTo("4.3");
- assertThat(setDefault.isPost()).isTrue();
- assertThat(setDefault.param("id")).isNotNull();
- assertThat(setDefault.isInternal()).isFalse();
-
- Action unsetDefault = controller.action("unset_default");
- assertThat(unsetDefault).isNotNull();
- assertThat(unsetDefault.handler()).isNotNull();
- assertThat(unsetDefault.since()).isEqualTo("4.3");
- assertThat(unsetDefault.deprecatedSince()).isEqualTo("7.0");
- assertThat(unsetDefault.changelog())
- .extracting(Change::getVersion, Change::getDescription)
- .containsOnly(
- tuple("7.0", "Unset a quality gate is no more authorized"));
- assertThat(unsetDefault.isPost()).isTrue();
- assertThat(unsetDefault.handler()).isEqualTo(RemovedWebServiceHandler.INSTANCE);
- assertThat(unsetDefault.responseExample()).isEqualTo(RemovedWebServiceHandler.INSTANCE.getResponseExample());
- assertThat(unsetDefault.isInternal()).isFalse();
- }
-
- @Test
- public void search_with_query() throws Exception {
- long gateId = 12345L;
- Association assoc = mock(Association.class);
- when(assoc.hasMoreResults()).thenReturn(true);
- List<ProjectQgateAssociation> projects = ImmutableList.of(
- new ProjectQgateAssociation().setId(42L).setName("Project One").setMember(false),
- new ProjectQgateAssociation().setId(24L).setName("Project Two").setMember(true));
- when(assoc.projects()).thenReturn(projects);
- when(projectFinder.find(any(ProjectQgateAssociationQuery.class))).thenReturn(assoc);
-
- tester.newGetRequest("api/qualitygates", "search")
- .setParam("gateId", Long.toString(gateId))
- .setParam("query", "Project")
- .execute()
- .assertJson("{\"more\":true,\"results\":["
- + "{\"id\":42,\"name\":\"Project One\",\"selected\":false},"
- + "{\"id\":24,\"name\":\"Project Two\",\"selected\":true}"
- + "]}");
- ArgumentCaptor<ProjectQgateAssociationQuery> queryCaptor = ArgumentCaptor.forClass(ProjectQgateAssociationQuery.class);
- verify(projectFinder).find(queryCaptor.capture());
- ProjectQgateAssociationQuery query = queryCaptor.getValue();
- assertThat(query.membership()).isEqualTo(ProjectQgateAssociationQuery.ANY);
- }
-
- @Test
- public void search_nominal() throws Exception {
- long gateId = 12345L;
- Association assoc = mock(Association.class);
- when(assoc.hasMoreResults()).thenReturn(true);
- List<ProjectQgateAssociation> projects = ImmutableList.of(
- new ProjectQgateAssociation().setId(24L).setName("Project Two").setMember(true));
- when(assoc.projects()).thenReturn(projects);
- when(projectFinder.find(any(ProjectQgateAssociationQuery.class))).thenReturn(assoc);
-
- tester.newGetRequest("api/qualitygates", "search")
- .setParam("gateId", Long.toString(gateId))
- .execute()
- .assertJson("{\"more\":true,\"results\":["
- + "{\"id\":24,\"name\":\"Project Two\",\"selected\":true}"
- + "]}");
- ArgumentCaptor<ProjectQgateAssociationQuery> queryCaptor = ArgumentCaptor.forClass(ProjectQgateAssociationQuery.class);
- verify(projectFinder).find(queryCaptor.capture());
- ProjectQgateAssociationQuery query = queryCaptor.getValue();
- assertThat(query.membership()).isEqualTo(ProjectQgateAssociationQuery.IN);
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SearchActionTest.java
new file mode 100644
index 00000000000..ebc4997eb21
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SearchActionTest.java
@@ -0,0 +1,177 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.qualitygate.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
+import org.sonar.server.qualitygate.QgateProjectFinder;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.Qualitygates.SearchResponse;
+
+import static java.lang.String.format;
+import static java.lang.String.valueOf;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.tuple;
+import static org.sonar.api.utils.System2.INSTANCE;
+import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_ID;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ORGANIZATION;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PAGE;
+import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PAGE_SIZE;
+
+public class SearchActionTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+
+ @Rule
+ public DbTester db = DbTester.create(INSTANCE);
+
+ private DbClient dbClient = db.getDbClient();
+ private DbSession dbSession = db.getSession();
+ private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
+
+ private QgateProjectFinder projectFinder = new QgateProjectFinder(dbClient, userSession);
+ private QualityGatesWsSupport wsSupport = new QualityGatesWsSupport(dbClient, userSession, defaultOrganizationProvider);
+
+ private SearchAction underTest = new SearchAction(dbClient, projectFinder, wsSupport);
+ private WsActionTester ws = new WsActionTester(underTest);
+
+ @Test
+ public void definition() {
+ WebService.Action action = ws.getDef();
+
+ assertThat(action).isNotNull();
+ assertThat(action.isInternal()).isFalse();
+ assertThat(action.isPost()).isFalse();
+ assertThat(action.responseExampleAsString()).isNotEmpty();
+ assertThat(action.params())
+ .extracting(WebService.Param::key, WebService.Param::isRequired)
+ .containsExactlyInAnyOrder(
+ tuple("gateId", true),
+ tuple("query", false),
+ tuple("organization", false),
+ tuple("selected", false),
+ tuple("page", false),
+ tuple("pageSize", false));
+ }
+
+ @Test
+ public void search_projects_of_a_quality_gate_from_an_organization() {
+ OrganizationDto organization = db.organizations().insert();
+ ComponentDto project = db.components().insertPublicProject(organization);
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(organization);
+ associateProjectToQualityGate(project, qualityGate);
+ userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+
+ SearchResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_ID, valueOf(qualityGate.getId()))
+ .setParam(PARAM_ORGANIZATION, valueOf(organization.getKey()))
+ .executeProtobuf(SearchResponse.class);
+
+ assertThat(response).isNotNull();
+ assertThat(response.getMore()).isFalse();
+ assertThat(response.getResultsCount()).isEqualTo(1);
+ assertThat(response.getResults(0).getId()).isEqualTo(project.getId());
+ assertThat(response.getResults(0).getName().substring(4)).isEqualTo(project.getKey().substring(3));
+ }
+
+ @Test
+ public void search_on_default_organization_when_none_is_provided() {
+ OrganizationDto defaultOrganization = db.getDefaultOrganization();
+
+ ComponentDto project = db.components().insertPublicProject(defaultOrganization);
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(defaultOrganization);
+ associateProjectToQualityGate(project, qualityGate);
+ userSession.addPermission(ADMINISTER_QUALITY_GATES, defaultOrganization);
+
+ SearchResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_ID, valueOf(qualityGate.getId()))
+ .executeProtobuf(SearchResponse.class);
+
+ assertThat(response).isNotNull();
+ assertThat(response.getMore()).isFalse();
+ assertThat(response.getResultsCount()).isEqualTo(1);
+ assertThat(response.getResults(0).getId()).isEqualTo(project.getId());
+ assertThat(response.getResults(0).getName().substring(4)).isEqualTo(project.getKey().substring(3));
+ }
+
+ @Test
+ public void fail_when_quality_gates_does_not_belong_to_organization() {
+ OrganizationDto organization = db.organizations().insert();
+ OrganizationDto otherOrganization = db.organizations().insert();
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(otherOrganization);
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage(format("Quality gate '%s' does not exists.", qualityGate.getId()));
+
+ ws.newRequest()
+ .setParam(PARAM_GATE_ID, valueOf(qualityGate.getId()))
+ .setParam(PARAM_ORGANIZATION, valueOf(organization.getKey()))
+ .executeProtobuf(SearchResponse.class);
+
+ }
+
+ @Test
+ public void more_is_true_when_not_all_project_fit_in_page_size() {
+ OrganizationDto organization = db.organizations().insert();
+ QualityGateDto qualityGate = db.qualityGates().insertQualityGate(organization);
+ for (int i = 0; i < 20; i++) {
+ ComponentDto project1 = db.components().insertPublicProject();
+ associateProjectToQualityGate(project1, qualityGate);
+ }
+
+ userSession.addPermission(ADMINISTER_QUALITY_GATES, organization);
+
+ SearchResponse response = ws.newRequest()
+ .setParam(PARAM_GATE_ID, valueOf(qualityGate.getId()))
+ .setParam(PARAM_ORGANIZATION, valueOf(organization.getKey()))
+ .setParam(PARAM_PAGE_SIZE, valueOf(10))
+ .setParam(PARAM_PAGE, valueOf(1))
+ .executeProtobuf(SearchResponse.class);
+
+ assertThat(response).isNotNull();
+ assertThat(response.getMore()).isTrue();
+ assertThat(response.getResultsCount()).isEqualTo(10);
+ }
+
+ private void associateProjectToQualityGate(ComponentDto componentDto, QualityGateDto qualityGateDto) {
+ dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto()
+ .setKey("sonar.qualitygate")
+ .setResourceId(componentDto.getId())
+ .setValue(valueOf(qualityGateDto.getId())));
+ db.commit();
+ }
+}
diff --git a/sonar-ws/src/main/protobuf/ws-qualitygates.proto b/sonar-ws/src/main/protobuf/ws-qualitygates.proto
index 08e1c4570dd..c9b63db5776 100644
--- a/sonar-ws/src/main/protobuf/ws-qualitygates.proto
+++ b/sonar-ws/src/main/protobuf/ws-qualitygates.proto
@@ -136,6 +136,18 @@ message ShowWsResponse {
}
}
+// GET api/qualitygates/search
+message SearchResponse {
+ optional bool more = 1;
+ repeated Result results = 2;
+
+ message Result {
+ optional int64 id = 1;
+ optional string name = 2;
+ optional bool selected = 3;
+ }
+}
+
// GET api/qualitygates/list
message ListWsResponse {
repeated QualityGate qualitygates = 1;