KEYCLOAK 2538 - UI group pagination - TU + some code improvement + add mockito dependency

This commit is contained in:
Levente NAGY 2017-09-12 15:09:08 +02:00
parent db56d82dbd
commit c8c88dd58c
7 changed files with 469 additions and 20 deletions

View file

@ -111,6 +111,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View file

@ -0,0 +1,218 @@
/*
* 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 <a href="mailto:levente.nagy@itesoft.com">NAGY Léventé</a>
* @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<GroupModel>) 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<Long> 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<Long> 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<String> result = Arrays.asList("idGroup1", "idGroup2", "idGroup3");
String idRealm = "idGroup";
TypedQuery<String> 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<GroupModel> searchResult = subject.searchForGroupByName(realmModelMock, search, first, max);
assertEquals(result.size(), searchResult.size());
}
@Test
public void testSearchForGroupByNameWithNullQueryResult() {
// Given
String idRealm = "idGroup";
TypedQuery<String> 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<GroupModel> searchResult = subject.searchForGroupByName(realmModelMock, search, null, null);
assertEquals(Collections.EMPTY_LIST, searchResult);
}
@Test
public void testSearchForGroupByNameWithNonTopLevelGroupInQueryResult() {
// Given
List<String> result = Arrays.asList("idGroup1", "idGroup2", "idGroup3", "idGroup4");
String idRealm = "idGroup";
TypedQuery<String> 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<GroupModel>) 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<GroupModel> searchResult = subject.searchForGroupByName(realmModelMock, search, first, max);
assertEquals(3,searchResult.size());
}
@Test
public void testGetGroupsCountByNameContaining() {
// Given
List<String> result = Arrays.asList("idGroup1", "idGroup2", "idGroup3", "idGroup4");
String idRealm = "idGroup";
TypedQuery<String> 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());
}
}

View file

@ -108,6 +108,7 @@
<hamcrest.version>1.3</hamcrest.version>
<jmeter.version>2.10</jmeter.version>
<junit.version>4.12</junit.version>
<mockito.version>1.9.5</mockito.version>
<picketlink.version>2.7.0.Final</picketlink.version>
<selenium.version>2.35.0</selenium.version>
<xml-apis.version>1.4.01</xml-apis.version>
@ -367,6 +368,12 @@
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
<version>${mockito.version}</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>

View file

@ -76,12 +76,7 @@ public class ModelToRepresentation {
} else {
ClientModel client = (ClientModel)role.getContainer();
String clientId = client.getClientId();
List<String> currentClientRoles = clientRoleNames.get(clientId);
if (currentClientRoles == null) {
currentClientRoles = new ArrayList<>();
clientRoleNames.put(clientId, currentClientRoles);
}
List<String> currentClientRoles = clientRoleNames.computeIfAbsent(clientId, k -> new ArrayList<>());
currentClientRoles.add(role.getName());
}
}
@ -153,9 +148,7 @@ public class ModelToRepresentation {
List<String> reqActions = new ArrayList<String>();
Set<String> requiredActions = user.getRequiredActions();
for (String ra : requiredActions){
reqActions.add(ra);
}
reqActions.addAll(requiredActions);
rep.setRequiredActions(reqActions);
@ -609,11 +602,7 @@ public class ModelToRepresentation {
Map<String, List<String>> grantedProtocolMappers = new HashMap<String, List<String>>();
for (ProtocolMapperModel protocolMapper : model.getGrantedProtocolMappers()) {
String protocol = protocolMapper.getProtocol();
List<String> currentProtocolMappers = grantedProtocolMappers.get(protocol);
if (currentProtocolMappers == null) {
currentProtocolMappers = new LinkedList<String>();
grantedProtocolMappers.put(protocol, currentProtocolMappers);
}
List<String> currentProtocolMappers = grantedProtocolMappers.computeIfAbsent(protocol, k -> new LinkedList<String>());
currentProtocolMappers.add(protocolMapper.getName());
}
@ -626,11 +615,7 @@ public class ModelToRepresentation {
ClientModel client2 = (ClientModel) role.getContainer();
String clientId2 = client2.getClientId();
List<String> currentClientRoles = grantedClientRoles.get(clientId2);
if (currentClientRoles == null) {
currentClientRoles = new LinkedList<String>();
grantedClientRoles.put(clientId2, currentClientRoles);
}
List<String> currentClientRoles = grantedClientRoles.computeIfAbsent(clientId2, k -> new LinkedList<String>());
currentClientRoles.add(role.getName());
}
}

View file

@ -180,6 +180,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View file

@ -126,7 +126,6 @@ public class GroupsResource {
try {
response.put("count", results);
} catch (JSONException e) {
e.printStackTrace();
return ErrorResponse.error("Cannot create response object", Response.Status.INTERNAL_SERVER_ERROR);
}
return Response.ok(response.toString(), MediaType.APPLICATION_JSON).build();

View file

@ -0,0 +1,230 @@
/*
* 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 <a href="mailto:levente.nagy@itesoft.com">NAGY Léventé</a>
* @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<GroupModel> 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<GroupRepresentation> 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<GroupModel> 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<GroupRepresentation> 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<GroupModel> 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<GroupRepresentation> 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());
}
}