From 181b908e2cc754e05255059c3a581d48c173cf3c Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Wed, 19 Feb 2014 18:40:51 +0100 Subject: [PATCH] SONAR-4366 Add remaining CRUD Web Services for quality gates --- .../core/qualitygate/db/QualityGateDao.java | 58 ++++++-- .../qualitygate/db/QualityGateMapper.java | 6 + .../core/qualitygate/db/QualityGateMapper.xml | 14 ++ .../qualitygate/db/QualityGateDaoTest.java | 22 +++ .../db/QualityGateDaoTest/delete-result.xml | 6 + .../db/QualityGateDaoTest/update-result.xml | 7 + .../server/qualitygate/QualityGates.java | 70 ++++++++- .../server/qualitygate/ws/QualityGatesWs.java | 85 ++++++++++- .../server/qualitygate/QualityGatesTest.java | 120 +++++++++++++++- .../qualitygate/ws/QualityGatesWsTest.java | 134 +++++++++++++++++- 10 files changed, 498 insertions(+), 24 deletions(-) create mode 100644 sonar-core/src/test/resources/org/sonar/core/qualitygate/db/QualityGateDaoTest/delete-result.xml create mode 100644 sonar-core/src/test/resources/org/sonar/core/qualitygate/db/QualityGateDaoTest/update-result.xml diff --git a/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateDao.java b/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateDao.java index c618343d15a..d3eaee3fd7f 100644 --- a/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateDao.java +++ b/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateDao.java @@ -19,13 +19,11 @@ */ package org.sonar.core.qualitygate.db; -import org.sonar.core.rule.RuleDto; +import org.apache.ibatis.session.SqlSession; +import org.sonar.core.persistence.MyBatis; import java.util.Collection; -import org.sonar.core.persistence.MyBatis; -import org.apache.ibatis.session.SqlSession; - /** * @since 4.3 */ @@ -64,10 +62,6 @@ public class QualityGateDao { return getMapper(session).selectAll(); } - private QualityGateMapper getMapper(SqlSession session) { - return session.getMapper(QualityGateMapper.class); - } - public QualityGateDto selectByName(String name) { SqlSession session = myBatis.openSession(); try { @@ -77,8 +71,52 @@ public class QualityGateDao { } } - private QualityGateDto selectByName(String name, SqlSession session) { + public QualityGateDto selectByName(String name, SqlSession session) { return getMapper(session).selectByName(name); } - + + public QualityGateDto selectById(long id) { + SqlSession session = myBatis.openSession(); + try { + return selectById(id, session); + } finally { + MyBatis.closeQuietly(session); + } + } + + public QualityGateDto selectById(long id, SqlSession session) { + return getMapper(session).selectById(id); + } + + public void delete(QualityGateDto qGate) { + SqlSession session = myBatis.openSession(); + try { + delete(qGate, session); + session.commit(); + } finally { + MyBatis.closeQuietly(session); + } + } + + public void delete(QualityGateDto qGate, SqlSession session) { + getMapper(session).delete(qGate.getId()); + } + + public void update(QualityGateDto qGate) { + SqlSession session = myBatis.openSession(); + try { + update(qGate, session); + session.commit(); + } finally { + MyBatis.closeQuietly(session); + } + } + + public void update(QualityGateDto qGate, SqlSession session) { + getMapper(session).update(qGate); + } + + private QualityGateMapper getMapper(SqlSession session) { + return session.getMapper(QualityGateMapper.class); + } } diff --git a/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateMapper.java b/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateMapper.java index 40931ecabaa..d44ba8dc812 100644 --- a/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateMapper.java @@ -28,4 +28,10 @@ public interface QualityGateMapper { List selectAll(); QualityGateDto selectByName(String name); + + QualityGateDto selectById(long id); + + void delete(long id); + + void update(QualityGateDto qGate); } diff --git a/sonar-core/src/main/resources/org/sonar/core/qualitygate/db/QualityGateMapper.xml b/sonar-core/src/main/resources/org/sonar/core/qualitygate/db/QualityGateMapper.xml index ab399d24dd3..43a368a2ac3 100644 --- a/sonar-core/src/main/resources/org/sonar/core/qualitygate/db/QualityGateMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/qualitygate/db/QualityGateMapper.xml @@ -21,5 +21,19 @@ select from quality_gates where name=#{name} + + + + + delete from quality_gates where id=#{id} + + + + update quality_gates set name=#{name} where id=#{id} + + diff --git a/sonar-core/src/test/java/org/sonar/core/qualitygate/db/QualityGateDaoTest.java b/sonar-core/src/test/java/org/sonar/core/qualitygate/db/QualityGateDaoTest.java index 0a72f182707..78bc4cbfa7a 100644 --- a/sonar-core/src/test/java/org/sonar/core/qualitygate/db/QualityGateDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/qualitygate/db/QualityGateDaoTest.java @@ -62,4 +62,26 @@ public class QualityGateDaoTest extends AbstractDaoTestCase { assertThat(dao.selectByName("Balanced").getName()).isEqualTo("Balanced"); assertThat(dao.selectByName("Unknown")).isNull(); } + + @Test + public void testSelectById() throws Exception { + setupData("selectAll"); + assertThat(dao.selectById(1L).getName()).isEqualTo("Very strict"); + assertThat(dao.selectById(42L)).isNull(); + } + + @Test + public void testDelete() throws Exception { + setupData("selectAll"); + dao.delete(new QualityGateDto().setId(1L)); + checkTable("delete", "quality_gates"); + } + + @Test + public void testUpdate() throws Exception { + setupData("selectAll"); + dao.update(new QualityGateDto().setId(1L).setName("Not so strict")); + checkTable("update", "quality_gates"); + } + } diff --git a/sonar-core/src/test/resources/org/sonar/core/qualitygate/db/QualityGateDaoTest/delete-result.xml b/sonar-core/src/test/resources/org/sonar/core/qualitygate/db/QualityGateDaoTest/delete-result.xml new file mode 100644 index 00000000000..af95b43928b --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/qualitygate/db/QualityGateDaoTest/delete-result.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/sonar-core/src/test/resources/org/sonar/core/qualitygate/db/QualityGateDaoTest/update-result.xml b/sonar-core/src/test/resources/org/sonar/core/qualitygate/db/QualityGateDaoTest/update-result.xml new file mode 100644 index 00000000000..ea83459b139 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/qualitygate/db/QualityGateDaoTest/update-result.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java index 7f231be6424..80ad46b1f02 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java @@ -19,6 +19,10 @@ */ package org.sonar.server.qualitygate; +import org.apache.commons.lang.StringUtils; +import org.sonar.core.properties.PropertyDto; +import org.sonar.core.properties.PropertiesDao; +import org.sonar.server.exceptions.NotFoundException; import com.google.common.base.Strings; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.qualitygate.db.QualityGateDao; @@ -27,6 +31,7 @@ import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.user.UserSession; import org.sonar.server.util.Validation; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import java.util.Collection; @@ -40,10 +45,15 @@ import static com.google.common.collect.Lists.newArrayList; */ public class QualityGates { + public static final String SONAR_QUALITYGATE_PROPERTY = "sonar.qualitygate"; + private final QualityGateDao dao; - public QualityGates(QualityGateDao dao) { + private final PropertiesDao propertiesDao; + + public QualityGates(QualityGateDao dao, PropertiesDao propertiesDao) { this.dao = dao; + this.propertiesDao = propertiesDao; } public QualityGateDto create(String name) { @@ -54,10 +64,68 @@ public class QualityGates { return newQualityGate; } + public QualityGateDto rename(long idToRename, String name) { + checkPermission(UserSession.get()); + QualityGateDto toRename = getNonNull(idToRename); + validateQualityGate(idToRename, name); + toRename.setName(name); + dao.update(toRename); + return toRename; + } + public Collection list() { return dao.selectAll(); } + public void delete(long idToDelete) { + checkPermission(UserSession.get()); + QualityGateDto qGate = getNonNull(idToDelete); + if (isDefault(qGate)) { + throw new BadRequestException("Impossible to delete default quality gate."); + } + dao.delete(qGate); + } + + public void setDefault(@Nullable Long idToUseAsDefault) { + if (idToUseAsDefault == null) { + propertiesDao.deleteGlobalProperty(SONAR_QUALITYGATE_PROPERTY); + } else { + QualityGateDto newDefault = getNonNull(idToUseAsDefault); + propertiesDao.setProperty(new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY).setValue(newDefault.getName())); + } + } + + @CheckForNull + public QualityGateDto getDefault() { + String defaultName = getDefaultName(); + if (defaultName == null) { + return null; + } else { + return dao.selectByName(defaultName); + } + } + + private boolean isDefault(QualityGateDto qGate) { + return qGate.getName().equals(getDefaultName()); + } + + private String getDefaultName() { + PropertyDto defaultQgate = propertiesDao.selectGlobalProperty(SONAR_QUALITYGATE_PROPERTY); + if (defaultQgate == null || StringUtils.isBlank(defaultQgate.getValue())) { + return null; + } else { + return defaultQgate.getValue(); + } + } + + private QualityGateDto getNonNull(long id) { + QualityGateDto qGate = dao.selectById(id); + if (qGate == null) { + throw new NotFoundException(); + } + return qGate; + } + private void validateQualityGate(@Nullable Long updatingQgateId, @Nullable String name) { List messages = newArrayList(); if (Strings.isNullOrEmpty(name)) { diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java index 017280cb44f..4855b658ec2 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java @@ -19,6 +19,7 @@ */ package org.sonar.server.qualitygate.ws; +import org.sonar.server.exceptions.BadRequestException; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.RequestHandler; import org.sonar.api.server.ws.Response; @@ -40,6 +41,7 @@ public class QualityGatesWs implements WebService { NewController controller = context.newController("api/qualitygates") .setSince("4.3") .setDescription("This service can be used to manage quality gates, including requirements and project association."); + controller.newAction("create") .setDescription("Create a quality gate, given its name.") .setPost(true) @@ -48,7 +50,40 @@ public class QualityGatesWs implements WebService { public void handle(Request request, Response response) { create(request, response); } - }).newParam("name"); + }).newParam("name").setDescription("The name of the quality gate to create."); + + controller.newAction("set_as_default") + .setDescription("Select the default quality gate.") + .setPost(true) + .setHandler(new RequestHandler() { + @Override + public void handle(Request request, Response response) { + setDefault(request, response); + } + }).newParam("id").setDescription("The ID of the quality gate to use as default."); + + controller.newAction("unset_default") + .setDescription("Unselect the default quality gate.") + .setPost(true) + .setHandler(new RequestHandler() { + @Override + public void handle(Request request, Response response) { + unsetDefault(response); + } + }); + + NewAction rename = controller.newAction("rename") + .setDescription("Rename a quality gate, given its id and new name.") + .setPost(true) + .setHandler(new RequestHandler() { + @Override + public void handle(Request request, Response response) { + rename(request, response); + } + }); + rename.newParam("id").setDescription("The ID of the quality gate to rename."); + rename.newParam("name").setDescription("The new name for the quality gate."); + controller.newAction("list") .setDescription("List all quality gates.") .setHandler(new RequestHandler() { @@ -57,15 +92,53 @@ public class QualityGatesWs implements WebService { list(request, response); } }); + + controller.newAction("destroy") + .setDescription("Destroy a quality gate, given its id.") + .setPost(true) + .setHandler(new RequestHandler() { + @Override + public void handle(Request request, Response response) { + destroy(request, response); + } + }).newParam("id").setDescription("The numerical ID of the quality gate to destroy."); + controller.done(); } + protected void setDefault(Request request, Response response) { + qualityGates.setDefault(parse(request.requiredParam("id"))); + response.noContent(); + } + + protected void unsetDefault(Response response) { + qualityGates.setDefault(null); + response.noContent(); + } + + protected void rename(Request request, Response response) { + long idToRename = parse(request.requiredParam("id")); + QualityGateDto renamedQualityGate = qualityGates.rename(idToRename, request.requiredParam("name")); + JsonWriter writer = response.newJsonWriter(); + writeQualityGate(renamedQualityGate, writer).close(); + } + + protected void destroy(Request request, Response response) { + qualityGates.delete(parse(request.requiredParam("id"))); + response.noContent(); + } + protected void list(Request request, Response response) { JsonWriter writer = response.newJsonWriter().beginObject().name("qualitygates").beginArray(); for (QualityGateDto qgate: qualityGates.list()) { writeQualityGate(qgate, writer); } - writer.endArray().endObject().close(); + writer.endArray(); + QualityGateDto defaultQgate = qualityGates.getDefault(); + if (defaultQgate != null) { + writer.prop("default", defaultQgate.getId()); + } + writer.endObject().close(); } protected void create(Request request, Response response) { @@ -74,6 +147,14 @@ public class QualityGatesWs implements WebService { writeQualityGate(newQualityGate, writer).close(); } + private Long parse(String idParam) { + try { + return Long.valueOf(idParam); + } catch (NumberFormatException badFormat) { + throw new BadRequestException("id must be a valid long value"); + } + } + private JsonWriter writeQualityGate(QualityGateDto newQualityGate, JsonWriter writer) { return writer.beginObject() .prop("id", newQualityGate.getId()) diff --git a/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java b/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java index b252d02a8b5..57396a96954 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java @@ -19,8 +19,12 @@ */ package org.sonar.server.qualitygate; +import org.sonar.core.properties.PropertyDto; +import org.mockito.ArgumentCaptor; +import org.mockito.Matchers; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.core.properties.PropertiesDao; import org.sonar.server.exceptions.ForbiddenException; - import org.sonar.server.exceptions.UnauthorizedException; import org.sonar.server.user.UserSessionTestUtils; import org.sonar.core.permission.GlobalPermissions; @@ -38,7 +42,7 @@ import org.sonar.server.exceptions.BadRequestException; import java.util.List; -import static org.fest.assertions.Assertions.assertThat; +import static org.fest.assertions.Assertions.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -48,6 +52,9 @@ public class QualityGatesTest { @Mock private QualityGateDao dao; + @Mock + private PropertiesDao propertiesDao; + private QualityGates qGates; UserSession authorizedUserSession = MockUserSession.create().setLogin("gaudol").setName("Olivier").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); @@ -56,7 +63,7 @@ public class QualityGatesTest { @Before public void initialize() { - qGates = new QualityGates(dao); + qGates = new QualityGates(dao, propertiesDao); UserSessionTestUtils.setUserSession(authorizedUserSession); } @@ -88,7 +95,6 @@ public class QualityGatesTest { qGates.create("polop"); } - @Test(expected = BadRequestException.class) public void should_fail_create_on_empty_name() throws Exception { qGates.create(""); @@ -100,4 +106,110 @@ public class QualityGatesTest { when(dao.selectByName(name)).thenReturn(new QualityGateDto().setName(name).setId(42L)); qGates.create(name); } + + @Test + public void should_rename_qgate() throws Exception { + long id = 42L; + String name = "SG-1"; + QualityGateDto existing = new QualityGateDto().setId(id).setName("Golden"); + when(dao.selectById(id)).thenReturn(existing); + QualityGateDto sg1 = qGates.rename(id, name); + assertThat(sg1.getName()).isEqualTo(name); + verify(dao).selectById(id); + verify(dao).selectByName(name); + verify(dao).update(sg1); + } + + @Test + public void should_allow_rename_with_same_name() throws Exception { + long id = 42L; + String name = "SG-1"; + QualityGateDto existing = new QualityGateDto().setId(id).setName(name); + when(dao.selectById(id)).thenReturn(existing); + QualityGateDto sg1 = qGates.rename(id, name); + assertThat(sg1.getName()).isEqualTo(name); + verify(dao).selectById(id); + verify(dao).selectByName(name); + verify(dao).update(sg1); + } + + @Test(expected = NotFoundException.class) + public void should_fail_rename_on_inexistent_qgate() throws Exception { + qGates.rename(42L, "Unknown"); + } + + @Test(expected = BadRequestException.class) + public void should_fail_rename_on_duplicate_name() throws Exception { + long id = 42L; + String name = "SG-1"; + QualityGateDto existing = new QualityGateDto().setId(id).setName("Golden"); + when(dao.selectById(id)).thenReturn(existing); + when(dao.selectByName(name)).thenReturn(new QualityGateDto().setId(666L).setName(name)); + qGates.rename(id, name); + } + + @Test + public void should_select_default_qgate() throws Exception { + long defaultId = 42L; + String defaultName = "Default Name"; + when(dao.selectById(defaultId)).thenReturn(new QualityGateDto().setId(defaultId).setName(defaultName )); + qGates.setDefault(defaultId); + verify(dao).selectById(defaultId); + ArgumentCaptor propertyCaptor = ArgumentCaptor.forClass(PropertyDto.class); + verify(propertiesDao).setProperty(propertyCaptor.capture()); + assertThat(propertyCaptor.getValue().getKey()).isEqualTo("sonar.qualitygate"); + assertThat(propertyCaptor.getValue().getValue()).isEqualTo(defaultName); + } + + @Test + public void should_unset_default_qgate() throws Exception { + qGates.setDefault(null); + verify(propertiesDao).deleteGlobalProperty("sonar.qualitygate"); + } + + @Test + public void should_delete_qgate() throws Exception { + long idToDelete = 42L; + QualityGateDto toDelete = new QualityGateDto().setId(idToDelete).setName("To Delete"); + when(dao.selectById(idToDelete)).thenReturn(toDelete); + qGates.delete(idToDelete); + verify(dao).selectById(idToDelete); + verify(dao).delete(toDelete); + } + + @Test + public void should_delete_qgate_if_non_default() throws Exception { + long idToDelete = 42L; + QualityGateDto toDelete = new QualityGateDto().setId(idToDelete).setName("To Delete"); + when(dao.selectById(idToDelete)).thenReturn(toDelete); + when(propertiesDao.selectGlobalProperty("sonar.qualitygate")).thenReturn(new PropertyDto().setValue("Other Qgate")); + qGates.delete(idToDelete); + verify(dao).selectById(idToDelete); + verify(dao).delete(toDelete); + } + + @Test(expected = BadRequestException.class) + public void should_not_delete_qgate_if_default() throws Exception { + long idToDelete = 42L; + String name = "To Delete"; + QualityGateDto toDelete = new QualityGateDto().setId(idToDelete).setName(name); + when(dao.selectById(idToDelete)).thenReturn(toDelete); + when(propertiesDao.selectGlobalProperty("sonar.qualitygate")).thenReturn(new PropertyDto().setValue(name)); + qGates.delete(idToDelete); + } + + @Test + public void should_return_default_qgate_if_set() throws Exception { + String defaultName = "Sonar way"; + when(propertiesDao.selectGlobalProperty("sonar.qualitygate")).thenReturn(new PropertyDto().setValue(defaultName)); + QualityGateDto defaultQgate = new QualityGateDto().setId(42L).setName(defaultName); + when(dao.selectByName(defaultName)).thenReturn(defaultQgate); + assertThat(qGates.getDefault()).isEqualTo(defaultQgate); + } + + @Test + public void should_return_null_default_qgate_if_unset() throws Exception { + when(propertiesDao.selectGlobalProperty("sonar.qualitygate")).thenReturn(new PropertyDto().setValue("")); + assertThat(qGates.getDefault()).isNull(); + } } diff --git a/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java b/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java index 4cf3d6c9971..22e886472bb 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java @@ -19,18 +19,22 @@ */ package org.sonar.server.qualitygate.ws; -import org.junit.Test; -import org.sonar.api.server.ws.WebService; - -import static org.fest.assertions.Assertions.assertThat; - +import org.elasticsearch.common.collect.Lists; import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WsTester; +import org.sonar.core.qualitygate.db.QualityGateDto; +import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.qualitygate.QualityGates; +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + @RunWith(MockitoJUnitRunner.class) public class QualityGatesWsTest { @@ -50,7 +54,7 @@ public class QualityGatesWsTest { assertThat(controller).isNotNull(); assertThat(controller.path()).isEqualTo("api/qualitygates"); assertThat(controller.description()).isNotEmpty(); - assertThat(controller.actions()).hasSize(2); + assertThat(controller.actions()).hasSize(6); WebService.Action list = controller.action("list"); assertThat(list).isNotNull(); @@ -64,8 +68,124 @@ public class QualityGatesWsTest { assertThat(create.handler()).isNotNull(); assertThat(create.since()).isEqualTo("4.3"); assertThat(create.isPost()).isTrue(); - assertThat(create.params()).hasSize(1); assertThat(create.param("name")).isNotNull(); assertThat(create.isPrivate()).isFalse(); + + WebService.Action destroy = controller.action("destroy"); + assertThat(destroy).isNotNull(); + assertThat(destroy.handler()).isNotNull(); + assertThat(destroy.since()).isEqualTo("4.3"); + assertThat(destroy.isPost()).isTrue(); + assertThat(destroy.param("id")).isNotNull(); + assertThat(destroy.isPrivate()).isFalse(); + + WebService.Action rename = controller.action("rename"); + assertThat(rename).isNotNull(); + assertThat(rename.handler()).isNotNull(); + assertThat(rename.since()).isEqualTo("4.3"); + assertThat(rename.isPost()).isTrue(); + assertThat(rename.param("id")).isNotNull(); + assertThat(rename.param("name")).isNotNull(); + assertThat(rename.isPrivate()).isFalse(); + + WebService.Action setDefault = controller.action("set_as_default"); + assertThat(setDefault).isNotNull(); + assertThat(setDefault.handler()).isNotNull(); + assertThat(setDefault.since()).isEqualTo("4.3"); + assertThat(setDefault.isPost()).isTrue(); + assertThat(setDefault.param("id")).isNotNull(); + assertThat(setDefault.isPrivate()).isFalse(); + + WebService.Action unsetDefault = controller.action("unset_default"); + assertThat(setDefault).isNotNull(); + assertThat(setDefault.handler()).isNotNull(); + assertThat(setDefault.since()).isEqualTo("4.3"); + assertThat(setDefault.isPost()).isTrue(); + assertThat(setDefault.isPrivate()).isFalse(); + } + + @Test + public void create_nominal() throws Exception { + String name = "New QG"; + when(qGates.create(name)).thenReturn(new QualityGateDto().setId(42L).setName(name)); + tester.newRequest("create").setParam("name", name).execute() + .assertJson("{'id':42,'name':'New QG'}"); + } + + @Test(expected = IllegalArgumentException.class) + public void create_with_missing_name() throws Exception { + tester.newRequest("create").execute(); + } + + @Test(expected = BadRequestException.class) + public void create_with_duplicate_name() throws Exception { + String name = "New QG"; + when(qGates.create(name)).thenThrow(BadRequestException.of("Name is already used")); + tester.newRequest("create").setParam("name", name).execute(); + } + + @Test + public void rename_nominal() throws Exception { + Long id = 42L; + String name = "New QG"; + when(qGates.rename(id, name)).thenReturn(new QualityGateDto().setId(id).setName(name)); + tester.newRequest("rename").setParam("id", id.toString()).setParam("name", name).execute() + .assertNoContent(); + } + + @Test + public void set_as_default_nominal() throws Exception { + Long id = 42L; + tester.newRequest("set_as_default").setParam("id", id.toString()).execute() + .assertNoContent(); + verify(qGates).setDefault(id); + } + + @Test + public void unset_default_nominal() throws Exception { + tester.newRequest("unset_default").execute() + .assertNoContent(); + verify(qGates).setDefault(null); + } + + @Test + public void destroy_nominal() throws Exception { + Long id = 42L; + tester.newRequest("destroy").setParam("id", id.toString()).execute() + .assertNoContent(); + } + + @Test(expected = IllegalArgumentException.class) + public void destroy_without_id() throws Exception { + tester.newRequest("destroy").execute(); + } + + @Test(expected = BadRequestException.class) + public void destroy_with_invalid_id() throws Exception { + tester.newRequest("destroy").setParam("id", "polop").execute(); + } + + @Test + public void list_nominal() throws Exception { + when(qGates.list()).thenReturn(Lists.newArrayList( + new QualityGateDto().setId(42L).setName("Golden"), + new QualityGateDto().setId(43L).setName("Star"), + new QualityGateDto().setId(666L).setName("Ninth") + )); + tester.newRequest("list").execute().assertJson( + "{'qualitygates':[{'id':42,'name':'Golden'},{'id':43,'name':'Star'},{'id':666,'name':'Ninth'}]}"); + } + + @Test + public void list_with_default() throws Exception { + QualityGateDto defaultQgate = new QualityGateDto().setId(42L).setName("Golden"); + when(qGates.list()).thenReturn(Lists.newArrayList( + defaultQgate, + new QualityGateDto().setId(43L).setName("Star"), + new QualityGateDto().setId(666L).setName("Ninth") + )); + when(qGates.getDefault()).thenReturn(defaultQgate); + tester.newRequest("list").execute().assertJson( + "{'qualitygates':[{'id':42,'name':'Golden'},{'id':43,'name':'Star'},{'id':666,'name':'Ninth'}],'default':42}"); } } -- 2.39.5