keycloak-aplcache

Details

diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java
index e821985..0563112 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java
@@ -129,7 +129,7 @@ public class GroupResource {
             child = realm.createGroup(rep.getName());
             updateGroup(rep, child);
             URI uri = uriInfo.getBaseUriBuilder()
-                                           .path(uriInfo.getMatchedURIs().get(1))
+                                           .path(uriInfo.getMatchedURIs().get(2))
                                            .path(child.getId()).build();
             builder.status(201).location(uri);
             adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java
index 81d8e61..e369859 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java
@@ -27,12 +27,16 @@ import org.keycloak.representations.idm.GroupRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.testsuite.admin.ApiUtil;
+import org.keycloak.testsuite.util.URLAssert;
+import org.keycloak.util.JsonSerialization;
 
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.net.URI;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.UUID;
 
 
 /**
@@ -107,6 +111,21 @@ public class GroupTest extends AbstractGroupTest {
         level2Group.setName("level2");
         response = realm.groups().group(topGroup.getId()).subGroup(level2Group);
         response.close();
+
+        URI location = response.getLocation();
+        final String level2Id = ApiUtil.getCreatedId(response);
+        final GroupRepresentation level2GroupById = realm.groups().group(level2Id).toRepresentation();
+        Assert.assertEquals(level2Id, level2GroupById.getId());
+        Assert.assertEquals(level2Group.getName(), level2GroupById.getName());
+
+        URLAssert.assertGetURL(location, adminClient.tokenManager().getAccessTokenString(), new URLAssert.AssertJSONResponseHandler() {
+            @Override
+            protected void assertResponseBody(String body) throws IOException {
+                GroupRepresentation level2 = JsonSerialization.readValue(body, GroupRepresentation.class);
+                Assert.assertEquals(level2Id, level2.getId());
+            }
+        });
+
         level2Group = realm.getGroupByPath("/top/level2");
         Assert.assertNotNull(level2Group);
         roles.clear();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java
index c66fd70..6ef0bbe 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java
@@ -18,14 +18,27 @@
 package org.keycloak.testsuite.util;
 
 import javax.ws.rs.core.UriBuilder;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.junit.Assert;
 import org.keycloak.testsuite.page.AbstractPage;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import org.keycloak.testsuite.auth.page.login.PageWithLoginUrl;
 import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.support.ui.ExpectedCondition;
-import org.openqa.selenium.support.ui.WebDriverWait;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.net.URI;
+import java.nio.charset.Charset;
 
 /**
  *
@@ -104,9 +117,68 @@ public class URLAssert {
     public static void assertCurrentUrlStartsWithLoginUrlOf(PageWithLoginUrl page) {
         assertCurrentUrlStartsWithLoginUrlOf(page.getDriver(), page);
     }
-    
+
     public static void assertCurrentUrlStartsWithLoginUrlOf(WebDriver driver, PageWithLoginUrl page) {
         assertCurrentUrlStartsWith(driver, page.getOIDCLoginUrl().toString());
     }
 
+    public static void assertGetURL(URI url, String accessToken, AssertResponseHandler handler) {
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        try {
+            HttpGet get = new HttpGet(url);
+            get.setHeader("Authorization", "Bearer " + accessToken);
+
+            CloseableHttpResponse response = httpclient.execute(get);
+
+            if (response.getStatusLine().getStatusCode() != 200) {
+                throw new RuntimeException("Response status error: " + response.getStatusLine().getStatusCode() + ": " + url);
+            }
+
+            handler.assertResponse(response);
+
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        finally {
+            try {
+                httpclient.close();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public interface AssertResponseHandler {
+        void assertResponse(CloseableHttpResponse response) throws IOException;
+    }
+
+    public static abstract class AssertJSONResponseHandler implements AssertResponseHandler {
+
+        @Override
+        public void assertResponse(CloseableHttpResponse response) throws IOException {
+            HttpEntity entity = response.getEntity();
+            Header contentType = entity.getContentType();
+            Assert.assertEquals("application/json", contentType.getValue());
+
+            char [] buf = new char[8192];
+            StringWriter out = new StringWriter();
+            Reader in = new InputStreamReader(entity.getContent(), Charset.forName("utf-8"));
+            int rc = 0;
+            try {
+                while ((rc = in.read(buf)) != -1) {
+                    out.write(buf, 0, rc);
+                }
+            } finally {
+                try {
+                    in.close();
+                } catch (Exception ignored) {}
+
+                out.close();
+            }
+
+            assertResponseBody(out.toString());
+        }
+
+        protected abstract void assertResponseBody(String body) throws IOException;
+    }
 }