package com.constellio.model.services.users;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Fail.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyList;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import com.constellio.data.dao.services.factories.DataLayerFactory;
import com.constellio.data.dao.services.idGenerator.UUIDV1Generator;
import com.constellio.data.dao.services.idGenerator.UniqueIdGenerator;
import com.constellio.model.conf.ModelLayerConfiguration;
import com.constellio.model.conf.ldap.LDAPConfigurationManager;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.Transaction;
import com.constellio.model.entities.records.wrappers.Group;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.entities.schemas.Metadata;
import com.constellio.model.entities.schemas.MetadataSchema;
import com.constellio.model.entities.schemas.MetadataSchemaType;
import com.constellio.model.entities.schemas.MetadataSchemaTypes;
import com.constellio.model.entities.security.global.GlobalGroup;
import com.constellio.model.entities.security.global.GlobalGroupStatus;
import com.constellio.model.entities.security.global.UserCredential;
import com.constellio.model.entities.security.global.UserCredentialStatus;
import com.constellio.model.entities.security.global.XmlGlobalGroup;
import com.constellio.model.services.collections.CollectionsListManager;
import com.constellio.model.services.factories.ModelLayerFactory;
import com.constellio.model.services.records.RecordServices;
import com.constellio.model.services.schemas.MetadataSchemasManager;
import com.constellio.model.services.search.SearchServices;
import com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators;
import com.constellio.model.services.search.query.logical.condition.LogicalSearchCondition;
import com.constellio.model.services.security.authentification.AuthenticationService;
import com.constellio.model.services.security.roles.Roles;
import com.constellio.model.services.security.roles.RolesManager;
import com.constellio.model.services.users.UserServicesRuntimeException.UserServicesRuntimeException_UserIsNotInCollection;
import com.constellio.sdk.tests.ConstellioTest;
public class UserServicesUnitTest extends ConstellioTest {
@Mock MetadataSchemasManager metadataSchemasManager;
@Mock MetadataSchemaTypes collection1Types;
@Mock MetadataSchema collection1UserSchema;
@Mock MetadataSchema collection1GroupSchema;
@Mock Metadata collection1UsernameMetadata;
@Mock Metadata collection1UserGroupsMetadata;
@Mock Metadata collection1GroupCodeMetadata;
@Mock MetadataSchemaType collection1UserType;
@Mock MetadataSchemaType collection1GroupType;
@Mock MetadataSchemaTypes collection2Types;
@Mock MetadataSchema collection2UserSchema;
@Mock MetadataSchema collection2GroupSchema;
@Mock Metadata collection2UsernameMetadata;
@Mock Metadata collection2UserGroupsMetadata;
@Mock Metadata collection2GroupCodeMetadata;
@Mock UserCredentialsManager userCredentialsManager;
@Mock XmlGlobalGroupsManager globalGroupsManager;
@Mock CollectionsListManager collectionsListManager;
@Mock RecordServices recordServices;
@Mock SearchServices searchServices;
@Mock AuthenticationService authenticationService;
@Mock ModelLayerConfiguration modelLayerConfiguration;
@Mock LDAPConfigurationManager configurationManager;
UserServices userServices;
@Mock UserCredential admin, alice, bob;
@Mock GlobalGroup legends, heroes;
@Mock Record userRecord, groupRecord;
@Mock User bobRecordInCollection1, bobRecordInCollection2;
@Mock Record bobRecordInCollection1Record, bobRecordInCollection2Record;
@Mock ModelLayerFactory modelLayerFactory;
@Mock DataLayerFactory dataLayerFactory;
UniqueIdGenerator uniqueIdGenerator = new UUIDV1Generator();
@Mock Group legendsInCollection1, legendsInCollection2;
@Mock Record legendsInCollection1Record, legendsInCollection2Record;
@Mock RolesManager rolesManager;
@Mock Roles roles;
@Before
public void setUp()
throws Exception {
when(rolesManager.getCollectionRoles(zeCollection)).thenReturn(roles);
when(modelLayerFactory.getDataLayerFactory()).thenReturn(dataLayerFactory);
when(dataLayerFactory.getSecondaryUniqueIdGenerator()).thenReturn(uniqueIdGenerator);
when(modelLayerFactory.getUserCredentialsManager()).thenReturn(userCredentialsManager);
when(modelLayerFactory.getGlobalGroupsManager()).thenReturn(globalGroupsManager);
when(modelLayerFactory.getCollectionsListManager()).thenReturn(collectionsListManager);
when(modelLayerFactory.newRecordServices()).thenReturn(recordServices);
when(modelLayerFactory.newSearchServices()).thenReturn(searchServices);
when(modelLayerFactory.getMetadataSchemasManager()).thenReturn(metadataSchemasManager);
when(modelLayerFactory.newAuthenticationService()).thenReturn(authenticationService);
when(modelLayerFactory.getRolesManager()).thenReturn(rolesManager);
when(modelLayerFactory.getConfiguration()).thenReturn(modelLayerConfiguration);
when(modelLayerFactory.getLdapConfigurationManager()).thenReturn(configurationManager);
userServices = spy(new UserServices(modelLayerFactory));
doReturn("group1Collection1Id").when(userServices).getGroupIdInCollection("group1", "collection1");
doReturn("group2Collection1Id").when(userServices).getGroupIdInCollection("group2", "collection1");
doReturn("group1Collection2Id").when(userServices).getGroupIdInCollection("group1", "collection2");
doReturn("group2Collection2Id").when(userServices).getGroupIdInCollection("group2", "collection2");
when(admin.getUsername()).thenReturn("admin");
when(admin.getStatus()).thenReturn(UserCredentialStatus.ACTIVE);
when(alice.getUsername()).thenReturn("alice");
when(alice.getStatus()).thenReturn(UserCredentialStatus.ACTIVE);
when(bob.getUsername()).thenReturn("bob");
when(bob.getStatus()).thenReturn(UserCredentialStatus.ACTIVE);
when(legends.getCode()).thenReturn("legends");
when(heroes.getCode()).thenReturn("heroes");
when(userRecord.getSchemaCode()).thenReturn("user_default");
when(bobRecordInCollection1.getSchemaCode()).thenReturn("user_default");
when(bobRecordInCollection2.getSchemaCode()).thenReturn("user_default");
when(bobRecordInCollection1.getCollection()).thenReturn("collection1");
when(bobRecordInCollection2.getCollection()).thenReturn("collection2");
when(legendsInCollection1.getSchemaCode()).thenReturn("group_default");
when(legendsInCollection2.getSchemaCode()).thenReturn("group_default");
when(legendsInCollection1.getCollection()).thenReturn("collection1");
when(legendsInCollection2.getCollection()).thenReturn("collection2");
when(groupRecord.getSchemaCode()).thenReturn("group_default");
when(metadataSchemasManager.getSchemaTypes("collection1")).thenReturn(collection1Types);
when(collection1Types.getSchema("user_default")).thenReturn(collection1UserSchema);
when(collection1Types.getSchema("group_default")).thenReturn(collection1GroupSchema);
when(collection1UserSchema.getCode()).thenReturn("user_default");
when(collection1GroupSchema.getCode()).thenReturn("group_default");
when(collection1UserSchema.getCollection()).thenReturn("collection1");
when(collection1GroupSchema.getCollection()).thenReturn("collection1");
when(collection1UserSchema.getMetadata(User.USERNAME)).thenReturn(collection1UsernameMetadata);
when(collection1UserSchema.getMetadata(User.GROUPS)).thenReturn(collection1UserGroupsMetadata);
when(collection1GroupSchema.getMetadata(Group.CODE)).thenReturn(collection1GroupCodeMetadata);
when(metadataSchemasManager.getSchemaTypes("collection2")).thenReturn(collection2Types);
when(collection2Types.getSchema("user_default")).thenReturn(collection2UserSchema);
when(collection2Types.getSchema("group_default")).thenReturn(collection2GroupSchema);
when(collection2UserSchema.getCode()).thenReturn("user_default");
when(collection2GroupSchema.getCode()).thenReturn("group_default");
when(collection2UserSchema.getCollection()).thenReturn("collection2");
when(collection2GroupSchema.getCollection()).thenReturn("collection2");
when(collection2UserSchema.getMetadata(User.USERNAME)).thenReturn(collection2UsernameMetadata);
when(collection2UserSchema.getMetadata(User.GROUPS)).thenReturn(collection2UserGroupsMetadata);
when(collection2GroupSchema.getMetadata(Group.CODE)).thenReturn(collection2GroupCodeMetadata);
when(bobRecordInCollection1.getCollection()).thenReturn("collection1");
when(bobRecordInCollection2.getCollection()).thenReturn("collection2");
when(bobRecordInCollection1.getWrappedRecord()).thenReturn(bobRecordInCollection1Record);
when(bobRecordInCollection2.getWrappedRecord()).thenReturn(bobRecordInCollection2Record);
when(bobRecordInCollection1Record.getCollection()).thenReturn("collection1");
when(bobRecordInCollection2Record.getCollection()).thenReturn("collection2");
when(legendsInCollection1.getCollection()).thenReturn("collection1");
when(legendsInCollection2.getCollection()).thenReturn("collection2");
when(legendsInCollection1.getWrappedRecord()).thenReturn(legendsInCollection1Record);
when(legendsInCollection2.getWrappedRecord()).thenReturn(legendsInCollection2Record);
when(legendsInCollection1Record.getCollection()).thenReturn("collection1");
when(legendsInCollection2Record.getCollection()).thenReturn("collection2");
doReturn(collection1GroupSchema).when(userServices).groupSchema("collection1");
doReturn(collection1UserSchema).when(userServices).userSchema("collection1");
doReturn(collection2GroupSchema).when(userServices).groupSchema("collection2");
doReturn(collection2UserSchema).when(userServices).userSchema("collection2");
}
@Test
public void whenGetUserThenReturnHim()
throws Exception {
when(userCredentialsManager.getUserCredential("bob")).thenReturn(bob);
assertThat(userServices.getUser("bob")).isSameAs(bob);
}
@Test
public void whenGetGroupThenReturnIt()
throws Exception {
when(globalGroupsManager.getGlobalGroupWithCode("legends")).thenReturn(legends);
assertThat(userServices.getGroup("legends")).isSameAs(legends);
}
@Test
public void whenGeActiveGroupThenOk()
throws Exception {
when(globalGroupsManager.getGlobalGroupWithCode("legends")).thenReturn(legends);
when(globalGroupsManager.getGlobalGroupWithCode("heroes")).thenReturn(heroes);
when(globalGroupsManager.getActiveGlobalGroupWithCode("heroes")).thenReturn(null);
when(globalGroupsManager.getActiveGlobalGroupWithCode("legends")).thenReturn(legends);
when(legends.getStatus()).thenReturn(GlobalGroupStatus.ACTIVE);
when(heroes.getStatus()).thenReturn(GlobalGroupStatus.INACTIVE);
assertThat(userServices.getGroup("legends")).isSameAs(legends);
assertThat(userServices.getActiveGroup("legends")).isSameAs(legends);
try {
userServices.getActiveGroup("heroes");
} catch (Exception e) {
assertThat(e.getMessage()).isEqualTo("No such group 'heroes'");
}
}
@Test
public void whenGetGroupInCollectionThenReturnRecordOfCorrectCollection()
throws Exception {
when(bob.getCollections()).thenReturn(Arrays.asList("collection2", "collection1"));
when(globalGroupsManager.getGlobalGroupWithCode("legends")).thenReturn(legends);
ArgumentCaptor<LogicalSearchCondition> conditionCaptor = ArgumentCaptor.forClass(LogicalSearchCondition.class);
when(searchServices.searchSingleResult(conditionCaptor.capture())).thenReturn(groupRecord);
Group returnedGroup = userServices.getGroupInCollection("legends", "collection2");
assertThat(returnedGroup.getWrappedRecord()).isSameAs(groupRecord);
LogicalSearchCondition condition = conditionCaptor.getValue();
assertThat(condition).isEqualTo(
LogicalSearchQueryOperators.from(collection2GroupSchema).where(collection2GroupCodeMetadata).is("legends"));
}
@Test
public void whenGetUserInInvalidCollectionThenException()
throws Exception {
when(bob.getCollections()).thenReturn(Arrays.asList("collection2"));
when(userCredentialsManager.getUserCredential("bob")).thenReturn(bob);
try {
userServices.getUserInCollection("bob", "collection1");
fail("UserServicesRuntimeException_UserIsNotInCollection expected");
} catch (UserServicesRuntimeException_UserIsNotInCollection e) {
// OK
}
verifyZeroInteractions(searchServices);
}
@Test
public void whenAddUpdateUserThenAddUpdateInManagerAndSync()
throws Exception {
doNothing().when(userServices).sync(bob);
userServices.addUpdateUserCredential(bob);
InOrder inOrder = inOrder(userServices, userCredentialsManager);
inOrder.verify(userCredentialsManager).addUpdate(bob);
inOrder.verify(userServices).sync(bob);
}
@Test
public void whenAddUpdateGroupThenAddUpdateInManagerAndSync()
throws Exception {
doNothing().when(userServices).sync(legends);
userServices.addUpdateGlobalGroup(legends);
InOrder inOrder = inOrder(userServices, globalGroupsManager);
inOrder.verify(globalGroupsManager).addUpdate(legends);
inOrder.verify(userServices).sync(legends);
}
//@Test
public void RecordwhenSyncUserThenAddUserToHisNewCollections()
throws Exception {
when(bob.getStatus()).thenReturn(UserCredentialStatus.ACTIVE);
when(bob.getCollections()).thenReturn(Arrays.asList("collection1", "collection2"));
when(bob.getGlobalGroups()).thenReturn(Arrays.asList("group1", "group2"));
doReturn(bobRecordInCollection1).when(userServices).getUserInCollection("bob", "collection1");
doReturn(null).when(userServices).getUserInCollection("bob", "collection2");
when(bobRecordInCollection1.getUserGroups()).thenReturn(Arrays.asList("group2Collection1Id", "group1Collection1Id"));
doReturn(bobRecordInCollection2).when(userServices).newUserInCollection("collection2");
when(bobRecordInCollection1.isDirty()).thenReturn(false);
when(bobRecordInCollection2.isDirty()).thenReturn(true);
userServices.sync(bob);
ArgumentCaptor<Transaction> transactionArgumentCaptor = ArgumentCaptor.forClass(Transaction.class);
verify(bobRecordInCollection1, never()).setUserGroups(anyList());
InOrder inOrder = inOrder(bobRecordInCollection2, recordServices);
inOrder.verify(recordServices, times(2)).execute(transactionArgumentCaptor.capture());
Transaction transaction = transactionArgumentCaptor.getValue();
assertThat(transaction.getRecords()).hasSize(1);
assertThat(transaction.getRecords().get(0)).isSameAs(bobRecordInCollection2Record);
}
//@Test
public void whenSyncUserThenAddUserToHisNewGroups()
throws Exception {
when(bob.getCollections()).thenReturn(Arrays.asList("collection1", "collection2"));
when(bob.getGlobalGroups()).thenReturn(Arrays.asList("group1", "group2"));
when(bob.getStatus()).thenReturn(UserCredentialStatus.ACTIVE);
doReturn(bobRecordInCollection1).when(userServices).getUserInCollection("bob", "collection1");
doReturn(bobRecordInCollection2).when(userServices).getUserInCollection("bob", "collection2");
when(bobRecordInCollection1.getUserGroups()).thenReturn(Arrays.asList("group2Collection1Id", "group1Collection1Id"));
when(bobRecordInCollection2.getUserGroups()).thenReturn(Arrays.asList("group1Collection2Id"));
when(bobRecordInCollection1.isDirty()).thenReturn(false);
when(bobRecordInCollection2.isDirty()).thenReturn(true);
userServices.sync(bob);
ArgumentCaptor<Transaction> transactionArgumentCaptor = ArgumentCaptor.forClass(Transaction.class);
verify(bobRecordInCollection1, never()).setUserGroups(anyList());
InOrder inOrder = inOrder(bobRecordInCollection2, recordServices);
inOrder.verify(bobRecordInCollection2).setUserGroups(Arrays.asList("group1Collection2Id", "group2Collection2Id"));
inOrder.verify(recordServices, times(1)).execute(transactionArgumentCaptor.capture());
Transaction transaction = transactionArgumentCaptor.getValue();
assertThat(transaction.getRecords()).hasSize(1);
assertThat(transaction.getRecords().get(0)).isSameAs(bobRecordInCollection2Record);
}
@Test
public void whenSyncGroupThenAddToHisNewCollections()
throws Exception {
when(collectionsListManager.getCollections()).thenReturn(Arrays.asList("collection1", "collection2"));
doReturn(legendsInCollection1).when(userServices).getGroupInCollection("legends", "collection1");
doReturn(null).when(userServices).getGroupInCollection("legends", "collection2");
doReturn(legendsInCollection2).when(userServices).newGroupInCollection("collection2");
when(legendsInCollection1.isDirty()).thenReturn(false);
when(legendsInCollection2.isDirty()).thenReturn(true);
userServices.sync(legends);
ArgumentCaptor<Transaction> transactionArgumentCaptor = ArgumentCaptor.forClass(Transaction.class);
verify(recordServices, times(2)).execute(transactionArgumentCaptor.capture());
Transaction transaction = transactionArgumentCaptor.getValue();
assertThat(transaction.getRecords()).hasSize(1);
assertThat(transaction.getRecords().get(0)).isSameAs(legendsInCollection2Record);
}
@Test
public void whenAddGroupsToCollectionsThenSyncAllOfThem()
throws Exception {
when(globalGroupsManager.getActiveGroups()).thenReturn(Arrays.asList(legends, heroes));
doNothing().when(userServices).sync(any(XmlGlobalGroup.class));
userServices.addGlobalGroupsInCollection("collection1");
verify(userServices).sync(legends);
verify(userServices).sync(heroes);
}
@Test
public void whenGetUserCredentialsThenOk()
throws Exception {
userServices.getActiveUserCredentials();
verify(userCredentialsManager).getActiveUserCredentials();
}
//
@Test
public void givenLDAPAuthenticationAndSyncWhenCanModifyUserAndGroupThenFalse()
throws Exception {
when(configurationManager.isLDAPAuthentication()).thenReturn(true);
when(configurationManager.idUsersSynchActivated()).thenReturn(true);
assertThat(userServices.canAddOrModifyUserAndGroup()).isFalse();
}
@Test
public void givenLDAPAuthenticationAndNotSyncWhenCanModifyUserAndGroupThenTrue()
throws Exception {
when(configurationManager.isLDAPAuthentication()).thenReturn(true);
when(configurationManager.idUsersSynchActivated()).thenReturn(false);
assertThat(userServices.canAddOrModifyUserAndGroup()).isTrue();
}
@Test
public void givenNotLDAPAuthenticationAndSyncWhenCanModifyUserAndGroupThenTrue()
throws Exception {
when(configurationManager.isLDAPAuthentication()).thenReturn(false);
when(configurationManager.idUsersSynchActivated()).thenReturn(true);
assertThat(userServices.canAddOrModifyUserAndGroup()).isTrue();
}
@Test
public void givenNotLDAPAuthenticationAndNotSyncWhenCanModifyUserAndGroupThenTrue()
throws Exception {
when(configurationManager.isLDAPAuthentication()).thenReturn(false);
when(configurationManager.idUsersSynchActivated()).thenReturn(false);
assertThat(userServices.canAddOrModifyUserAndGroup()).isTrue();
}
//
@Test
public void givenLDPADAuthAndCurrentUserAdminWhenCanModifyHimSelfPasswordThenTrue()
throws Exception {
when(configurationManager.isLDAPAuthentication()).thenReturn(true);
assertThat(userServices.canModifyPassword(admin, admin)).isTrue();
}
@Test
public void givenLDPADAuthAndCurrentUserAdminWhenCanModifyAlicesPasswordThenFalse()
throws Exception {
when(configurationManager.isLDAPAuthentication()).thenReturn(true);
assertThat(userServices.canModifyPassword(admin, alice)).isFalse();
}
@Test
public void givenLDPADAuthAndCurrentUserAliceWhenCanModifyPasswordThenFalse()
throws Exception {
when(configurationManager.isLDAPAuthentication()).thenReturn(true);
assertThat(userServices.canModifyPassword(alice, alice)).isFalse();
}
@Test
public void givenNotLDPADAuthAndCurrentUserAliceWhenCanModifyPasswordThenTrue()
throws Exception {
when(configurationManager.isLDAPAuthentication()).thenReturn(false);
assertThat(userServices.canModifyPassword(alice, alice)).isTrue();
}
@Test
public void whenIsLDAPAuthenticationThenOk()
throws Exception {
when(configurationManager.isLDAPAuthentication()).thenReturn(false).thenReturn(true);
assertThat(userServices.isLDAPAuthentication()).isFalse();
assertThat(userServices.isLDAPAuthentication()).isTrue();
}
}