From e53077c87e2c5a6441234bc61d6dfa44ba54cb32 Mon Sep 17 00:00:00 2001 From: Johannes Schnatterer Date: Thu, 28 Jun 2018 10:16:45 +0200 Subject: [PATCH 1/3] REST Docs: Describes 400 for PUT --- .../src/main/java/sonia/scm/api/v2/resources/GroupResource.java | 1 + .../src/main/java/sonia/scm/api/v2/resources/UserResource.java | 1 + 2 files changed, 2 insertions(+) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java index f8c7a3852c..affdf94332 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupResource.java @@ -87,6 +87,7 @@ public class GroupResource { @Consumes(VndMediaType.GROUP) @StatusCodes({ @ResponseCode(code = 204, condition = "update success"), + @ResponseCode(code = 400, condition = "Invalid body, e.g. illegal change of id/group name"), @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"group\" privilege"), @ResponseCode(code = 404, condition = "not found, no group with the specified id/name available"), diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java index f1d9596b3e..2356e81ed7 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserResource.java @@ -93,6 +93,7 @@ public class UserResource { @Consumes(VndMediaType.USER) @StatusCodes({ @ResponseCode(code = 204, condition = "update success"), + @ResponseCode(code = 400, condition = "Invalid body, e.g. illegal change of id/user name"), @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), @ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user\" privilege"), @ResponseCode(code = 404, condition = "not found, no user with the specified id/name available"), From ad4ea743a0fe360ab4d47b022793ade2d52b7d2b Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Thu, 28 Jun 2018 11:06:16 +0200 Subject: [PATCH 2/3] Added unit tests for PUT/DELETE on groups --- .../v2/resources/GroupRootResourceTest.java | 69 +++++++++++++++++++ .../sonia/scm/api/v2/group-test-update.json | 11 +++ 2 files changed, 80 insertions(+) create mode 100644 scm-webapp/src/test/resources/sonia/scm/api/v2/group-test-update.json diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupRootResourceTest.java index 2b4cedb4fc..74b9dbd2d5 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/GroupRootResourceTest.java @@ -65,6 +65,7 @@ public class GroupRootResourceTest { public void prepareEnvironment() throws IOException, GroupException { initMocks(this); doNothing().when(groupManager).create(groupCaptor.capture()); + doNothing().when(groupManager).modify(groupCaptor.capture()); Group group = createDummyGroup(); when(groupManager.getPage(any(), eq(0), eq(10))).thenReturn(new PageResult<>(singletonList(group), 1)); @@ -108,6 +109,74 @@ public class GroupRootResourceTest { assertTrue(response.getContentAsString().contains("\"name\":\"user\"")); } + @Test + public void shouldUpdateGroup() throws URISyntaxException, IOException { + URL url = Resources.getResource("sonia/scm/api/v2/group-test-update.json"); + byte[] groupJson = Resources.toByteArray(url); + + Group group = createDummyGroup(); + when(groupManager.get("admin")).thenReturn(group); + Group updatedGroup = createDummyGroup(); + updatedGroup.setDescription("Updated description"); + + MockHttpRequest request = MockHttpRequest + .put("/" + GroupRootResource.GROUPS_PATH_V2 + "admin") + .contentType(VndMediaType.GROUP) + .content(groupJson); + + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + Group capturedGroup = groupCaptor.getValue(); + + assertEquals(HttpServletResponse.SC_NO_CONTENT, response.getStatus()); + + assertEquals("Updated description", capturedGroup.getDescription()); + } + + @Test + public void updateShouldFailOnNonexistentGroup() throws URISyntaxException, IOException { + URL url = Resources.getResource("sonia/scm/api/v2/group-test-update.json"); + byte[] groupJson = Resources.toByteArray(url); + + Group updatedGroup = createDummyGroup(); + updatedGroup.setDescription("Updated description"); + + MockHttpRequest request = MockHttpRequest + .put("/" + GroupRootResource.GROUPS_PATH_V2 + "idontexist") + .contentType(VndMediaType.GROUP) + .content(groupJson); + + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_NOT_FOUND, response.getStatus()); + } + + @Test + public void shouldDeleteGroup() throws URISyntaxException { + Group group = createDummyGroup(); + when(groupManager.get("admin")).thenReturn(group); + + MockHttpRequest request = MockHttpRequest.delete("/" + GroupRootResource.GROUPS_PATH_V2 + "admin"); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_NO_CONTENT, response.getStatus()); + } + + @Test + public void shouldNotFailOnDeletingNonexistentGroup() throws URISyntaxException { + MockHttpRequest request = MockHttpRequest.delete("/" + GroupRootResource.GROUPS_PATH_V2 + "idontexist"); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_NO_CONTENT, response.getStatus()); + } + @Test public void shouldCreateNewGroupWithMembers() throws URISyntaxException, IOException { URL url = Resources.getResource("sonia/scm/api/v2/group-test-create.json"); diff --git a/scm-webapp/src/test/resources/sonia/scm/api/v2/group-test-update.json b/scm-webapp/src/test/resources/sonia/scm/api/v2/group-test-update.json new file mode 100644 index 0000000000..fd41ff5837 --- /dev/null +++ b/scm-webapp/src/test/resources/sonia/scm/api/v2/group-test-update.json @@ -0,0 +1,11 @@ +{ + "description": "Updated description", + "name": "admin", + "_embedded": { + "members": [ + { + "name": "user" + } + ] + } +} From 4da48d1ed3a569a57a04a0799ac3efeebc2df63e Mon Sep 17 00:00:00 2001 From: Philipp Czora Date: Thu, 28 Jun 2018 11:56:21 +0200 Subject: [PATCH 3/3] Renamed query param --- .../v2/resources/GroupCollectionResource.java | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java index 12a3cd58f1..b2842e2571 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionResource.java @@ -1,23 +1,13 @@ package sonia.scm.api.v2.resources; -import com.webcohesion.enunciate.metadata.rs.ResponseCode; -import com.webcohesion.enunciate.metadata.rs.ResponseHeader; -import com.webcohesion.enunciate.metadata.rs.ResponseHeaders; -import com.webcohesion.enunciate.metadata.rs.StatusCodes; -import com.webcohesion.enunciate.metadata.rs.TypeHint; +import com.webcohesion.enunciate.metadata.rs.*; import sonia.scm.group.Group; import sonia.scm.group.GroupException; import sonia.scm.group.GroupManager; import sonia.scm.web.VndMediaType; import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; +import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; @@ -65,7 +55,7 @@ public class GroupCollectionResource { public Response getAll(@Context Request request, @DefaultValue("0") @QueryParam("page") int page, @DefaultValue("" + DEFAULT_PAGE_SIZE) @QueryParam("pageSize") int pageSize, - @QueryParam("sortby") String sortBy, + @QueryParam("sortBy") String sortBy, @DefaultValue("false") @QueryParam("desc") boolean desc) { return adapter.getAll(page, pageSize, sortBy, desc,