diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/GroupsResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/GroupsResource.java
index e704c399d6..6c92204cca 100755
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/GroupsResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/GroupsResource.java
@@ -24,6 +24,7 @@ import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
+import java.util.Map;
/**
* @author Bill Burke
@@ -69,39 +70,38 @@ public interface GroupsResource {
/**
* Counts all groups.
- * @return The number of groups.
+ * @return A map containing key "count" with number of groups as value.
*/
@GET
@NoCache
- @Path("/count")
+ @Path("count")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
- Response count();
+ Map count();
/**
* Counts groups by name search.
* @param search max number of occurrences
- * @return The number of group containing search therm.
+ * @return A map containing key "count" with number of groups as value which matching with search.
*/
@GET
@NoCache
- @Path("/count")
+ @Path("count")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
- Response count(@QueryParam("search") String search);
+ Map count(@QueryParam("search") String search);
/**
* Counts groups by name search.
- * @param search max number of occurrences
* @param onlyTopGroups true
or false
for filter only top level groups count
- * @return The number of group containing search therm.
+ * @return A map containing key "count" with number of top level groups.
*/
@GET
@NoCache
- @Path("/count")
+ @Path("count")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
- Response count(@QueryParam("search") String search, @QueryParam("top") String onlyTopGroups);
+ Map count(@QueryParam("top") @DefaultValue("true") boolean onlyTopGroups);
/**
* create or add a top level realm groupSet or create child. This will update the group and set the parent if it exists. Create it and set the parent
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java
index bcff0ba591..318bb539c5 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java
@@ -94,7 +94,6 @@ public class RealmCacheSession implements CacheRealmProvider {
protected static final Logger logger = Logger.getLogger(RealmCacheSession.class);
public static final String REALM_CLIENTS_QUERY_SUFFIX = ".realm.clients";
public static final String ROLES_QUERY_SUFFIX = ".roles";
- public static final String ROLE_BY_NAME_QUERY_SUFFIX = ".role.by-name";
protected RealmCacheManager cache;
protected KeycloakSession session;
protected RealmProvider delegate;
@@ -839,6 +838,9 @@ public class RealmCacheSession implements CacheRealmProvider {
}
list.add(group);
}
+
+ list.sort(Comparator.comparing(GroupModel::getName));
+
return list;
}
@@ -885,6 +887,9 @@ public class RealmCacheSession implements CacheRealmProvider {
}
list.add(group);
}
+
+ list.sort(Comparator.comparing(GroupModel::getName));
+
return list;
}
@@ -921,6 +926,9 @@ public class RealmCacheSession implements CacheRealmProvider {
}
list.add(group);
}
+
+ list.sort(Comparator.comparing(GroupModel::getName));
+
return list;
}
@@ -980,11 +988,9 @@ public class RealmCacheSession implements CacheRealmProvider {
String groupId = eventToAdd.getId();
// Check if we have existing event with bigger priority
- boolean eventAlreadyExists = invalidationEvents.stream().filter((InvalidationEvent event) -> {
-
- return (event.getId().equals(groupId)) && (event instanceof GroupAddedEvent || event instanceof GroupMovedEvent || event instanceof GroupRemovedEvent);
-
- }).findFirst().isPresent();
+ boolean eventAlreadyExists = invalidationEvents.stream()
+ .anyMatch((InvalidationEvent event) -> (event.getId().equals(groupId)) &&
+ (event instanceof GroupAddedEvent || event instanceof GroupMovedEvent || event instanceof GroupRemovedEvent));
if (!eventAlreadyExists) {
invalidationEvents.add(eventToAdd);
diff --git a/model/jpa/pom.xml b/model/jpa/pom.xml
index 5994089985..54166f5445 100755
--- a/model/jpa/pom.xml
+++ b/model/jpa/pom.xml
@@ -111,11 +111,6 @@
junit
test
-
- org.mockito
- mockito-all
- test
-
diff --git a/model/jpa/src/test/java/org/keycloak/models/jpa/JpaRealmProviderTest.java b/model/jpa/src/test/java/org/keycloak/models/jpa/JpaRealmProviderTest.java
deleted file mode 100644
index fc8ffa4ae1..0000000000
--- a/model/jpa/src/test/java/org/keycloak/models/jpa/JpaRealmProviderTest.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.keycloak.models.jpa;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.keycloak.models.GroupModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RealmProvider;
-import org.keycloak.models.jpa.entities.GroupEntity;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.mockito.stubbing.Answer;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-import javax.persistence.TypedQuery;
-import java.util.*;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
-
-/**
- * @author NAGY Léventé
- * @version $Revision: 1 $
- */
-@RunWith(MockitoJUnitRunner.class)
-public class JpaRealmProviderTest {
-
- private JpaRealmProvider subject;
-
- private RealmModel realmModelMock;
- private RealmProvider realmProviderMock;
- private KeycloakSession sessionMock;
- private EntityManager entityManagerMock;
-
- @Before
- public void setup() {
- realmModelMock = mock(RealmModel.class);
- realmProviderMock = mock(RealmProvider.class);
- sessionMock = mock(KeycloakSession.class);
- entityManagerMock = mock(EntityManager.class);
-
- subject = new JpaRealmProvider(sessionMock, entityManagerMock);
-
- // Common behaviours
- when(realmProviderMock.getGroupById(anyString(), any(RealmModel.class))).thenAnswer((Answer) invocationOnMock -> {
- GroupEntity entity = new GroupEntity();
- entity.setId((String) invocationOnMock.getArguments()[0]);
- entity.setName((String) invocationOnMock.getArguments()[0]);
- return new GroupAdapter(realmModelMock, entityManagerMock, entity);
- });
- }
-
- @Test
- public void testGetGroupsCountAllGroups() {
- // Given
- Long result = 10L;
- String idRealm = "idGroup";
- TypedQuery query = mock(TypedQuery.class);
-
- // When
- when(entityManagerMock.createNamedQuery("getGroupCount", Long.class)).thenReturn(query);
- when(realmModelMock.getId()).thenReturn(idRealm);
- when(query.setParameter("realm", idRealm)).thenReturn(query);
- when(query.getSingleResult()).thenReturn(result);
-
- // Then
- Long countResult = subject.getGroupsCount(realmModelMock, false);
-
- assertEquals(result, countResult);
- }
-
- @Test
- public void testGetGroupsCountOnlyTopLevelGroups() {
- // Given
- Long result = 10L;
- String idRealm = "idGroup";
- TypedQuery query = mock(TypedQuery.class);
-
- // When
- when(entityManagerMock.createNamedQuery("getTopLevelGroupCount", Long.class)).thenReturn(query);
- when(realmModelMock.getId()).thenReturn(idRealm);
- when(query.setParameter("realm", idRealm)).thenReturn(query);
- when(query.getSingleResult()).thenReturn(result);
-
- // Then
- Long countResult = subject.getGroupsCount(realmModelMock, true);
-
- assertEquals(result, countResult);
- }
-
- @Test
- public void testSearchForGroupByNameWithAllParams() {
- // Given
- List result = Arrays.asList("idGroup1", "idGroup2", "idGroup3");
- String idRealm = "idGroup";
- TypedQuery query = mock(TypedQuery.class);
- String search = "findMe";
- Integer first = 0;
- Integer max = 10;
-
- // When
- when(entityManagerMock.createNamedQuery("getGroupIdsByNameContaining", String.class)).thenReturn(query);
- when(realmModelMock.getId()).thenReturn(idRealm);
- when(query.setParameter("realm", idRealm)).thenReturn(query);
- when(query.setParameter("search", search)).thenReturn(query);
- when(query.setFirstResult(first)).thenReturn(query);
- when(query.setMaxResults(max)).thenReturn(query);
- when(query.getResultList()).thenReturn(result);
- when(sessionMock.realms()).thenReturn(realmProviderMock);
-
- // Then
- List searchResult = subject.searchForGroupByName(realmModelMock, search, first, max);
-
- assertEquals(result.size(), searchResult.size());
- }
-
- @Test
- public void testSearchForGroupByNameWithNullQueryResult() {
- // Given
- String idRealm = "idGroup";
- TypedQuery query = mock(TypedQuery.class);
- String search = "findMe";
-
- // When
- when(entityManagerMock.createNamedQuery("getGroupIdsByNameContaining", String.class)).thenReturn(query);
- when(realmModelMock.getId()).thenReturn(idRealm);
- when(query.setParameter("realm", idRealm)).thenReturn(query);
- when(query.setParameter("search", search)).thenReturn(query);
- when(query.getResultList()).thenReturn(null);
- when(sessionMock.realms()).thenReturn(realmProviderMock);
-
- // Then
- List searchResult = subject.searchForGroupByName(realmModelMock, search, null, null);
-
- assertEquals(Collections.EMPTY_LIST, searchResult);
- }
-
- @Test
- public void testSearchForGroupByNameWithNonTopLevelGroupInQueryResult() {
- // Given
- List result = Arrays.asList("idGroup1", "idGroup2", "idGroup3", "idGroup4");
- String idRealm = "idGroup";
- TypedQuery query = mock(TypedQuery.class);
- String search = "findMe";
- Integer first = 0;
- Integer max = 10;
-
- // When
- when(entityManagerMock.createNamedQuery("getGroupIdsByNameContaining", String.class)).thenReturn(query);
- when(realmModelMock.getId()).thenReturn(idRealm);
- when(query.setParameter("realm", idRealm)).thenReturn(query);
- when(query.setParameter("search", search)).thenReturn(query);
- when(query.setFirstResult(first)).thenReturn(query);
- when(query.setMaxResults(max)).thenReturn(query);
- when(query.getResultList()).thenReturn(result);
- when(sessionMock.realms()).thenReturn(realmProviderMock);
- when(realmProviderMock.getGroupById(anyString(), any(RealmModel.class))).thenAnswer((Answer) invocationOnMock -> {
- GroupEntity entity = new GroupEntity();
- entity.setId((String) invocationOnMock.getArguments()[0]);
- entity.setName((String) invocationOnMock.getArguments()[0]);
- if(Arrays.asList("idGroup2", "idGroup4").contains(invocationOnMock.getArguments()[0])) {
- entity.setParent(new GroupEntity());
- entity.getParent().setId("idGroup5");
- entity.getParent().setName("idGroup5");
- }
- return new GroupAdapter(realmModelMock, entityManagerMock, entity);
- });
-
- // Then
- List searchResult = subject.searchForGroupByName(realmModelMock, search, first, max);
-
- assertEquals(3,searchResult.size());
- }
-
- @Test
- public void testGetGroupsCountByNameContaining() {
- // Given
- List result = Arrays.asList("idGroup1", "idGroup2", "idGroup3", "idGroup4");
- String idRealm = "idGroup";
- TypedQuery query = mock(TypedQuery.class);
- String search = "findMe";
-
- // When
- when(entityManagerMock.createNamedQuery("getGroupIdsByNameContaining", String.class)).thenReturn(query);
- when(realmModelMock.getId()).thenReturn(idRealm);
- when(query.setParameter("realm", idRealm)).thenReturn(query);
- when(query.setParameter("search", search)).thenReturn(query);
- when(query.getResultList()).thenReturn(result);
- when(sessionMock.realms()).thenReturn(realmProviderMock);
-
- // Then
- Long countResult = subject.getGroupsCountByNameContaining(realmModelMock, search);
-
- verify(query, never()).setFirstResult(anyInt());
- verify(query, never()).setFirstResult(anyInt());
- assertEquals(result.size(), countResult.intValue());
- }
-}
diff --git a/pom.xml b/pom.xml
index e437123938..8b216dcbef 100755
--- a/pom.xml
+++ b/pom.xml
@@ -108,7 +108,6 @@
1.3
2.10
4.12
- 1.9.5
2.7.0.Final
2.35.0
1.4.01
@@ -368,12 +367,6 @@
${junit.version}
test
-
- org.mockito
- mockito-all
- test
- ${mockito.version}
-
org.hamcrest
hamcrest-all
diff --git a/services/pom.xml b/services/pom.xml
index cbbf3da206..733b81277e 100755
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -180,11 +180,6 @@
-
- org.mockito
- mockito-all
- test
-
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java
index 958b995786..15be7ae029 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java
@@ -35,7 +35,9 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import org.keycloak.services.ErrorResponse;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
@@ -113,22 +115,19 @@ public class GroupsResource {
*/
@GET
@NoCache
- @Path("/count")
+ @Path("count")
@Produces(MediaType.APPLICATION_JSON)
- public Response getGroupCount(@QueryParam("search") String search, @QueryParam("top") String onlyTopGroups) {
+ public Map getGroupCount(@QueryParam("search") String search,
+ @QueryParam("top") @DefaultValue("false") boolean onlyTopGroups) {
Long results;
- JSONObject response = new JSONObject();
+ Map map = new HashMap<>();
if (Objects.nonNull(search)) {
results = realm.getGroupsCountByNameContaining(search);
} else {
- results = realm.getGroupsCount(Objects.equals(onlyTopGroups, Boolean.TRUE.toString()));
+ results = realm.getGroupsCount(onlyTopGroups);
}
- try {
- response.put("count", results);
- } catch (JSONException e) {
- return ErrorResponse.error("Cannot create response object", Response.Status.INTERNAL_SERVER_ERROR);
- }
- return Response.ok(response.toString(), MediaType.APPLICATION_JSON).build();
+ map.put("count", results);
+ return map;
}
/**
diff --git a/services/src/test/java/org/keycloak/services/resources/admin/GroupsResourceTest.java b/services/src/test/java/org/keycloak/services/resources/admin/GroupsResourceTest.java
deleted file mode 100644
index 9783bbb065..0000000000
--- a/services/src/test/java/org/keycloak/services/resources/admin/GroupsResourceTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright 2016 Red Hat, Inc. and/or its affiliates
- * and other contributors as indicated by the @author tags.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.keycloak.services.resources.admin;
-
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.events.admin.ResourceType;
-import org.keycloak.models.GroupModel;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
-import org.keycloak.representations.idm.GroupRepresentation;
-import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
-import org.keycloak.services.resources.admin.permissions.GroupPermissionEvaluator;
-import twitter4j.JSONException;
-import twitter4j.JSONObject;
-
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.util.Collections;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-/**
- * @author NAGY Léventé
- * @version $Revision: 1 $
- */
-public class GroupsResourceTest {
-
- private GroupsResource subject;
-
- private RealmModel realmMock;
- private KeycloakSession sessionMock;
- private AdminPermissionEvaluator authMock;
- private AdminEventBuilder adminEventBuilderMock;
-
- @Before
- public void setup() {
- realmMock = mock(RealmModel.class);
- sessionMock = mock(KeycloakSession.class);
- authMock = mock(AdminPermissionEvaluator.class);
- when(authMock.groups()).thenReturn(mock(GroupPermissionEvaluator.class));
-
- adminEventBuilderMock = mock(AdminEventBuilder.class);
- when(adminEventBuilderMock.resource(ResourceType.GROUP)).thenReturn(adminEventBuilderMock);
-
- subject= new GroupsResource(realmMock, sessionMock, authMock, adminEventBuilderMock);
- }
-
- @Test
- public void testGetGroupWithAllParams() {
- // Given
- String search = "hello";
- Integer first = 0;
- Integer max = 20;
- String groupId = "groupId";
- String groupName = "groupName";
- GroupModel groupMock = mock(GroupModel.class);
- List groupsList = Collections.singletonList(groupMock);
-
- // When
- when(realmMock.searchForGroupByName(search, first, max)).thenReturn(groupsList);
- when(groupMock.getSubGroups()).thenReturn(Collections.EMPTY_SET);
- when(groupMock.getId()).thenReturn(groupId);
- when(groupMock.getName()).thenReturn(groupName);
- when(groupMock.getParent()).thenReturn(null);
-
- //Then
- List result = subject.getGroups(search, first,max);
-
- Assert.assertEquals(groupsList.size(), result.size());
- Assert.assertEquals(groupId, result.get(0).getId());
- Assert.assertEquals(groupName, result.get(0).getName());
- Assert.assertTrue(result.get(0).getSubGroups().isEmpty());
- }
-
- @Test
- public void testGetGroupWithoutSearch() {
- // Given
- Integer first = 0;
- Integer max = 20;
- String groupId = "groupId";
- String groupName = "groupName";
- GroupModel groupMock = mock(GroupModel.class);
- List groupsList = Collections.singletonList(groupMock);
-
- // When
- when(realmMock.getTopLevelGroups(first, max)).thenReturn(groupsList);
- when(groupMock.getSubGroups()).thenReturn(Collections.EMPTY_SET);
- when(groupMock.getId()).thenReturn(groupId);
- when(groupMock.getName()).thenReturn(groupName);
- when(groupMock.getParent()).thenReturn(null);
-
- //Then
- List result = subject.getGroups(null, first,max);
-
- Assert.assertEquals(groupsList.size(), result.size());
- Assert.assertEquals(groupId, result.get(0).getId());
- Assert.assertEquals(groupName, result.get(0).getName());
- Assert.assertTrue(result.get(0).getSubGroups().isEmpty());
- }
-
- @Test
- public void testGetGroupWithoutSearchAndPagination() {
- // Given
- String groupId = "groupId";
- String groupName = "groupName";
- GroupModel groupMock = mock(GroupModel.class);
- List groupsList = Collections.singletonList(groupMock);
-
- // When
- when(realmMock.getTopLevelGroups()).thenReturn(groupsList);
- when(groupMock.getSubGroups()).thenReturn(Collections.EMPTY_SET);
- when(groupMock.getId()).thenReturn(groupId);
- when(groupMock.getName()).thenReturn(groupName);
- when(groupMock.getParent()).thenReturn(null);
-
- //Then
- List result = subject.getGroups(null, null, null);
-
- Assert.assertEquals(groupsList.size(), result.size());
- Assert.assertEquals(groupId, result.get(0).getId());
- Assert.assertEquals(groupName, result.get(0).getName());
- Assert.assertTrue(result.get(0).getSubGroups().isEmpty());
- }
-
- @Test
- public void testGetGroupCountWithSearchAndTopLevelFlagTrue() {
- // Given
- String search = "search";
- Long countResult = 5L;
- JSONObject response = new JSONObject();
- try {
- response.put("count", countResult);
- } catch (JSONException e) {
- fail(e.getMessage());
- }
-
- // When
- when(realmMock.getGroupsCountByNameContaining(search)).thenReturn(countResult);
-
- //Then
- Response restResponse = subject.getGroupCount(search, "true");
-
- assertEquals(response.toString(), restResponse.getEntity());
- assertEquals(MediaType.APPLICATION_JSON, restResponse.getMediaType().toString());
- }
-
- @Test
- public void testGetGroupCountWithoutSearchAndTopLevelFlagTrue() {
- // Given
- Long countResult = 5L;
- JSONObject response = new JSONObject();
- try {
- response.put("count", countResult);
- } catch (JSONException e) {
- fail(e.getMessage());
- }
-
- // When
- when(realmMock.getGroupsCount(true)).thenReturn(countResult);
-
- //Then
- Response restResponse = subject.getGroupCount(null, "true");
-
- assertEquals(response.toString(), restResponse.getEntity());
- assertEquals(MediaType.APPLICATION_JSON, restResponse.getMediaType().toString());
- }
-
- @Test
- public void testGetGroupCountWithoutSearchAndTopLevelFlagFalse() {
- // Given
- Long countResult = 5L;
- JSONObject response = new JSONObject();
- try {
- response.put("count", countResult);
- } catch (JSONException e) {
- fail(e.getMessage());
- }
-
- // When
- when(realmMock.getGroupsCount(false)).thenReturn(countResult);
-
- //Then
- Response restResponse = subject.getGroupCount(null, "false");
-
- assertEquals(response.toString(), restResponse.getEntity());
- assertEquals(MediaType.APPLICATION_JSON, restResponse.getMediaType().toString());
- }
-
- @Test
- public void testGetGroupCountWithoutSearchAndTopLevelFlagNull() {
- // Given
- Long countResult = 5L;
- JSONObject response = new JSONObject();
- try {
- response.put("count", countResult);
- } catch (JSONException e) {
- fail(e.getMessage());
- }
-
- // When
- when(realmMock.getGroupsCount(false)).thenReturn(countResult);
-
- //Then
- Response restResponse = subject.getGroupCount(null, null);
-
- assertEquals(response.toString(), restResponse.getEntity());
- assertEquals(MediaType.APPLICATION_JSON, restResponse.getMediaType().toString());
- }
-}
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 b7274ecbe3..fd58f7590a 100755
--- 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
@@ -92,7 +92,6 @@ public class GroupTest extends AbstractGroupTest {
user.setCredentials(credentials);
users.add(user);
-
List clients = testRealmRep.getClients();
ClientRepresentation client = new ClientRepresentation();
@@ -155,16 +154,16 @@ public class GroupTest extends AbstractGroupTest {
@Test
public void doNotAllowSameGroupNameAtSameLevel() throws Exception {
RealmResource realm = adminClient.realms().realm("test");
-
+
GroupRepresentation topGroup = new GroupRepresentation();
topGroup.setName("top");
topGroup = createGroup(realm, topGroup);
-
+
GroupRepresentation anotherTopGroup = new GroupRepresentation();
anotherTopGroup.setName("top");
Response response = realm.groups().add(anotherTopGroup);
assertEquals(409, response.getStatus()); // conflict status 409 - same name not allowed
-
+
GroupRepresentation level2Group = new GroupRepresentation();
level2Group.setName("level2");
response = realm.groups().group(topGroup.getId()).subGroup(level2Group);
@@ -177,7 +176,7 @@ public class GroupTest extends AbstractGroupTest {
response.close();
assertEquals(409, response.getStatus()); // conflict status 409 - same name not allowed
}
-
+
@Test
public void createAndTestGroups() throws Exception {
RealmResource realm = adminClient.realms().realm("test");
@@ -206,7 +205,7 @@ public class GroupTest extends AbstractGroupTest {
GroupRepresentation topGroup = new GroupRepresentation();
topGroup.setName("top");
topGroup = createGroup(realm, topGroup);
-
+
List roles = new LinkedList<>();
roles.add(topRole);
realm.groups().group(topGroup.getId()).roles().realmLevel().add(roles);
@@ -634,4 +633,59 @@ public class GroupTest extends AbstractGroupTest {
assertEquals(110, group.members(0, 1000).size());
assertEquals(110, group.members(-1, -2).size());
}
+
+ @Test
+ public void searchAndCountGroups() throws Exception {
+ String firstGroupId = "";
+
+ RealmResource realm = adminClient.realms().realm("test");
+
+ // Clean up all test groups
+ for (GroupRepresentation group : realm.groups().groups()) {
+ GroupResource resource = realm.groups().group(group.getId());
+ resource.remove();
+ assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupPath(group.getId()), ResourceType.GROUP);
+ }
+
+ // Add 20 new groups with known names
+ for (int i=0;i<20;i++) {
+ GroupRepresentation group = new GroupRepresentation();
+ group.setName("group"+i);
+ group = createGroup(realm, group);
+ if(i== 0) {
+ firstGroupId = group.getId();
+ }
+ }
+
+ // Get groups by search and pagination
+ List allGroups = realm.groups().groups();
+ assertEquals(20, allGroups.size());
+
+ List slice = realm.groups().groups(5, 7);
+ assertEquals(7, slice.size());
+
+ List search = realm.groups().groups("group1",0,20);
+ assertEquals(11, search.size());
+ for(GroupRepresentation group : search) {
+ assertTrue(group.getName().contains("group1"));
+ }
+
+ List noResultSearch = realm.groups().groups("abcd",0,20);
+ assertEquals(0, noResultSearch.size());
+
+ // Count
+ assertEquals(new Long(allGroups.size()), realm.groups().count().get("count"));
+ assertEquals(new Long(search.size()), realm.groups().count("group1").get("count"));
+ assertEquals(new Long(noResultSearch.size()), realm.groups().count("abcd").get("count"));
+
+ // Add a subgroup for onlyTopLevel flag testing
+ GroupRepresentation level2Group = new GroupRepresentation();
+ level2Group.setName("group1111");
+ Response response = realm.groups().group(firstGroupId).subGroup(level2Group);
+ response.close();
+ assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupSubgroupsPath(firstGroupId), level2Group, ResourceType.GROUP);
+
+ assertEquals(new Long(allGroups.size()), realm.groups().count(true).get("count"));
+ assertEquals(new Long(allGroups.size() + 1), realm.groups().count(false).get("count"));
+ }
}
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/controllers/groups.js b/themes/src/main/resources/theme/base/admin/resources/js/controllers/groups.js
index 23edb675d5..bc3691f9df 100755
--- a/themes/src/main/resources/theme/base/admin/resources/js/controllers/groups.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/controllers/groups.js
@@ -36,7 +36,7 @@ module.controller('GroupListCtrl', function($scope, $route, $q, realm, groups, g
Groups.query(queryParams, function(entry) {
promiseGetGroups.resolve(entry);
}, function() {
- promiseGetGroups.reject('Unable to fetch ' + i);
+ promiseGetGroups.reject('Unable to fetch ' + queryParams);
});
var promiseGetGroupsChain = promiseGetGroups.promise.then(function(entry) {
groups = entry;
@@ -53,14 +53,12 @@ module.controller('GroupListCtrl', function($scope, $route, $q, realm, groups, g
GroupsCount.query(countParams, function(entry) {
promiseCount.resolve(entry);
}, function() {
- promiseCount.reject('Unable to fetch ' + i);
+ promiseCount.reject('Unable to fetch ' + countParams);
});
var promiseCountChain = promiseCount.promise.then(function(entry) {
groupsCount = entry;
$scope.numberOfPages = Math.ceil(groupsCount.count/$scope.pageSize);
});
-
- $q.all([promiseGetGroupsChain, promiseCountChain]);
};
$scope.$watch('currentPage', function(newValue, oldValue) {
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/loaders.js b/themes/src/main/resources/theme/base/admin/resources/js/loaders.js
index 9b7bab3bda..fb49c64f10 100755
--- a/themes/src/main/resources/theme/base/admin/resources/js/loaders.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/loaders.js
@@ -491,7 +491,7 @@ module.factory('GroupListLoader', function(Loader, Groups, $route, $q) {
return Loader.query(Groups, function() {
return {
realm : $route.current.params.realm,
- first : 1,
+ first : 0,
max : 20
}
});
@@ -501,7 +501,7 @@ module.factory('GroupCountLoader', function(Loader, GroupsCount, $route, $q) {
return Loader.query(GroupsCount, function() {
return {
realm : $route.current.params.realm,
- top : 'true'
+ top : true
}
});
});