From e2d2765f41bfa4bea1d0f19e754acd0c70cf2d36 Mon Sep 17 00:00:00 2001 From: Guillaume Jambet Date: Tue, 5 Dec 2017 16:27:27 +0100 Subject: [PATCH] SONAR-10134 Bringing Organization to Copy Action --- .../server/qualitygate/QualityGateFinder.java | 3 +- .../qualitygate/QualityGateUpdater.java | 55 ++----- .../server/qualitygate/ws/CopyAction.java | 38 ++--- .../server/qualitygate/ws/CreateAction.java | 6 +- .../qualitygate/QualityGateUpdaterTest.java | 15 +- .../server/qualitygate/ws/CopyActionTest.java | 147 +++++++++++++++--- .../qualitygate/ws/CreateActionTest.java | 74 ++++++--- 7 files changed, 218 insertions(+), 120 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java index 23cceab3186..8f3d75bb5b9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateFinder.java @@ -68,7 +68,8 @@ public class QualityGateFinder { } public QGateWithOrgDto getByOrganizationAndId(DbSession dbSession, OrganizationDto organization, long qualityGateId) { - return checkFound(dbClient.qualityGateDao().selectByOrganizationAndId(dbSession, organization, qualityGateId), "No quality gate has been found for id %s", qualityGateId); + return checkFound(dbClient.qualityGateDao().selectByOrganizationAndId(dbSession, organization, qualityGateId), + "No quality gate has been found for id %s in organization %s", qualityGateId, organization.getName()); } public Optional getDefault(DbSession dbSession) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateUpdater.java index 0ef74ade3b3..d4306095d56 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateUpdater.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateUpdater.java @@ -19,8 +19,6 @@ */ package org.sonar.server.qualitygate; -import java.util.ArrayList; -import java.util.List; import javax.annotation.Nullable; import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; @@ -29,13 +27,10 @@ import org.sonar.db.organization.OrganizationDto; import org.sonar.db.property.PropertyDto; import org.sonar.db.qualitygate.QualityGateConditionDto; import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.util.Validation; -import static com.google.common.base.Strings.isNullOrEmpty; -import static java.lang.String.format; +import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.server.util.Validation.IS_ALREADY_USED_MESSAGE; -import static org.sonar.server.ws.WsUtils.checkRequest; +import static org.sonar.server.ws.WsUtils.checkFound; public class QualityGateUpdater { @@ -50,7 +45,7 @@ public class QualityGateUpdater { } public QualityGateDto create(DbSession dbSession, OrganizationDto organizationDto, String name) { - validateQualityGateCreation(dbSession, organizationDto, name); + validateQualityGate(dbSession, organizationDto, name); QualityGateDto newQualityGate = new QualityGateDto() .setName(name) .setBuiltIn(false) @@ -60,61 +55,37 @@ public class QualityGateUpdater { return newQualityGate; } - public QualityGateDto copy(DbSession dbSession, QualityGateDto qualityGateDto, String destinationName) { + public QualityGateDto copy(DbSession dbSession, OrganizationDto organizationDto, QualityGateDto qualityGateDto, String destinationName) { - validateQualityGateUpdate(dbSession, qualityGateDto.getId(), destinationName); - - QualityGateDto destinationGate = new QualityGateDto().setName(destinationName).setBuiltIn(false).setUuid(uuidFactory.create()); - dbClient.qualityGateDao().insert(dbSession, destinationGate); + QualityGateDto destinationGate = create(dbSession, organizationDto, destinationName); for (QualityGateConditionDto sourceCondition : dbClient.gateConditionDao().selectForQualityGate(dbSession, qualityGateDto.getId())) { dbClient.gateConditionDao().insert(new QualityGateConditionDto().setQualityGateId(destinationGate.getId()) - .setMetricId(sourceCondition.getMetricId()).setOperator(sourceCondition.getOperator()) - .setWarningThreshold(sourceCondition.getWarningThreshold()).setErrorThreshold(sourceCondition.getErrorThreshold()).setPeriod(sourceCondition.getPeriod()), + .setMetricId(sourceCondition.getMetricId()).setOperator(sourceCondition.getOperator()) + .setWarningThreshold(sourceCondition.getWarningThreshold()).setErrorThreshold(sourceCondition.getErrorThreshold()).setPeriod(sourceCondition.getPeriod()), dbSession); } return destinationGate; } - private void validateQualityGateUpdate(DbSession dbSession, Long qualityGateId, String name) { - List errors = new ArrayList<>(); - checkQualityGateDoesNotAlreadyExist(dbSession, qualityGateId, name, errors); - checkRequest(errors.isEmpty(), errors); + private void validateQualityGate(DbSession dbSession, OrganizationDto organizationDto, String name) { + checkQualityGateDoesNotAlreadyExist(dbSession, organizationDto, name); } - public void setDefault(DbSession dbSession, @Nullable QualityGateDto qualityGateDto) { if (qualityGateDto == null) { dbClient.propertiesDao().deleteGlobalProperty(SONAR_QUALITYGATE_PROPERTY, dbSession); } else { - checkQualityGateExistence(dbSession, qualityGateDto.getId()); + long qualityGateId = qualityGateDto.getId(); + checkFound(dbClient.qualityGateDao().selectById(dbSession, qualityGateId), "There is no quality gate with id=" + qualityGateId); dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY).setValue(qualityGateDto.getId().toString())); } } - private void checkQualityGateExistence(DbSession dbSession, @Nullable Long qualityGateId) { - if (qualityGateId == null || - dbClient.qualityGateDao().selectById(dbSession, qualityGateId) == null) { - throw new NotFoundException("There is no quality gate with id=" + qualityGateId); - } - } - - private void validateQualityGateCreation(DbSession dbSession, OrganizationDto organizationDto, @Nullable String name) { - List errors = new ArrayList<>(); - if (isNullOrEmpty(name)) { - errors.add(format(Validation.CANT_BE_EMPTY_MESSAGE, "Name")); - } else { - checkQualityGateDoesNotAlreadyExist(dbSession, organizationDto, name, errors); - } - checkRequest(errors.isEmpty(), errors); - } - - private void checkQualityGateDoesNotAlreadyExist(DbSession dbSession, OrganizationDto organizationDto, String name, List errors) { + private void checkQualityGateDoesNotAlreadyExist(DbSession dbSession, OrganizationDto organizationDto, String name) { QualityGateDto existingQgate = dbClient.qualityGateDao().selectByOrganizationAndName(dbSession, organizationDto, name); - if (existingQgate != null) { - errors.add(format(IS_ALREADY_USED_MESSAGE, "Name")); - } + checkArgument(existingQgate == null, IS_ALREADY_USED_MESSAGE, "Name"); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java index d91e28783f4..0013a40b181 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java @@ -24,12 +24,13 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.qualitygate.QualityGateUpdater; import org.sonar.server.user.UserSession; +import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES; import static org.sonar.server.qualitygate.ws.QualityGatesWs.parseId; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ID; @@ -41,17 +42,17 @@ public class CopyAction implements QualityGatesWsAction { private final DbClient dbClient; private final UserSession userSession; - private final DefaultOrganizationProvider organizationProvider; private final QualityGateUpdater qualityGateUpdater; private final QualityGateFinder qualityGateFinder; + private final QualityGatesWsSupport wsSupport; - public CopyAction(DbClient dbClient, UserSession userSession, DefaultOrganizationProvider organizationProvider, - QualityGateUpdater qualityGateUpdater, QualityGateFinder qualityGateFinder) { + public CopyAction(DbClient dbClient, UserSession userSession, QualityGateUpdater qualityGateUpdater, + QualityGateFinder qualityGateFinder, QualityGatesWsSupport wsSupport) { this.dbClient = dbClient; this.userSession = userSession; - this.organizationProvider = organizationProvider; this.qualityGateUpdater = qualityGateUpdater; this.qualityGateFinder = qualityGateFinder; + this.wsSupport = wsSupport; } @Override @@ -72,6 +73,8 @@ public class CopyAction implements QualityGatesWsAction { .setDescription("The name of the quality gate to create") .setRequired(true) .setExampleValue("My Quality Gate"); + + wsSupport.createOrganizationParam(action); } @Override @@ -79,23 +82,20 @@ public class CopyAction implements QualityGatesWsAction { Long id = parseId(request, PARAM_ID); String destinationName = request.mandatoryParam(PARAM_NAME); - userSession.checkPermission(ADMINISTER_QUALITY_GATES, organizationProvider.get().getUuid()); - - QualityGateDto qualityGateDto = doCopy(id, destinationName); - - writeProtobuf(newBuilder() - .setId(qualityGateDto.getId()) - .setName(qualityGateDto.getName()) - .build(), request, response); - } + checkArgument(!destinationName.isEmpty(), "The 'name' parameter is empty"); - private QualityGateDto doCopy(Long id, String destinationName) { try (DbSession dbSession = dbClient.openSession(false)) { - QualityGateDto qualityGateDto = qualityGateFinder.getById(dbSession, id); - QualityGateDto result = qualityGateUpdater.copy(dbSession, qualityGateDto, destinationName); + + OrganizationDto organization = wsSupport.getOrganization(dbSession, request); + userSession.checkPermission(ADMINISTER_QUALITY_GATES, organization); + QualityGateDto qualityGate = qualityGateFinder.getByOrganizationAndId(dbSession, organization, id); + QualityGateDto copy = qualityGateUpdater.copy(dbSession, organization, qualityGate, destinationName); dbSession.commit(); - return result; + + writeProtobuf(newBuilder() + .setId(copy.getId()) + .setName(copy.getName()) + .build(), request, response); } } - } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java index 5500aff1084..c8e9b8dd2b7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java @@ -31,6 +31,7 @@ import org.sonar.server.qualitygate.QualityGateUpdater; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Qualitygates.CreateResponse; +import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_CREATE; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_NAME; import static org.sonar.server.ws.WsUtils.writeProtobuf; @@ -78,7 +79,10 @@ public class CreateAction implements QualityGatesWsAction { userSession.checkPermission(OrganizationPermission.ADMINISTER_QUALITY_GATES, organizationDto.getUuid()); - QualityGateDto newQualityGate = qualityGateUpdater.create(dbSession, organizationDto, request.mandatoryParam(PARAM_NAME)); + String name = request.mandatoryParam(PARAM_NAME); + checkArgument(!name.isEmpty(), "The 'name' parameter is empty"); + + QualityGateDto newQualityGate = qualityGateUpdater.create(dbSession, organizationDto, name); CreateResponse.Builder createResponse = CreateResponse.newBuilder() .setId(newQualityGate.getId()) .setName(newQualityGate.getName()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java index 3bc6535c6de..4da4e3ad16e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java @@ -19,6 +19,8 @@ */ package org.sonar.server.qualitygate; +import static org.assertj.core.api.Assertions.assertThat; + import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -29,9 +31,6 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.exceptions.BadRequestException; - -import static org.assertj.core.api.Assertions.assertThat; public class QualityGateUpdaterTest { @@ -61,20 +60,12 @@ public class QualityGateUpdaterTest { assertThat(reloaded).isNotNull(); } - @Test - public void fail_to_create_when_name_is_empty() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Name can't be empty"); - - underTest.create(dbSession, db.organizations().insert(), ""); - } - @Test public void fail_to_create_when_name_already_exists() { OrganizationDto org = db.organizations().insert(); underTest.create(dbSession, org, QGATE_NAME); - expectedException.expect(BadRequestException.class); + expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Name has already been taken"); underTest.create(dbSession, org, QGATE_NAME); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CopyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CopyActionTest.java index 1a8d8c1158c..1e3d33ae893 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CopyActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CopyActionTest.java @@ -29,9 +29,10 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.metric.MetricDto; +import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.qualitygate.QGateWithOrgDto; import org.sonar.db.qualitygate.QualityGateConditionDto; import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.TestDefaultOrganizationProvider; @@ -41,12 +42,14 @@ import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Qualitygates.QualityGate; +import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.tuple; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ID; import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_NAME; +import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ORGANIZATION; public class CopyActionTest { @@ -64,8 +67,9 @@ public class CopyActionTest { private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); private QualityGateUpdater qualityGateUpdater = new QualityGateUpdater(dbClient, UuidFactoryFast.getInstance()); private QualityGateFinder qualityGateFinder = new QualityGateFinder(dbClient); + private QualityGatesWsSupport wsSupport = new QualityGatesWsSupport(dbClient, userSession, defaultOrganizationProvider); - private CopyAction underTest = new CopyAction(dbClient, userSession, defaultOrganizationProvider, qualityGateUpdater, qualityGateFinder); + private CopyAction underTest = new CopyAction(dbClient, userSession, qualityGateUpdater, qualityGateFinder, wsSupport); private WsActionTester ws = new WsActionTester(underTest); @Test @@ -80,22 +84,27 @@ public class CopyActionTest { .extracting(WebService.Param::key, WebService.Param::isRequired) .containsExactlyInAnyOrder( tuple("id", true), + tuple("organization", false), tuple("name", true)); } @Test public void copy() { - userSession.addPermission(ADMINISTER_QUALITY_GATES, defaultOrganizationProvider.get().getUuid()); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); + + OrganizationDto organization = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, organization); + + QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); MetricDto metric = db.measures().insertMetric(); QualityGateConditionDto condition = db.qualityGates().addCondition(qualityGate, metric); ws.newRequest() .setParam(PARAM_ID, qualityGate.getId().toString()) .setParam(PARAM_NAME, "new-name") + .setParam(PARAM_ORGANIZATION, organization.getKey()) .execute(); - QualityGateDto actual = db.getDbClient().qualityGateDao().selectByName(dbSession, "new-name"); + QGateWithOrgDto actual = db.getDbClient().qualityGateDao().selectByOrganizationAndName(dbSession, organization, "new-name"); assertThat(actual).isNotNull(); assertThat(actual.isBuiltIn()).isFalse(); assertThat(actual.getId()).isNotEqualTo(qualityGate.getId()); @@ -107,29 +116,35 @@ public class CopyActionTest { } @Test - public void fail_when_missing_administer_quality_gate_permission() { - userSession.addPermission(ADMINISTER_QUALITY_PROFILES, defaultOrganizationProvider.get().getUuid()); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); - - expectedException.expect(ForbiddenException.class); + public void default_organization_is_used_when_no_organization_parameter(){ + OrganizationDto defaultOrganization = db.getDefaultOrganization(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, defaultOrganization); + QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(defaultOrganization); ws.newRequest() .setParam(PARAM_ID, qualityGate.getId().toString()) .setParam(PARAM_NAME, "new-name") .execute(); + + QGateWithOrgDto actual = db.getDbClient().qualityGateDao().selectByOrganizationAndName(dbSession, defaultOrganization, "new-name"); + assertThat(actual).isNotNull(); + assertThat(actual.getOrganizationUuid()).isEqualTo(defaultOrganization.getUuid()); } @Test public void copy_of_builtin_should_not_be_builtin() { - userSession.addPermission(ADMINISTER_QUALITY_GATES, defaultOrganizationProvider.get().getUuid()); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(qualityGateDto -> qualityGateDto.setBuiltIn(true)); + OrganizationDto organization = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, organization); + QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization, qualityGateDto -> qualityGateDto.setBuiltIn(true)); ws.newRequest() .setParam(PARAM_ID, qualityGate.getId().toString()) .setParam(PARAM_NAME, "new-name") + .setParam(PARAM_ORGANIZATION, organization.getKey()) .execute(); QualityGateDto actual = db.getDbClient().qualityGateDao().selectByName(dbSession, "new-name"); + assertThat(actual).isNotNull(); assertThat(actual.isBuiltIn()).isFalse(); } @@ -138,65 +153,147 @@ public class CopyActionTest { userSession.addPermission(ADMINISTER_QUALITY_GATES, defaultOrganizationProvider.get().getUuid()); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); - QualityGate result = ws.newRequest() + QualityGate response = ws.newRequest() .setParam(PARAM_ID, qualityGate.getId().toString()) .setParam(PARAM_NAME, "new-name") .executeProtobuf(QualityGate.class); - assertThat(result.getId()).isNotEqualTo(qualityGate.getId()); - assertThat(result.getName()).isEqualTo("new-name"); + assertThat(response).isNotNull(); + assertThat(response.getId()).isNotEqualTo(qualityGate.getId()); + assertThat(response.getName()).isEqualTo("new-name"); + } + + @Test + public void quality_gates_can_have_the_same_name_in_different_organization() { + OrganizationDto organization1 = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, organization1); + QualityGateDto qualityGate1 = db.qualityGates().insertQualityGate(organization1); + + OrganizationDto organization2 = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, organization2); + QualityGateDto qualityGate2 = db.qualityGates().insertQualityGate(organization2); + + assertThat(qualityGate1.getName()).isNotEqualTo(qualityGate2.getName()); + + ws.newRequest() + .setParam(PARAM_ORGANIZATION, organization2.getKey()) + .setParam(PARAM_ID, qualityGate2.getId().toString()) + .setParam(PARAM_NAME, qualityGate1.getName()) + .execute(); + + QGateWithOrgDto actual = db.getDbClient().qualityGateDao().selectByOrganizationAndName(dbSession, organization2, qualityGate1.getName()); + assertThat(actual).isNotNull(); + } + + @Test + public void quality_gate_from_external_organization_can_not_be_copied(){ + OrganizationDto organization1 = db.organizations().insert(); + QualityGateDto qualityGate1 = db.qualityGates().insertQualityGate(organization1); + + OrganizationDto organization2 = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, organization2); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage(format("No quality gate has been found for id %s in organization %s", qualityGate1.getId(), organization2.getName())); + + ws.newRequest() + .setParam(PARAM_ORGANIZATION, organization2.getKey()) + .setParam(PARAM_ID, qualityGate1.getId().toString()) + .setParam(PARAM_NAME, "new-name") + .execute(); + } + + @Test + public void fail_when_missing_administer_quality_gate_permission() { + OrganizationDto organization = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_PROFILES, organization); + + QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); + + expectedException.expect(ForbiddenException.class); + + ws.newRequest() + .setParam(PARAM_ID, qualityGate.getId().toString()) + .setParam(PARAM_NAME, "new-name") + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); } @Test public void fail_when_id_parameter_is_missing() { - userSession.addPermission(ADMINISTER_QUALITY_GATES, defaultOrganizationProvider.get().getUuid()); + OrganizationDto organization = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, organization); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("The 'id' parameter is missing"); ws.newRequest() .setParam(PARAM_NAME, "new-name") + .setParam(PARAM_ORGANIZATION, organization.getKey()) .execute(); } @Test public void fail_when_quality_gate_id_is_not_found() { - userSession.addPermission(ADMINISTER_QUALITY_GATES, defaultOrganizationProvider.get().getUuid()); + OrganizationDto organization = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, organization); expectedException.expect(NotFoundException.class); - expectedException.expectMessage("No quality gate has been found for id 123"); + expectedException.expectMessage(format( + "No quality gate has been found for id 123 in organization %s", organization.getName())); ws.newRequest() .setParam(PARAM_ID, "123") .setParam(PARAM_NAME, "new-name") + .setParam(PARAM_ORGANIZATION, organization.getKey()) .execute(); } @Test public void fail_when_name_parameter_is_missing() { - userSession.addPermission(ADMINISTER_QUALITY_GATES, defaultOrganizationProvider.get().getUuid()); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); + OrganizationDto organization = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, organization); + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(organization); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("The 'name' parameter is missing"); ws.newRequest() .setParam(PARAM_ID, qualityGate.getId().toString()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) .execute(); } @Test - public void fail_when_name_parameter_match_existing_quality_gate() { - userSession.addPermission(ADMINISTER_QUALITY_GATES, defaultOrganizationProvider.get().getUuid()); - QualityGateDto existingQualityGate = db.qualityGates().insertQualityGate(); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(); + public void fail_when_name_parameter_is_empty() { + OrganizationDto organization = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, organization); + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(organization); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("The 'name' parameter is empty"); - expectedException.expect(BadRequestException.class); + ws.newRequest() + .setParam(PARAM_ID, qualityGate.getId().toString()) + .setParam(PARAM_NAME, "") + .setParam(PARAM_ORGANIZATION, organization.getKey()) + .execute(); + } + + @Test + public void fail_when_name_parameter_match_existing_quality_gate_in_the_same_organization() { + OrganizationDto organization = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, organization); + QualityGateDto existingQualityGate = db.qualityGates().insertQualityGate(organization); + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(organization); + + expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Name has already been taken"); ws.newRequest() .setParam(PARAM_ID, qualityGate.getId().toString()) .setParam(PARAM_NAME, existingQualityGate.getName()) + .setParam(PARAM_ORGANIZATION, organization.getKey()) .execute(); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateActionTest.java index d9e3543fdf7..dee256e48a4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateActionTest.java @@ -19,7 +19,13 @@ */ package org.sonar.server.qualitygate.ws; +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES; +import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_NAME; +import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ORGANIZATION; + import java.util.Optional; + import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -31,8 +37,8 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.organization.OrganizationDbTester; import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.qualitygate.QGateWithOrgDto; import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.organization.TestDefaultOrganizationProvider; @@ -41,9 +47,6 @@ import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; import org.sonarqube.ws.Qualitygates.CreateResponse; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES; - public class CreateActionTest { @Rule @@ -94,6 +97,33 @@ public class CreateActionTest { assertThat(qualityGateDto).isNotNull(); } + @Test + public void creating_a_qg_with_a_name_used_in_another_organization_should_work() { + OrganizationDto anOrganization = db.organizations().insert(); + QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(anOrganization); + OrganizationDto anotherOrganization = db.organizations().insert(); + + userSession.addPermission(ADMINISTER_QUALITY_GATES, anotherOrganization); + + CreateResponse response = ws.newRequest() + .setParam(PARAM_NAME, qualityGate.getName()) + .setParam(PARAM_ORGANIZATION, anotherOrganization.getKey()) + .executeProtobuf(CreateResponse.class); + + assertThat(response.getName()).isEqualTo(qualityGate.getName()); + assertThat(response.getId()).isNotEqualTo(qualityGate.getId()); + } + + @Test + public void test_ws_definition() { + WebService.Action action = ws.getDef(); + assertThat(action).isNotNull(); + assertThat(action.isInternal()).isFalse(); + assertThat(action.isPost()).isTrue(); + assertThat(action.responseExampleAsString()).isNotEmpty(); + assertThat(action.params()).hasSize(2); + } + @Test public void throw_ForbiddenException_if_incorrect_organization() { logInAsQualityGateAdmin(db.getDefaultOrganization()); @@ -147,33 +177,37 @@ public class CreateActionTest { executeRequest(Optional.of(org), "Default"); - expectedException.expect(BadRequestException.class); + expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Name has already been taken"); executeRequest(Optional.of(org), "Default"); } @Test - public void creating_a_qg_with_a_name_used_in_another_organization_should_work() { - OrganizationDto org1 = db.organizations().insert(); - OrganizationDto org2 = db.organizations().insert(); + public void fail_when_name_parameter_is_empty() { + OrganizationDto org = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, org); - userSession.logIn() - .addPermission(ADMINISTER_QUALITY_GATES, org1) - .addPermission(ADMINISTER_QUALITY_GATES, org2); + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("The 'name' parameter is empty"); - executeRequest(Optional.of(org1), "Default"); - executeRequest(Optional.of(org2), "Default"); + ws.newRequest() + .setParam(PARAM_NAME, "") + .setParam(PARAM_ORGANIZATION, org.getKey()) + .execute(); } @Test - public void test_ws_definition() { - WebService.Action action = ws.getDef(); - assertThat(action).isNotNull(); - assertThat(action.isInternal()).isFalse(); - assertThat(action.isPost()).isTrue(); - assertThat(action.responseExampleAsString()).isNotEmpty(); - assertThat(action.params()).hasSize(2); + public void fail_when_name_parameter_is_missing() { + OrganizationDto org = db.organizations().insert(); + userSession.addPermission(ADMINISTER_QUALITY_GATES, org); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("The 'name' parameter is missing"); + + ws.newRequest() + .setParam(PARAM_ORGANIZATION, org.getKey()) + .execute(); } private CreateResponse executeRequest(Optional organization, String qualitGateName) { -- 2.39.5