/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * licenses this file to you 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 the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>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.apereo.portal.layout.profile; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apereo.portal.security.IPerson; import org.apereo.portal.security.IdentitySwapperManager; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; public class StickyProfileMapperImplTest { StickyProfileMapperImpl stickyMapper; @Mock IPerson person; @Mock IPerson guestPerson; @Mock HttpServletRequest request; @Mock IProfileSelectionRegistry registry; @Mock IdentitySwapperManager identitySwapperManager; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(registry.profileSelectionForUser("bobby")).thenReturn("profileFNameFromRegistry"); when(identitySwapperManager.isImpersonating(request)).thenReturn(false); Map<String, String> mappings = new HashMap<String, String>(); mappings.put("validKey1", "profileFName1"); mappings.put("validKey2", "profileFName2"); stickyMapper = new StickyProfileMapperImpl(); stickyMapper.setProfileSelectionRegistry(registry); stickyMapper.setIdentitySwapperManager(identitySwapperManager); stickyMapper.setMappings(mappings); stickyMapper.setProfileKeyForNoSelection("default"); when(person.getUserName()).thenReturn("bobby"); when(guestPerson.isGuest()).thenReturn(true); } /** * Test that when the underlying registry has a stored selection for a user, reflects that * selection. */ @Test public void testReflectsStoredSelection() { final String mappedFName = stickyMapper.getProfileFname(person, request); assertEquals("profileFNameFromRegistry", mappedFName); } /** * Test that when the underlying registry has no stored selection for a user, maps to null * (indicating no opinion about what profile ought to be mapped.) */ @Test public void testMapsToNullWhenNoStoredSelection() { // over-ride the set-up specified behavior when(registry.profileSelectionForUser("bobby")).thenReturn(null); assertNull(stickyMapper.getProfileFname(person, request)); } /** * Test that when the underlying registry fails, translates this failure into a null mapping * (indicating no available opinion about what profile ought to be mapped.) */ @Test public void testMapsToNullWhenUnderlyingRegistryThrows() { // over-ride the set-up specified behavior when(registry.profileSelectionForUser("bobby")).thenThrow(RuntimeException.class); assertNull(stickyMapper.getProfileFname(person, request)); } /** Test that stores selection to registry. */ @Test public void testStoresValidSelectionToRegistry() { ProfileSelectionEvent selectionEvent = new ProfileSelectionEvent(this, "validKey1", person, request); stickyMapper.onApplicationEvent(selectionEvent); verify(registry).registerUserProfileSelection("bobby", "profileFName1"); // this verifyNoMoreInteractions() is questionable // it makes the test over-specified, but it would catch some weird bugs wherein the profile mapper // might have done weird unexpected things to the registry. verifyNoMoreInteractions(registry); } /** Test that does not store selections by guest user to registry. */ @Test public void testIngoresGuestUserProfileSelections() { final ProfileSelectionEvent selectionEvent = new ProfileSelectionEvent(this, "validKey1", guestPerson, request); stickyMapper.onApplicationEvent(selectionEvent); verifyZeroInteractions(registry); } /** * Test that when the underlying registry throws in the course of handling profile selection * event, failure does not propagate out of the event handling method. */ @Test public void testFailsEventHandlingGracefully() { doThrow(RuntimeException.class) .when(registry) .registerUserProfileSelection("bobby", "profileFName1"); final ProfileSelectionEvent selectionEvent = new ProfileSelectionEvent(this, "validKey1", person, request); stickyMapper.onApplicationEvent(selectionEvent); verify(registry).registerUserProfileSelection("bobby", "profileFName1"); } /** Test that when the identity is swapped, ignores profile selection requests. */ @Test public void testIgnoresSelectionWhenIdentitySwapped() { // override the configuration in setUp() when(identitySwapperManager.isImpersonating(request)).thenReturn(true); ProfileSelectionEvent selectionEvent = new ProfileSelectionEvent(this, "validKey1", person, request); stickyMapper.onApplicationEvent(selectionEvent); verifyZeroInteractions(registry); } /** * Test that ignores requests for profile using a key that does not map to any known profile. */ @Test public void testIgnoresInvalidProfileKey() { ProfileSelectionEvent selectionEvent = new ProfileSelectionEvent(this, "bogusKey", person, request); stickyMapper.onApplicationEvent(selectionEvent); verifyZeroInteractions(registry); } /** * Test that when the user selects the profile key that the mapper is configured to consider * meaning no preference, clears the selection in the registry. */ @Test public void testSelectingDefaultTranslatesToClearingSelection() { ProfileSelectionEvent selectionEvent = new ProfileSelectionEvent(this, "default", person, request); stickyMapper.onApplicationEvent(selectionEvent); verify(registry).registerUserProfileSelection("bobby", null); } /** * Test that when the presenting profile key both is a key in the key->fname map and is the * configured key-that-ought-to-mean-no-preference, apathy wins. */ @Test public void testSelectingDefaultOverridesConfiguredMapping() { stickyMapper.setProfileKeyForNoSelection("validKey2"); ProfileSelectionEvent selectionEvent = new ProfileSelectionEvent(this, "validKey2", person, request); stickyMapper.onApplicationEvent(selectionEvent); // verify that stored this as null, not as profileFName2 verify(registry).registerUserProfileSelection("bobby", null); } /** * Test that when asked about the profile mapping for a null IPerson, throws * NullPointerException (which is the Validate.notNull() behavior). */ @Test(expected = NullPointerException.class) public void testThrowsNullPointerExceptionOnNullPerson() { stickyMapper.getProfileFname(null, request); } /** * Test that when asked about the profile mapping for a null HttpServletRequest, throws * NullPointerException (which is the Validate.notNull() behavior). */ @Test(expected = NullPointerException.class) public void testThrowsNullPointerExceptionOnNullServletRequestOnGetProfileFname() { stickyMapper.getProfileFname(person, null); } /** * Test that when asked to handle profile selection by a broken IPerson with a null userName, * throws NullPointerException (which is the Validate.notNull() behavior). */ @Test(expected = NullPointerException.class) public void testThrowsNullPointerExceptionOnNullUsernamedIPerson() { // overrides the mock behavior specified in setUp(). when(person.getUserName()).thenReturn(null); stickyMapper.getProfileFname(person, request); } }