/* * Copyright (c) JForum Team. All rights reserved. * * The software in this package is published under the terms of the LGPL * license a copy of which has been included with this distribution in the * license.txt file. * * The JForum Project * http://www.jforum.net */ package net.jforum.controllers; import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import net.jforum.core.SecurityConstraint; import net.jforum.core.SessionManager; import net.jforum.entities.Group; import net.jforum.entities.User; import net.jforum.entities.UserSession; import net.jforum.repository.RankingRepository; import net.jforum.repository.UserRepository; import net.jforum.security.EditUserRule; import net.jforum.security.RoleManager; import net.jforum.services.AvatarService; import net.jforum.services.LostPasswordService; import net.jforum.services.UserService; import net.jforum.util.ConfigKeys; import net.jforum.util.JForumConfig; import net.jforum.util.SecurityConstants; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.runners.MockitoJUnitRunner; import br.com.caelum.vraptor.interceptor.multipart.UploadedFile; import br.com.caelum.vraptor.util.test.MockResult; /** * @author Rafael Steil, Jonatan Cloutier */ @RunWith(MockitoJUnitRunner.class) public class UserControllerTestCase { @Mock private UserRepository userRepository; @Mock private UserSession userSession; @Mock private UserService userService; @Mock private SessionManager sessionManager; @Mock private JForumConfig config; @Mock private RoleManager roleManager; @Mock private LostPasswordService lostPasswordService; @Mock private AvatarService avatarService; @Mock private RankingRepository rankingRepository; @Spy private MockResult mockResult; @Mock private HttpServletRequest mockRequest; @Mock private ForumController mockForumController; @Mock private MessageController mockMessageController; @Mock private UserController mockForwardControler; @Mock private UserController mockRedirectController; @InjectMocks private UserController userController; private User user = new User(); private List<User> userList = new ArrayList<User>(); @Before public void setup() { when(userSession.getRoleManager()).thenReturn(roleManager); when(mockResult.forwardTo(userController)).thenReturn(mockForwardControler); when(mockResult.redirectTo(userController)).thenReturn(mockRedirectController); } @Test public void edit() { when(userRepository.get(1)).thenReturn(user); userController.edit(1); assertEquals(user, mockResult.included("user")); } @Test public void editSave() { user.setId(1); userController.editSave(user,null, null, null); verify(userService).update(user, false); } @Test public void recoverPassword() { userController.recoverPassword("123"); assertEquals("123", mockResult.included("hash")); } @Test public void recoverPasswordValidateUsingBadDataExpectFail() { userController.recoverPasswordValidate("hash", "user", "123"); assertEquals(true, mockResult.included("error")); assertEquals("PasswordRecovery.invalidData", mockResult.included("message")); } @Test public void recoverPasswordValidateUsingGoodDataExpectSuccess() { when(userRepository.validateLostPasswordHash("user", "hash")).thenReturn(user); userController.recoverPasswordValidate("hash", "user", "123"); assertEquals("PasswordRecovery.ok", mockResult.included("message")); } @Test public void lostPasswordSend() { when(lostPasswordService.send("username", "email")).thenReturn(true); userController.lostPasswordSend("username", "email"); assertEquals(true, mockResult.included("success")); } @Test public void loginWithReferer() { when(config.getBoolean(ConfigKeys.LOGIN_IGNORE_REFERER)).thenReturn(false); when(mockRequest.getHeader("Referer")).thenReturn("some referer"); userController.login(null, false); assertEquals("some referer", mockResult.included("returnPath")); } @Test public void loginWithReturnPath() { userController.login("some return path", false); assertEquals("some return path", mockResult.included("returnPath")); } @Test public void loginWithoutReturnPathAndIgnoringReferer() { when(config.getBoolean(ConfigKeys.LOGIN_IGNORE_REFERER)).thenReturn(true); when(mockRequest.getHeader("Referer")).thenReturn("some referer"); userController.login(null, false); assertNull(mockResult.included("returnPath")); } @Test public void editShouldHaveEditUserRule() throws Exception { Method method = userController.getClass().getMethod("edit", int.class); assertNotNull(method); assertTrue(method.isAnnotationPresent(SecurityConstraint.class)); assertEquals(EditUserRule.class, method.getAnnotation(SecurityConstraint.class).value()); } @Test public void editSaveShouldHaveEditUserRule() throws Exception { Method method = userController.getClass().getMethod("editSave", User.class, Integer.class, UploadedFile.class, Integer.class); assertNotNull(method); assertTrue(method.isAnnotationPresent(SecurityConstraint.class)); assertEquals(EditUserRule.class, method.getAnnotation(SecurityConstraint.class).value()); } @Test public void listUsingListingIsDisabledShouldForceEmptyList() { when(roleManager.isUserListingEnabled()).thenReturn(false); userController.list(0); assertEquals(userList, mockResult.included("users")); } @Test public void listCanInteractWithOtherGroups() { when(roleManager.roleExists(SecurityConstants.INTERACT_OTHER_GROUPS)).thenReturn(true); when(roleManager.isUserListingEnabled()).thenReturn(true); userController.list(0); verify(userRepository).getAllUsers(0, 0); } @Test public void listCannotInteractWithOtherGroups() { when(roleManager.roleExists(SecurityConstants.INTERACT_OTHER_GROUPS)).thenReturn(false); when(roleManager.isUserListingEnabled()).thenReturn(true); when(userSession.getUser()).thenReturn(user); userController.list(0); verify(userRepository, never()).getAllUsers(0, 0); } @Test public void logout() { when(config.getInt(ConfigKeys.ANONYMOUS_USER_ID)).thenReturn(1); when(config.getValue(ConfigKeys.COOKIE_AUTO_LOGIN)).thenReturn("x"); when(config.getValue(ConfigKeys.COOKIE_USER_HASH)).thenReturn("y"); userController.logout(); verify(userSession).becomeAnonymous(1); verify(userSession).removeCookie("x"); verify(userSession).removeCookie("y"); } @Test public void authenticateUserUsingInvalidCredentialsExpectsInvalidLogin() { when(userService.validateLogin("user", "passwd")).thenReturn(null); userController.authenticateUser("user", "passwd", false, null); verify(mockRedirectController).login(anyString(), anyBoolean()); } @Test public void authenticateUserUsingGoodCredentialsAndAutoLoginEnabledExpectsSuccess() { user.setId(26); when(userService.validateLogin("user", "passwd")).thenReturn(user); when(config.getValue(ConfigKeys.COOKIE_AUTO_LOGIN)).thenReturn("x"); when(config.getValue(ConfigKeys.COOKIE_USER_HASH)).thenReturn("y"); when(config.getValue(ConfigKeys.COOKIE_USER_ID)).thenReturn("z"); when(userService.generateAutoLoginSecurityHash(26)).thenReturn("456"); when(userService.generateAutoLoginUserHash("456")).thenReturn("789"); userController.authenticateUser("user", "passwd", true, null); verify(userSession).becomeLogged(); verify(userSession).addCookie("x", "1"); verify(userSession).addCookie("y", "789"); verify(userSession).addCookie("z", "26"); Assert.assertEquals("456", user.getSecurityHash()); } @Test public void authenticateUserUsingGoodCredentialsWithoutAutoLoginExpectsSuccess() { when(userService.validateLogin("user", "passwd")).thenReturn(user); userController.authenticateUser("user", "passwd", false, null); verify(userSession).becomeLogged(); verify(userSession, never()).addCookie(anyString(), anyString()); } @Test public void authenticateUserWithReturnPath() { when(userService.validateLogin("user1", "pass1")).thenReturn(user); userController.authenticateUser("user1", "pass1", false, "return path"); verify(mockResult).redirectTo("return path"); } @Test public void registrationCompletedWithAnonymousUserExpectRedirect() { when(userSession.isLogged()).thenReturn(false); userController.registrationCompleted(); verify(mockRedirectController).insert(); } @Test public void registrationCompletedWithValidUserExpectsPropertyBagWithUser() { when(userSession.isLogged()).thenReturn(true); when(userSession.getUser()).thenReturn(user); userController.registrationCompleted(); assertEquals(user, mockResult.included("user")); } @Test public void insertSaveUsernameTooBig() { when(config.getInt(ConfigKeys.USERNAME_MAX_LENGTH)).thenReturn(1); user.setUsername("username1"); userController.insertSave(user); assertEquals("User.usernameTooBig", mockResult.included("error")); verify(mockForwardControler).insert(); } @Test public void insertSaveUsernameContainsInvalidChars() { when(config.getInt(ConfigKeys.USERNAME_MAX_LENGTH)).thenReturn(20); user.setUsername("<username"); userController.insertSave(user); assertEquals("User.usernameInvalidChars", mockResult.included("error")); verify(mockForwardControler).insert(); } @Test public void insertSaveUsernameContainsInvalidChars2() { when(config.getInt(ConfigKeys.USERNAME_MAX_LENGTH)).thenReturn(20); user.setUsername(">username"); userController.insertSave(user); assertEquals("User.usernameInvalidChars", mockResult.included("error")); verify(mockForwardControler).insert(); } @Test public void insertSaveUsernameNotAvailable() { when(config.getInt(ConfigKeys.USERNAME_MAX_LENGTH)).thenReturn(20); when(userRepository.isUsernameAvailable("username", null)).thenReturn(false); user.setUsername("username"); userController.insertSave(user); assertEquals("User.usernameNotAvailable", mockResult.included("error")); verify(mockForwardControler).insert(); } @Test public void insertSaveUser() { when(config.getInt(ConfigKeys.USERNAME_MAX_LENGTH)).thenReturn(20); when(userRepository.isUsernameAvailable("username", null)).thenReturn(true); user.setUsername("username"); userController.insertSave(user); verify(userService).add(user); verify(mockRedirectController).registrationCompleted(); } @Test public void insertLoginUser() { when(config.getInt(ConfigKeys.USERNAME_MAX_LENGTH)).thenReturn(20); when(userRepository.isUsernameAvailable("username", null)).thenReturn(true); user.setUsername("username"); userController.insertSave(user); verify(userSession).becomeLogged(); } @Test public void profileHasReadAccessRightsShouldAllowViewProfile() { when(roleManager.getCanViewProfile()).thenReturn(true); when(userSession.getUser()).thenReturn(user); userController.profile(1); verify(userRepository).get(1); } @Test public void profileHasWriteAccessRightsShouldAllowEditProfile() { when(roleManager.getCanViewProfile()).thenReturn(true); when(roleManager.getCanEditUser(any(User.class), anyListOf(Group.class))).thenReturn(true); when(userSession.getUser()).thenReturn(user); userController.profile(1); assertEquals(true, mockResult.included("canEdit")); } @Test public void profileDoesNotHaveReadAccessRightShouldDenyViewProfile() { when(roleManager.getCanViewProfile()).thenReturn(false); when(mockResult.redirectTo(MessageController.class)).thenReturn(mockMessageController); userController.profile(1); verify(mockMessageController).accessDenied(); } @Test public void profileDoesNotHaveWriteAccessRightShouldDenyEditProfile() { when(roleManager.getCanViewProfile()).thenReturn(true); when(roleManager.getCanEditUser(any(User.class), anyListOf(Group.class))).thenReturn(false); when(userSession.getUser()).thenReturn(user); userController.profile(1); assertEquals(false, mockResult.included("canEdit")); } }