diff options
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(); + } +} |