/* * Copyright (C) 2007-2014 Crafter Software Corporation. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.craftercms.profile.services.impl; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.bson.types.ObjectId; import org.craftercms.commons.collections.SetUtils; import org.craftercms.commons.security.permissions.PermissionEvaluator; import org.craftercms.profile.api.AccessToken; import org.craftercms.profile.api.AttributeDefinition; import org.craftercms.profile.api.AttributePermission; import org.craftercms.profile.api.Profile; import org.craftercms.profile.api.ProfileConstants; import org.craftercms.profile.api.Tenant; import org.craftercms.profile.api.services.ProfileService; import org.craftercms.profile.repositories.ProfileRepository; import org.craftercms.profile.repositories.TenantRepository; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * Unit tests for {@link org.craftercms.profile.services.impl.TenantServiceImpl}. * * @author avasquez */ public class TenantServiceImplTest { private static final String LABEL_KEY = "label"; private static final ObjectId TENANT1_ID = new ObjectId(); private static final ObjectId TENANT2_ID = new ObjectId(); private static final String TENANT1_NAME = "tenant1"; private static final String TENANT2_NAME = "tenant2"; private static final String ROLE1 = "role1"; private static final String ROLE2 = "role2"; private static final String ATTRIB1_NAME = "attrib1"; private static final String ATTRIB1_LABEL = "Attribute #1"; private static final String ATTRIB2_NAME = "attrib2"; private static final String ATTRIB2_LABEL = "Attribute #2"; private static final Object DEFAULT_ATTRIB_VALUE = "test"; private static final String APP_NAME = "app"; private TenantServiceImpl tenantService; @Mock private PermissionEvaluator<AccessToken, String> permissionEvaluator; @Mock private TenantRepository tenantRepository; @Mock private ProfileRepository profileRepository; @Mock private ProfileService profileService; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(permissionEvaluator.isAllowed(anyString(), anyString())) .thenReturn(true); when(tenantRepository.findByName(TENANT1_NAME)) .thenReturn(getTenant1()); when(tenantRepository.findByName(TENANT2_NAME)) .thenReturn(getTenant2()); when(tenantRepository.findAll()) .thenReturn(Arrays.asList(getTenant1(), getTenant2())); when(tenantRepository.count()) .thenReturn(2L); when(profileService.getProfilesByRole(TENANT2_NAME, ROLE1, null, null, ProfileConstants.NO_ATTRIBUTE)) .thenReturn(Arrays.asList(mock(Profile.class))); when(profileService.getProfilesByExistingAttribute(TENANT2_NAME, ATTRIB1_NAME, null, null, ProfileConstants.NO_ATTRIBUTE)) .thenReturn(Arrays.asList(mock(Profile.class))); tenantService = new TenantServiceImpl(); tenantService.setTenantPermissionEvaluator(permissionEvaluator); tenantService.setTenantRepository(tenantRepository); tenantService.setProfileService(profileService); tenantService.setProfileRepository(profileRepository); } @Test public void testCreateTenant() throws Exception { Tenant actual = tenantService.createTenant(getTenant1()); Tenant expected = getTenant1(); assertEqualTenants(expected, actual); verify(tenantRepository).insert(actual); } @Test public void testGetTenant() throws Exception { Tenant actual = tenantService.getTenant(TENANT1_NAME); Tenant expected = getTenant1(); assertEqualTenants(expected, actual); verify(tenantRepository).findByName(TENANT1_NAME); } @Test public void testUpdateTenant() throws Exception { AttributeDefinition def1 = new AttributeDefinition(); def1.setName(ATTRIB1_NAME); AttributeDefinition def2 = new AttributeDefinition(); def2.setName(ATTRIB2_NAME); def2.setDefaultValue(DEFAULT_ATTRIB_VALUE); Tenant expected = getTenant1(); expected.getAvailableRoles().remove(ROLE1); expected.getAttributeDefinitions().remove(def1); expected.getAttributeDefinitions().add(def2); Map<String, Object> expectedSetParams = new HashMap<>(); expectedSetParams.put("verifyNewProfiles", expected.isVerifyNewProfiles()); expectedSetParams.put("availableRoles", expected.getAvailableRoles()); expectedSetParams.put("ssoEnabled", expected.isSsoEnabled()); expectedSetParams.put("attributeDefinitions", expected.getAttributeDefinitions()); Tenant actual = tenantService.updateTenant(expected); assertEqualTenants(expected, actual); verify(profileRepository).removeRoleFromAll(TENANT1_NAME, ROLE1); verify(profileRepository).removeAttributeFromAll(TENANT1_NAME, ATTRIB1_NAME); verify(profileRepository).updateAllWithDefaultValue(TENANT1_NAME, ATTRIB2_NAME, DEFAULT_ATTRIB_VALUE); verify(tenantRepository).update(TENANT1_ID.toString(), "{$set: #}", false, false, expectedSetParams); } @Test public void testDeleteTenant() throws Exception { tenantService.deleteTenant(TENANT1_NAME); verify(profileRepository).removeAll(TENANT1_NAME); verify(tenantRepository).removeByName(TENANT1_NAME); } @Test public void testGetTenantCount() throws Exception { long expected = 2L; long actual = tenantService.getTenantCount(); assertEquals(expected, actual); verify(tenantRepository).count(); } @Test public void testGetAllTenants() throws Exception { List<Tenant> expected = Arrays.asList(getTenant1(), getTenant2()); List<Tenant> actual = tenantService.getAllTenants(); assertNotNull(actual); assertEquals(2, actual.size()); assertEqualTenants(expected.get(0), actual.get(0)); assertEqualTenants(expected.get(1), actual.get(1)); verify(tenantRepository).findAll(); } @Test public void testVerifyNewProfiles() throws Exception { Tenant expected = getTenant1(); expected.setVerifyNewProfiles(false); Map<String, Object> expectedSetParams = new HashMap<>(); expectedSetParams.put("verifyNewProfiles", expected.isVerifyNewProfiles()); Tenant actual = tenantService.verifyNewProfiles(TENANT1_NAME, false); assertEqualTenants(expected, actual); verify(tenantRepository).findByName(TENANT1_NAME); verify(tenantRepository).update(TENANT1_ID.toString(), "{$set: #}", false, false, expectedSetParams); } @Test public void testAddAvailableRoles() throws Exception { Tenant expected = getTenant1(); expected.getAvailableRoles().add(ROLE2); List<String> rolesToAdd = Collections.singletonList(ROLE2); Map<String, Object> expectedPushParams = new HashMap<>(); expectedPushParams.put("availableRoles", Collections.singletonMap("$each", rolesToAdd)); Tenant actual = tenantService.addRoles(TENANT1_NAME, rolesToAdd); assertEqualTenants(expected, actual); verify(tenantRepository).findByName(TENANT1_NAME); verify(tenantRepository).update(TENANT1_ID.toString(), "{$push: #}", false, false, expectedPushParams); } @Test public void testRemoveAvailableRoles() throws Exception { Tenant expected = getTenant1(); expected.getAvailableRoles().remove(ROLE1); List<String> rolesToRemove = Collections.singletonList(ROLE1); Map<String, Object> expectedPullParams = new HashMap<>(); expectedPullParams.put("availableRoles", Collections.singletonMap("$in", rolesToRemove)); Tenant actual = tenantService.removeRoles(TENANT1_NAME, rolesToRemove); assertEqualTenants(expected, actual); verify(profileRepository).removeRoleFromAll(TENANT1_NAME, ROLE1); verify(tenantRepository).findByName(TENANT1_NAME); verify(tenantRepository).update(TENANT1_ID.toString(), "{$pull: #}", false, false, expectedPullParams); } @Test public void testAddAttributeDefinitions() throws Exception { AttributeDefinition def = getAttribute2Definition(); List<AttributeDefinition> defsToAdd = Collections.singletonList(def); Tenant expected = getTenant1(); expected.getAttributeDefinitions().add(def); Map<String, Object> expectedPushParams = new HashMap<>(); expectedPushParams.put("attributeDefinitions", Collections.singletonMap("$each", defsToAdd)); Tenant actual = tenantService.addAttributeDefinitions(TENANT1_NAME, defsToAdd); assertEqualTenants(expected, actual); verify(profileRepository).updateAllWithDefaultValue(TENANT1_NAME, ATTRIB2_NAME, DEFAULT_ATTRIB_VALUE); verify(tenantRepository).findByName(TENANT1_NAME); verify(tenantRepository).update(TENANT1_ID.toString(), "{$push: #}", false, false, expectedPushParams); } @Test public void testUpdateAttributeDefinitions() throws Exception { AttributeDefinition def = getAttribute2Definition(); def.setName(ATTRIB1_NAME); Tenant expected = getTenant1(); expected.getAttributeDefinitions().clear(); expected.getAttributeDefinitions().add(def); Map<String, Object> expectedSetParams = new HashMap<>(); expectedSetParams.put("attributeDefinitions.0", def); Tenant actual = tenantService.updateAttributeDefinitions(TENANT1_NAME, Collections.singletonList(def)); assertEqualTenants(expected, actual); verify(tenantRepository).findByName(TENANT1_NAME); verify(tenantRepository).update(TENANT1_ID.toString(), "{$set: #}", false, false, expectedSetParams); } @Test public void testRemoveAttributeDefinitions() throws Exception { Tenant expected = getTenant1(); expected.getAttributeDefinitions().clear(); Map<String, String> defNameValuePair = Collections.singletonMap("name", ATTRIB1_NAME); Map<String, Object> expectedPullParams = new HashMap<>(); expectedPullParams.put("attributeDefinitions", Collections.singletonMap("$in", Collections.singletonList(defNameValuePair))); Tenant actual = tenantService.removeAttributeDefinitions(TENANT1_NAME, Collections.singletonList(ATTRIB1_NAME)); assertEqualTenants(expected, actual); verify(tenantRepository).findByName(TENANT1_NAME); verify(tenantRepository).update(TENANT1_ID.toString(), "{$pull: #}", false, false, expectedPullParams); } private Tenant getTenant1() { Tenant tenant = new Tenant(); tenant.setId(TENANT1_ID); tenant.setName(TENANT1_NAME); tenant.setVerifyNewProfiles(true); tenant.setAvailableRoles(SetUtils.asSet(ROLE1)); tenant.setAttributeDefinitions(new ArrayList<>(Collections.singletonList(getAttribute1Definition()))); return tenant; } private Tenant getTenant2() { Tenant tenant = new Tenant(); tenant.setId(TENANT2_ID); tenant.setName(TENANT2_NAME); tenant.setVerifyNewProfiles(true); tenant.setAvailableRoles(SetUtils.asSet(ROLE1, ROLE2)); tenant.setAttributeDefinitions(new ArrayList<>(Collections.singletonList(getAttribute1Definition()))); return tenant; } private AttributeDefinition getAttribute1Definition() { AttributePermission permission = new AttributePermission(); permission.allow(AttributePermission.ANY_ACTION); AttributeDefinition def = new AttributeDefinition(); def.setName(ATTRIB1_NAME); def.setMetadata(Collections.<String, Object>singletonMap(LABEL_KEY, ATTRIB1_LABEL)); def.addPermission(permission); return def; } private AttributeDefinition getAttribute2Definition() { AttributePermission permission = new AttributePermission(APP_NAME); permission.allow(AttributePermission.ANY_ACTION); AttributeDefinition def = new AttributeDefinition(); def.setName(ATTRIB2_NAME); def.setMetadata(Collections.<String, Object>singletonMap(LABEL_KEY, ATTRIB2_LABEL)); def.addPermission(permission); def.setDefaultValue(DEFAULT_ATTRIB_VALUE); return def; } private void assertEqualTenants(Tenant expected, Tenant actual) { assertNotNull(actual); assertEquals(expected.getName(), actual.getName()); assertEquals(expected.isVerifyNewProfiles(), actual.isVerifyNewProfiles()); assertEquals(expected.getAvailableRoles(), actual.getAvailableRoles()); assertEqualAttributeDefinitions(expected.getAttributeDefinitions(), actual.getAttributeDefinitions()); } private void assertEqualAttributeDefinitions(List<AttributeDefinition> expected, List<AttributeDefinition> actual) { assertNotNull(expected); assertEquals(expected.size(), actual.size()); Iterator<AttributeDefinition> expectedIter = expected.iterator(); Iterator<AttributeDefinition> actualIter = actual.iterator(); while (expectedIter.hasNext()) { AttributeDefinition expectedDefinition = expectedIter.next(); AttributeDefinition actualDefinition = actualIter.next(); assertEqualAttributeDefinitions(expectedDefinition, actualDefinition); } } private void assertEqualAttributeDefinitions(AttributeDefinition expected, AttributeDefinition actual) { List<AttributePermission> expectedPermissions = expected.getPermissions(); List<AttributePermission> actualPermissions = actual.getPermissions(); assertEquals(expected.getName(), actual.getName()); assertEquals(expected.getMetadata(), actual.getMetadata()); assertNotNull(actualPermissions); assertEquals(expectedPermissions.size(), actualPermissions.size()); for (int i = 0; i < expectedPermissions.size(); i++) { AttributePermission expectedPermission = expectedPermissions.get(i); AttributePermission actualPermission = actualPermissions.get(i); assertEquals(expectedPermission.getApplication(), actualPermission.getApplication()); assertEquals(expectedPermission.getAllowedActions(), actualPermission.getAllowedActions()); } } }