aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ComponentFinder.java20
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java90
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ComponentFinderTest.java59
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java7
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java22
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SelectActionTest.java210
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesService.java9
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/SelectWsRequest.java57
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/qualitygate/QualityGatesServiceTest.java63
9 files changed, 506 insertions, 31 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentFinder.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentFinder.java
index 41554dd51ce..1f4efe50b40 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentFinder.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentFinder.java
@@ -37,6 +37,7 @@ import static org.sonar.server.ws.WsUtils.checkRequest;
public class ComponentFinder {
private static final String MSG_COMPONENT_ID_OR_KEY_TEMPLATE = "Either '%s' or '%s' must be provided, not both";
+ public static final String MSG_PARAMETER_MUST_NOT_BE_EMPTY = "The '%s' parameter must not be empty";
private final DbClient dbClient;
@@ -48,11 +49,22 @@ public class ComponentFinder {
checkArgument(componentUuid != null ^ componentKey != null, MSG_COMPONENT_ID_OR_KEY_TEMPLATE, parameterNames.getUuidParam(), parameterNames.getKeyParam());
if (componentUuid != null) {
- checkArgument(!componentUuid.isEmpty(), "The '%s' parameter must not be empty", parameterNames.getUuidParam());
+ checkArgument(!componentUuid.isEmpty(), MSG_PARAMETER_MUST_NOT_BE_EMPTY, parameterNames.getUuidParam());
return getByUuid(dbSession, componentUuid);
}
- checkArgument(!componentKey.isEmpty(), "The '%s' parameter must not be empty", parameterNames.getKeyParam());
+ checkArgument(!componentKey.isEmpty(), MSG_PARAMETER_MUST_NOT_BE_EMPTY, parameterNames.getKeyParam());
+ return getByKey(dbSession, componentKey);
+ }
+
+ public ComponentDto getByIdOrKey(DbSession dbSession, @Nullable Long componentId, @Nullable String componentKey, ParamNames parameterNames) {
+ checkArgument(componentId != null ^ componentKey != null, MSG_COMPONENT_ID_OR_KEY_TEMPLATE, parameterNames.getUuidParam(), parameterNames.getKeyParam());
+
+ if (componentId != null) {
+ return getById(dbSession, componentId);
+ }
+
+ checkArgument(!componentKey.isEmpty(), MSG_PARAMETER_MUST_NOT_BE_EMPTY, parameterNames.getKeyParam());
return getByKey(dbSession, componentKey);
}
@@ -64,6 +76,10 @@ public class ComponentFinder {
return getIfPresentOrFail(dbClient.componentDao().selectByUuid(dbSession, uuid), format("Component id '%s' not found", uuid));
}
+ public ComponentDto getById(DbSession dbSession, long id) {
+ return getIfPresentOrFail(dbClient.componentDao().selectById(dbSession, id), format("Component id '%s' not found", id));
+ }
+
/**
* A project can be:
* <ul>
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java
index 8f55ba0d85e..5e162479244 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java
@@ -19,45 +19,109 @@
*/
package org.sonar.server.qualitygate.ws;
+import org.elasticsearch.common.Nullable;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
-import org.sonar.server.qualitygate.QualityGates;
-import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.component.ComponentFinder.ParamNames;
+import org.sonar.server.user.UserSession;
+import org.sonarqube.ws.client.qualitygate.SelectWsRequest;
+import static org.sonar.server.qualitygate.QualityGates.SONAR_QUALITYGATE_PROPERTY;
+import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
+import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
+import static org.sonar.server.ws.WsUtils.checkFound;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_GATE_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY;
public class SelectAction implements QualityGatesWsAction {
+ private final DbClient dbClient;
+ private final UserSession userSession;
+ private final ComponentFinder componentFinder;
- private final QualityGates qualityGates;
-
- public SelectAction(QualityGates qualityGates) {
- this.qualityGates = qualityGates;
+ public SelectAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder) {
+ this.dbClient = dbClient;
+ this.userSession = userSession;
+ this.componentFinder = componentFinder;
}
@Override
public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("select")
- .setDescription("Associate a project to a quality gate. Require Administer Quality Gates permission")
+ .setDescription("Associate a project to a quality gate.<br>" +
+ "The '%s' or '%s' must be provided.<br>" +
+ "Require Administer Quality Gates permission.",
+ PARAM_PROJECT_ID, PARAM_PROJECT_KEY)
.setPost(true)
.setSince("4.3")
.setHandler(this);
- action.createParam(QualityGatesWsParameters.PARAM_GATE_ID)
- .setDescription("Quality Gate ID")
+ action.createParam(PARAM_GATE_ID)
+ .setDescription("Quality gate id")
.setRequired(true)
.setExampleValue("1");
action.createParam(PARAM_PROJECT_ID)
- .setDescription("Project ID")
- .setRequired(true)
- .setExampleValue("12");
+ .setDescription("Project id")
+ .setExampleValue("12")
+ .setDeprecatedSince("6.1");
+
+ action.createParam(PARAM_PROJECT_KEY)
+ .setDescription("Project key")
+ .setExampleValue(KEY_PROJECT_EXAMPLE_001)
+ .setSince("6.1");
}
@Override
public void handle(Request request, Response response) {
- qualityGates.associateProject(QualityGatesWs.parseId(request, QualityGatesWsParameters.PARAM_GATE_ID), QualityGatesWs.parseId(request, PARAM_PROJECT_ID));
+ doHandle(toSelectWsRequest(request));
response.noContent();
}
+ private void doHandle(SelectWsRequest request) {
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ checkQualityGate(dbClient, request.getGateId());
+ ComponentDto project = getProject(dbSession, request.getProjectId(), request.getProjectKey());
+
+ dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto()
+ .setKey(SONAR_QUALITYGATE_PROPERTY)
+ .setResourceId(project.getId())
+ .setValue(String.valueOf(request.getGateId())));
+
+ dbSession.commit();
+ } finally {
+ dbClient.closeSession(dbSession);
+ }
+ }
+
+ private static SelectWsRequest toSelectWsRequest(Request request) {
+ return new SelectWsRequest()
+ .setGateId(request.mandatoryParamAsLong(PARAM_GATE_ID))
+ .setProjectId(request.paramAsLong(PARAM_PROJECT_ID))
+ .setProjectKey(request.param(PARAM_PROJECT_KEY));
+ }
+
+ private ComponentDto getProject(DbSession dbSession, @Nullable Long projectId, @Nullable String projectKey) {
+ ComponentDto project = componentFinder.getByIdOrKey(dbSession, projectId, projectKey, ParamNames.PROJECT_ID_AND_KEY);
+
+ if (!userSession.hasPermission(GlobalPermissions.QUALITY_GATE_ADMIN) &&
+ !userSession.hasComponentUuidPermission(UserRole.ADMIN, project.uuid())) {
+ throw insufficientPrivilegesException();
+ }
+
+ return project;
+ }
+
+ private static void checkQualityGate(DbClient dbClient, long id) {
+ checkFound(dbClient.qualityGateDao().selectById(id), "There is no quality gate with id=" + id);
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentFinderTest.java
index 8902b9a0a59..4df8ea6cef0 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentFinderTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentFinderTest.java
@@ -95,6 +95,47 @@ public class ComponentFinderTest {
}
@Test
+ public void getByIdOrKey_fail_when_id_and_key_are_null() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Either 'id' or 'key' must be provided, not both");
+
+ underTest.getByIdOrKey(dbSession, null, null, ID_AND_KEY);
+ }
+
+ @Test
+ public void getByIdOrKey_fail_when_both_id_and_key_are_provided() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Either 'id' or 'key' must be provided, not both");
+
+ underTest.getByIdOrKey(dbSession, 1L, "project-key", ID_AND_KEY);
+ }
+
+ @Test
+ public void getByIdOrKey_fail_when_key_is_empty() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The 'key' parameter must not be empty");
+
+ underTest.getByIdOrKey(dbSession, null, "", ID_AND_KEY);
+ }
+
+
+ @Test
+ public void getByIdOrKey_fail_when_component_id_not_found() {
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage("Component id '175' not found");
+
+ underTest.getByIdOrKey(dbSession, 175L, null, ID_AND_KEY);
+ }
+
+ @Test
+ public void getByIdOrKey_fail_when_component_key_not_found() {
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage("Component key 'project-key' not found");
+
+ underTest.getByIdOrKey(dbSession, null, "project-key", ID_AND_KEY);
+ }
+
+ @Test
public void get_component_by_uuid() {
componentDb.insertComponent(newProjectDto("project-uuid"));
@@ -111,4 +152,22 @@ public class ComponentFinderTest {
assertThat(component.key()).isEqualTo("project-key");
}
+
+ @Test
+ public void getByIdOrKey_get_component_by_id() {
+ ComponentDto source = componentDb.insertComponent(newProjectDto());
+
+ ComponentDto component = underTest.getByIdOrKey(dbSession, source.getId(), null, ID_AND_KEY);
+
+ assertThat(component.getId()).isEqualTo(source.getId());
+ }
+
+ @Test
+ public void getByIdOrKey_get_component_by_key() {
+ componentDb.insertComponent(newProjectDto().setKey("project-key"));
+
+ ComponentDto component = underTest.getByIdOrKey(dbSession, null, "project-key", ID_AND_KEY);
+
+ assertThat(component.key()).isEqualTo("project-key");
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java
index 70b98ba5878..619fee9c638 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java
@@ -32,8 +32,11 @@ import org.sonar.api.i18n.I18n;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.Metric.ValueType;
import org.sonar.core.timemachine.Periods;
+import org.sonar.db.DbClient;
+import org.sonar.server.component.ComponentFinder;
import org.sonar.server.qualitygate.QgateProjectFinder;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsTester;
import java.util.Collection;
@@ -62,12 +65,14 @@ public class AppActionTest {
@Before
public void setUp() {
+ SelectAction selectAction = new SelectAction(mock(DbClient.class), mock(UserSessionRule.class), mock(ComponentFinder.class));
+
tester = new WsTester(new QualityGatesWs(
new ListAction(qGates), new ShowAction(qGates), new SearchAction(mock(QgateProjectFinder.class)),
new CreateAction(qGates), new CopyAction(qGates), new DestroyAction(qGates), new RenameAction(qGates),
new SetAsDefaultAction(qGates), new UnsetDefaultAction(qGates),
new CreateConditionAction(qGates), new UpdateConditionAction(qGates), new DeleteConditionAction(qGates),
- new SelectAction(qGates), new DeselectAction(qGates), new AppAction(qGates)));
+ selectAction, new DeselectAction(qGates), new AppAction(qGates)));
}
@Test
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
index 7ae85a1d2f5..fce093f1e56 100644
--- 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
@@ -21,6 +21,7 @@ package org.sonar.server.qualitygate.ws;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -29,18 +30,19 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.server.ws.WebService.Action;
import org.sonar.api.server.ws.WebService.Controller;
+import org.sonar.db.DbClient;
import org.sonar.db.qualitygate.ProjectQgateAssociation;
import org.sonar.db.qualitygate.ProjectQgateAssociationQuery;
import org.sonar.db.qualitygate.QualityGateConditionDto;
import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.qualitygate.QgateProjectFinder;
import org.sonar.server.qualitygate.QgateProjectFinder.Association;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsTester;
-import java.util.List;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
@@ -64,12 +66,14 @@ public class QualityGatesWsTest {
@Before
public void setUp() {
+ SelectAction selectAction = new SelectAction(mock(DbClient.class), mock(UserSessionRule.class), mock(ComponentFinder.class));
+
tester = new WsTester(new QualityGatesWs(
new ListAction(qGates), new ShowAction(qGates), new SearchAction(projectFinder),
new CreateAction(qGates), new CopyAction(qGates), new DestroyAction(qGates), new RenameAction(qGates),
new SetAsDefaultAction(qGates), new UnsetDefaultAction(qGates),
new CreateConditionAction(qGates), new UpdateConditionAction(qGates), new DeleteConditionAction(qGates),
- new SelectAction(qGates), new DeselectAction(qGates), new AppAction(qGates)));
+ selectAction, new DeselectAction(qGates), new AppAction(qGates)));
}
@Test
@@ -427,18 +431,6 @@ public class QualityGatesWsTest {
}
@Test
- public void select_nominal() throws Exception {
- long gateId = 42L;
- long projectId = 666L;
- tester.newPostRequest("api/qualitygates", "select")
- .setParam("gateId", Long.toString(gateId))
- .setParam("projectId", Long.toString(projectId))
- .execute()
- .assertNoContent();
- verify(qGates).associateProject(gateId, projectId);
- }
-
- @Test
public void deselect_nominal() throws Exception {
long gateId = 42L;
long projectId = 666L;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SelectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SelectActionTest.java
new file mode 100644
index 00000000000..3cfc31a05e9
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/SelectActionTest.java
@@ -0,0 +1,210 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.qualitygate.ws;
+
+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.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.qualitygate.QualityGateDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsActionTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN;
+import static org.sonar.core.permission.GlobalPermissions.QUALITY_PROFILE_ADMIN;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonar.server.qualitygate.QualityGates.SONAR_QUALITYGATE_PROPERTY;
+
+public class SelectActionTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+
+ @Rule
+ public DbTester db = DbTester.create(System2.INSTANCE);
+ DbClient dbClient = db.getDbClient();
+ DbSession dbSession = db.getSession();
+ ComponentDbTester componentDb = new ComponentDbTester(db);
+
+ WsActionTester ws;
+
+ SelectAction underTest;
+
+ @Before
+ public void setUp() {
+ ComponentFinder componentFinder = new ComponentFinder(dbClient);
+ underTest = new SelectAction(dbClient, userSession, componentFinder);
+ ws = new WsActionTester(underTest);
+
+ userSession.login("login").setGlobalPermissions(QUALITY_GATE_ADMIN);
+ }
+
+ @Test
+ public void select_by_id() throws Exception {
+ ComponentDto project = insertProject();
+ QualityGateDto gate = insertQualityGate();
+ String gateId = String.valueOf(gate.getId());
+
+ callById(gateId, project.getId());
+ assertSelected(gateId, project.getId());
+ }
+
+ @Test
+ public void select_by_key() throws Exception {
+ ComponentDto project = insertProject();
+ QualityGateDto gate = insertQualityGate();
+ String gateId = String.valueOf(gate.getId());
+
+ callByKey(gateId, project.getKey());
+ assertSelected(gateId, project.getId());
+ }
+
+ @Test
+ public void project_admin() throws Exception {
+ ComponentDto project = insertProject();
+ QualityGateDto gate = insertQualityGate();
+ String gateId = String.valueOf(gate.getId());
+
+ userSession.login("login").addProjectUuidPermissions(UserRole.ADMIN, project.uuid());
+
+ callByKey(gateId, project.getKey());
+ assertSelected(gateId, project.getId());
+ }
+
+ @Test
+ public void system_admin() throws Exception {
+ ComponentDto project = insertProject();
+ QualityGateDto gate = insertQualityGate();
+ String gateId = String.valueOf(gate.getId());
+
+ userSession.login("login").setGlobalPermissions(SYSTEM_ADMIN);
+
+ callByKey(gateId, project.getKey());
+ assertSelected(gateId, project.getId());;
+ }
+
+ @Test
+ public void fail_when_no_quality_gate() throws Exception {
+ ComponentDto project = insertProject();
+
+ expectedException.expect(NotFoundException.class);
+ callByKey("1", project.getKey());
+ }
+
+ @Test
+ public void fail_when_no_project_id() throws Exception {
+ QualityGateDto gate = insertQualityGate();
+ String gateId = String.valueOf(gate.getId());
+
+ expectedException.expect(NotFoundException.class);
+ callById(gateId, 1L);
+ }
+
+ @Test
+ public void fail_when_no_project_key() throws Exception {
+ QualityGateDto gate = insertQualityGate();
+ String gateId = String.valueOf(gate.getId());
+
+ expectedException.expect(NotFoundException.class);
+ callByKey(gateId, "unknown");
+ }
+
+ @Test
+ public void fail_when_anonymous() throws Exception {
+ ComponentDto project = insertProject();
+ QualityGateDto gate = insertQualityGate();
+ String gateId = String.valueOf(gate.getId());
+
+ userSession.anonymous();
+
+ expectedException.expect(ForbiddenException.class);
+ callByKey(gateId, project.getKey());
+ }
+
+ @Test
+ public void fail_when_not_project_admin() throws Exception {
+ ComponentDto project = insertProject();
+ QualityGateDto gate = insertQualityGate();
+ String gateId = String.valueOf(gate.getId());
+
+ userSession.login("login").addProjectUuidPermissions(UserRole.ISSUE_ADMIN, project.uuid());
+
+ expectedException.expect(ForbiddenException.class);
+ callByKey(gateId, project.getKey());
+ }
+
+ @Test
+ public void fail_when_not_quality_gates_admin() throws Exception {
+ ComponentDto project = insertProject();
+ QualityGateDto gate = insertQualityGate();
+ String gateId = String.valueOf(gate.getId());
+
+ userSession.login("login").setGlobalPermissions(QUALITY_PROFILE_ADMIN);
+
+ expectedException.expect(ForbiddenException.class);
+ callByKey(gateId, project.getKey());
+ }
+
+ private ComponentDto insertProject() {
+ return componentDb.insertComponent(newProjectDto());
+ }
+
+ private QualityGateDto insertQualityGate() {
+ QualityGateDto gate = new QualityGateDto().setName("Custom");
+ dbClient.qualityGateDao().insert(dbSession, gate);
+ dbSession.commit();
+ return gate;
+ }
+
+ private void callByKey(String gateId, String projectKey) {
+ ws.newRequest()
+ .setMethod("POST")
+ .setParam("gateId", String.valueOf(gateId))
+ .setParam("projectKey", projectKey)
+ .execute();
+ }
+
+ private void callById(String gateId, Long projectId) {
+ ws.newRequest()
+ .setMethod("POST")
+ .setParam("gateId", String.valueOf(gateId))
+ .setParam("projectId", String.valueOf(projectId))
+ .execute();
+ }
+
+ private void assertSelected(String gateId, Long projectId) {
+ assertThat(dbClient.propertiesDao().selectProjectProperty(projectId, SONAR_QUALITYGATE_PROPERTY).getValue()).isEqualTo(gateId);
+ }
+}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesService.java
index bd00874f57a..fa8a57ab4b9 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesService.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesService.java
@@ -22,9 +22,11 @@ package org.sonarqube.ws.client.qualitygate;
import org.sonarqube.ws.WsQualityGates.ProjectStatusWsResponse;
import org.sonarqube.ws.client.BaseService;
import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsConnector;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_ANALYSIS_ID;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_GATE_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY;
@@ -41,4 +43,11 @@ public class QualityGatesService extends BaseService {
.setParam(PARAM_PROJECT_KEY, request.getProjectKey()),
ProjectStatusWsResponse.parser());
}
+
+ public void associateProject(SelectWsRequest request) {
+ call(new PostRequest(path("select"))
+ .setParam(PARAM_GATE_ID, request.getGateId())
+ .setParam(PARAM_PROJECT_ID, request.getProjectId())
+ .setParam(PARAM_PROJECT_KEY, request.getProjectKey()));
+ }
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/SelectWsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/SelectWsRequest.java
new file mode 100644
index 00000000000..a3dc530f7b7
--- /dev/null
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/SelectWsRequest.java
@@ -0,0 +1,57 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonarqube.ws.client.qualitygate;
+
+import javax.annotation.CheckForNull;
+
+public class SelectWsRequest {
+ private long gateId;
+ private Long projectId;
+ private String projectKey;
+
+ public long getGateId() {
+ return gateId;
+ }
+
+ public SelectWsRequest setGateId(long gateId) {
+ this.gateId = gateId;
+ return this;
+ }
+
+ @CheckForNull
+ public Long getProjectId() {
+ return projectId;
+ }
+
+ public SelectWsRequest setProjectId(Long projectId) {
+ this.projectId = projectId;
+ return this;
+ }
+
+ @CheckForNull
+ public String getProjectKey() {
+ return projectKey;
+ }
+
+ public SelectWsRequest setProjectKey(String projectKey) {
+ this.projectKey = projectKey;
+ return this;
+ }
+}
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/qualitygate/QualityGatesServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/qualitygate/QualityGatesServiceTest.java
new file mode 100644
index 00000000000..3000be63863
--- /dev/null
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/qualitygate/QualityGatesServiceTest.java
@@ -0,0 +1,63 @@
+
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonarqube.ws.client.qualitygate;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.ws.client.PostRequest;
+import org.sonarqube.ws.client.ServiceTester;
+import org.sonarqube.ws.client.WsConnector;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_GATE_ID;
+
+public class QualityGatesServiceTest {
+ private static final Long PROJECT_ID_VALUE = 195L;
+ private static final String PROJECT_KEY_VALUE = "project_key_value";
+ private static final Long GATE_ID_VALUE = 243L;
+
+ @Rule
+ public ServiceTester<QualityGatesService> serviceTester = new ServiceTester<>(new QualityGatesService(mock(WsConnector.class)));
+
+ private QualityGatesService underTest = serviceTester.getInstanceUnderTest();
+
+ @Test
+ public void associate_project_does_POST_request() {
+ underTest.associateProject(new SelectWsRequest()
+ .setGateId(GATE_ID_VALUE)
+ .setProjectId(PROJECT_ID_VALUE)
+ .setProjectKey(PROJECT_KEY_VALUE));
+
+ assertThat(serviceTester.getPostParser()).isNull();
+
+ PostRequest postRequest = serviceTester.getPostRequest();
+
+ serviceTester.assertThat(postRequest)
+ .hasPath("select")
+ .hasParam(PARAM_GATE_ID, String.valueOf(GATE_ID_VALUE))
+ .hasParam(PARAM_PROJECT_ID, String.valueOf(PROJECT_ID_VALUE))
+ .hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
+ .andNoOtherParam();
+ }
+}