From 456e3c985dd3d0fa07c4c0ec4b56bb8e7a508ee4 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 7 Dec 2017 09:26:50 +0100 Subject: [PATCH] SONAR-9962 api/qualitygates/destroy fail on default quality gate --- .../server/qualitygate/QualityGateFinder.java | 1 + .../server/qualitygate/ws/DestroyAction.java | 5 ++ .../qualitygate/ws/DestroyActionTest.java | 59 ++++++++++--------- .../ProjectQualityGatePageTest.java | 59 ++++++++----------- 4 files changed, 60 insertions(+), 64 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 8f3d75bb5b9..6a914c6cc14 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 @@ -72,6 +72,7 @@ public class QualityGateFinder { "No quality gate has been found for id %s in organization %s", qualityGateId, organization.getName()); } + // TODO As there is always a default quality gate, this method should not return an optional public Optional getDefault(DbSession dbSession) { Optional defaultQualityGateId = getDefaultId(dbSession); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java index c90a1ba85ba..1f5f70a3467 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java @@ -19,6 +19,7 @@ */ package org.sonar.server.qualitygate.ws; +import java.util.Optional; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -27,6 +28,8 @@ import org.sonar.db.DbSession; import org.sonar.db.qualitygate.QualityGateDto; import org.sonar.server.qualitygate.QualityGateFinder; +import static com.google.common.base.Preconditions.checkArgument; + public class DestroyAction implements QualityGatesWsAction { private final DbClient dbClient; @@ -60,6 +63,8 @@ public class DestroyAction implements QualityGatesWsAction { try (DbSession dbSession = dbClient.openSession(false)) { QualityGateDto qualityGate = finder.getById(dbSession, qualityGateId); + Optional defaultQualityGate = finder.getDefault(dbSession); + checkArgument(!defaultQualityGate.isPresent() || !defaultQualityGate.get().getId().equals(qualityGate.getId()), "The default quality gate cannot be removed"); wsSupport.checkCanEdit(qualityGate); dbClient.qualityGateDao().delete(qualityGate, dbSession); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/DestroyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/DestroyActionTest.java index d4e01ff13f1..7579f39d0af 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/DestroyActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/DestroyActionTest.java @@ -88,75 +88,76 @@ public class DestroyActionTest { } @Test - public void fail_when_invalid_id() { + public void delete_quality_gate_if_non_default_when_a_default_exist() { userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization()); + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("To Delete")); + Long toDeleteQualityGateId = qualityGate.getId(); + assertThat(db.getDbClient().qualityGateDao().selectById(dbSession, toDeleteQualityGateId)).isNotNull(); - String invalidId = "invalid-id"; - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage(format("The 'id' parameter cannot be parsed as a long value: %s", invalidId)); + QualityGateDto defaultQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("Default")); + db.qualityGates().setDefaultQualityGate(defaultQualityGate); ws.newRequest() - .setParam(PARAM_ID, valueOf(invalidId)) + .setParam(PARAM_ID, valueOf(toDeleteQualityGateId)) .execute(); + + assertThat(db.getDbClient().qualityGateDao().selectById(dbSession, toDeleteQualityGateId)).isNull(); } @Test - public void should_fail_when_missing_id() { + public void does_not_delete_built_in_quality_gate() { userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization()); + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(qg -> qg.setBuiltIn(true)); + Long qualityGateId = qualityGate.getId(); expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(format("Operation forbidden for built-in Quality Gate '%s'", qualityGate.getName())); ws.newRequest() - .setParam(PARAM_ID, valueOf(EMPTY)) + .setParam(PARAM_ID, valueOf(qualityGateId)) .execute(); + + assertThat(db.getDbClient().qualityGateDao().selectById(dbSession, qualityGateId)).isNotNull(); } @Test - public void delete_quality_gate_even_if_default() { + public void fail_when_invalid_id() { userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization()); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("To Delete")); - db.qualityGates().setDefaultQualityGate(qualityGate); - Long qualityGateId = qualityGate.getId(); + + String invalidId = "invalid-id"; + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(format("The 'id' parameter cannot be parsed as a long value: %s", invalidId)); ws.newRequest() - .setParam(PARAM_ID, valueOf(qualityGateId)) + .setParam(PARAM_ID, valueOf(invalidId)) .execute(); - - assertThat(db.getDbClient().qualityGateDao().selectById(dbSession, qualityGateId)).isNull(); } @Test - public void delete_quality_gate_if_non_default_when_a_default_exist() { + public void fail_when_missing_id() { userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization()); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("To Delete")); - Long toDeleteQualityGateId = qualityGate.getId(); - assertThat(db.getDbClient().qualityGateDao().selectById(dbSession, toDeleteQualityGateId)).isNotNull(); - QualityGateDto defaultQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("Default")); - db.qualityGates().setDefaultQualityGate(defaultQualityGate); + expectedException.expect(IllegalArgumentException.class); ws.newRequest() - .setParam(PARAM_ID, valueOf(toDeleteQualityGateId)) + .setParam(PARAM_ID, valueOf(EMPTY)) .execute(); - - assertThat(db.getDbClient().qualityGateDao().selectById(dbSession, toDeleteQualityGateId)).isNull(); } @Test - public void does_not_delete_built_in_quality_gate() { + public void fail_to_delete_default_quality_gate() { userSession.addPermission(ADMINISTER_QUALITY_GATES, db.getDefaultOrganization()); - QualityGateDto qualityGate = db.qualityGates().insertQualityGate(qg -> qg.setBuiltIn(true)); + QualityGateDto qualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("To Delete")); + db.qualityGates().setDefaultQualityGate(qualityGate); Long qualityGateId = qualityGate.getId(); expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage(format("Operation forbidden for built-in Quality Gate '%s'", qualityGate.getName())); + expectedException.expectMessage("The default quality gate cannot be removed"); ws.newRequest() .setParam(PARAM_ID, valueOf(qualityGateId)) .execute(); - - assertThat(db.getDbClient().qualityGateDao().selectById(dbSession, qualityGateId)).isNotNull(); } @Test diff --git a/tests/src/test/java/org/sonarqube/tests/qualityGate/ProjectQualityGatePageTest.java b/tests/src/test/java/org/sonarqube/tests/qualityGate/ProjectQualityGatePageTest.java index 779c59e0652..2d2acea2359 100644 --- a/tests/src/test/java/org/sonarqube/tests/qualityGate/ProjectQualityGatePageTest.java +++ b/tests/src/test/java/org/sonarqube/tests/qualityGate/ProjectQualityGatePageTest.java @@ -32,6 +32,7 @@ import org.sonar.wsclient.qualitygate.QualityGateClient; import org.sonarqube.qa.util.Tester; import org.sonarqube.qa.util.pageobjects.Navigation; import org.sonarqube.qa.util.pageobjects.ProjectQualityGatePage; +import org.sonarqube.ws.Qualitygates; import org.sonarqube.ws.client.PostRequest; import org.sonarqube.ws.client.qualitygates.SelectRequest; @@ -64,56 +65,48 @@ public class ProjectQualityGatePageTest { @Test public void should_display_default() { - QualityGate customQualityGate = createCustomQualityGate("should_display_default"); - qualityGateClient().setDefault(customQualityGate.id()); - - try { - ProjectQualityGatePage page = openPage(); - SelenideElement selectedQualityGate = page.getSelectedQualityGate(); - selectedQualityGate.should(Condition.text("Default")); - selectedQualityGate.should(Condition.text(customQualityGate.name())); - } finally { - qualityGateClient().destroy(customQualityGate.id()); - } + Qualitygates.CreateResponse customQualityGate = tester.qGates().generate(); + qualityGateClient().setDefault(customQualityGate.getId()); + + ProjectQualityGatePage page = openPage(); + SelenideElement selectedQualityGate = page.getSelectedQualityGate(); + selectedQualityGate.should(Condition.text("Default")); + selectedQualityGate.should(Condition.text(customQualityGate.getName())); } @Test public void should_display_custom() { - QualityGate customQualityGate = createCustomQualityGate("should_display_custom"); + Qualitygates.CreateResponse customQualityGate = tester.qGates().generate(); associateWithQualityGate(customQualityGate); ProjectQualityGatePage page = openPage(); SelenideElement selectedQualityGate = page.getSelectedQualityGate(); selectedQualityGate.shouldNot(Condition.text("Default")); - selectedQualityGate.should(Condition.text(customQualityGate.name())); + selectedQualityGate.should(Condition.text(customQualityGate.getName())); } @Test public void should_set_custom() { - QualityGate customQualityGate = createCustomQualityGate("should_set_custom"); + Qualitygates.CreateResponse customQualityGate = tester.qGates().generate(); ProjectQualityGatePage page = openPage(); - page.setQualityGate(customQualityGate.name()); + page.setQualityGate(customQualityGate.getName()); SelenideElement selectedQualityGate = page.getSelectedQualityGate(); - selectedQualityGate.should(Condition.text(customQualityGate.name())); + selectedQualityGate.should(Condition.text(customQualityGate.getName())); } @Test public void should_set_default() { - QualityGate customQualityGate = createCustomQualityGate("should_set_default"); - qualityGateClient().setDefault(customQualityGate.id()); - - try { - ProjectQualityGatePage page = openPage(); - page.setQualityGate(customQualityGate.name()); - - SelenideElement selectedQualityGate = page.getSelectedQualityGate(); - selectedQualityGate.should(Condition.text("Default")); - selectedQualityGate.should(Condition.text(customQualityGate.name())); - } finally { - qualityGateClient().destroy(customQualityGate.id()); - } + Qualitygates.CreateResponse customQualityGate = tester.qGates().generate(); + qualityGateClient().setDefault(customQualityGate.getId()); + + ProjectQualityGatePage page = openPage(); + page.setQualityGate(customQualityGate.getName()); + + SelenideElement selectedQualityGate = page.getSelectedQualityGate(); + selectedQualityGate.should(Condition.text("Default")); + selectedQualityGate.should(Condition.text(customQualityGate.getName())); } private ProjectQualityGatePage openPage() { @@ -122,12 +115,8 @@ public class ProjectQualityGatePageTest { return navigation.openProjectQualityGate("sample"); } - private QualityGate createCustomQualityGate(String name) { - return qualityGateClient().create(name); - } - - private void associateWithQualityGate(QualityGate qualityGate) { - tester.wsClient().qualitygates().select(new SelectRequest().setProjectKey("sample").setGateId(String.valueOf(qualityGate.id()))); + private void associateWithQualityGate(Qualitygates.CreateResponse qualityGate) { + tester.wsClient().qualitygates().select(new SelectRequest().setProjectKey("sample").setGateId(String.valueOf(qualityGate.getId()))); } private QualityGateClient qualityGateClient() { -- 2.39.5