From ea78774a2d02622dbf7fa9110b3f549a7a5196a6 Mon Sep 17 00:00:00 2001 From: jeb228 Date: Fri, 7 Jan 2011 22:20:16 +0000 Subject: [PATCH] NIHVIVO-1568 continue new unit tests for Authenticate. --- .../controller/edit/AuthenticateTest.java | 290 +++++++++++++----- 1 file changed, 219 insertions(+), 71 deletions(-) diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java index 4e6eb1d5a..ad49ff80c 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java @@ -2,12 +2,19 @@ package edu.cornell.mannlib.vitro.webapp.controller.edit; +import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.FORCED_PASSWORD_CHANGE; import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGING_IN; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.net.URL; +import java.util.Arrays; import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import org.junit.Before; import org.junit.Ignore; @@ -18,6 +25,8 @@ import stubs.javax.servlet.ServletContextStub; import stubs.javax.servlet.http.HttpServletRequestStub; import stubs.javax.servlet.http.HttpServletResponseStub; import stubs.javax.servlet.http.HttpSessionStub; +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.webapp.beans.User; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.AuthenticatorStub; @@ -35,6 +44,7 @@ public class AuthenticateTest extends AbstractTestClass { private HttpServletRequestStub request; private HttpServletResponseStub response; private Authenticate auth; + private LoginProcessBean initialProcessBean; // ---------------------------------------------------------------------- // Setup and data @@ -47,16 +57,24 @@ public class AuthenticateTest extends AbstractTestClass { "new_dba_uri", NEW_DBA_PW, 50, 0); /** A DBA who has logged in before. */ - private static final UserInfo OLD_DBA = new UserInfo("old_dba_name", - "old_dba_uri", "old_dba_pw", 50, 5); + private static final String OLD_DBA_NAME = "old_dba_name"; + private static final String OLD_DBA_PW = "old_dba_pw"; + private static final String OLD_DBA_URI = "old_dba_uri"; + private static final int OLD_DBA_SECURITY_LEVEL = 50; + private static final UserInfo OLD_DBA = new UserInfo(OLD_DBA_NAME, + OLD_DBA_URI, OLD_DBA_PW, OLD_DBA_SECURITY_LEVEL, 5); /** A self-editor who has logged in before and has a profile. */ - private static final UserInfo OLD_SELF = new UserInfo("old_self_name", - "old_self_uri", "old_self_pw", 1, 100); + private static final String OLD_SELF_NAME = "old_self_name"; + private static final String OLD_SELF_PW = "old_self_pw"; + private static final UserInfo OLD_SELF = new UserInfo(OLD_SELF_NAME, + "old_self_uri", OLD_SELF_PW, 1, 100); - /** A self-editor who has never logged in and has no profile. */ - private static final UserInfo NEW_STRANGER = new UserInfo( - "new_stranger_name", "new_stranger_uri", "stranger_pw", 1, 0); + /** A self-editor who has logged in before but has no profile. */ + private static final String OLD_STRANGER_NAME = "old_stranger_name"; + private static final String OLD_STRANGER_PW = "stranger_pw"; + private static final UserInfo OLD_STRANGER = new UserInfo( + OLD_STRANGER_NAME, "old_stranger_uri", OLD_STRANGER_PW, 1, 20); /** the login page */ private static final String URL_LOGIN = "/vivo/login"; @@ -87,7 +105,7 @@ public class AuthenticateTest extends AbstractTestClass { authenticator.addUser(createUserFromUserInfo(NEW_DBA)); authenticator.addUser(createUserFromUserInfo(OLD_DBA)); authenticator.addUser(createUserFromUserInfo(OLD_SELF)); - authenticator.addUser(createUserFromUserInfo(NEW_STRANGER)); + authenticator.addUser(createUserFromUserInfo(OLD_STRANGER)); authenticator.setAssociatedUri(OLD_SELF.username, "old_self_associated_uri"); @@ -194,7 +212,7 @@ public class AuthenticateTest extends AbstractTestClass { // ---------------------------------------------------------------------- /** The "return" parameter is set, so we detect the restart. */ - @Ignore + @Ignore // TODO @Test public void restartFromALoginLink() { setProcessBean(LOGGING_IN, "username", URL_LOGIN, URL_SOMEWHERE_ELSE); @@ -202,7 +220,7 @@ public class AuthenticateTest extends AbstractTestClass { } /** The "return" parameter is set, so we detect the restart. */ - @Ignore + @Ignore // TODO @Test public void restartFromABookmarkOfTheLoginLink() { setProcessBean(LOGGING_IN, "username", URL_LOGIN, URL_SOMEWHERE_ELSE); @@ -210,7 +228,7 @@ public class AuthenticateTest extends AbstractTestClass { } /** The "afterLoginUrl" parameter is set, so we detect the restart. */ - @Ignore + @Ignore // TODO @Test public void restartFromARestrictedPage() { setProcessBean(LOGGING_IN, "username", URL_LOGIN, URL_SOMEWHERE_ELSE); @@ -218,7 +236,7 @@ public class AuthenticateTest extends AbstractTestClass { } /** The referrer is not the loginProcessPage, so we detect the restart. */ - @Ignore + @Ignore // TODO @Test public void restartFromADifferentWidgetPage() { setProcessBean(LOGGING_IN, "username", URL_LOGIN, URL_SOMEWHERE_ELSE); @@ -226,7 +244,7 @@ public class AuthenticateTest extends AbstractTestClass { } /** The referrer is not the loginProcessPage, so we detect the restart. */ - @Ignore + @Ignore // TODO @Test public void restartFromTheLoginPageWhenWeWereUsingAWidgetPage() { setProcessBean(LOGGING_IN, "username", URL_SOMEWHERE_ELSE, @@ -270,113 +288,183 @@ public class AuthenticateTest extends AbstractTestClass { doTheRequest(); assertProcessBean(LOGGING_IN, NEW_DBA_NAME, NO_MSG, - "Please enter your password.", URL_LOGIN, + "Please enter your password.", URL_LOGIN, URL_WITH_LINK); + assertRedirectToLoginProcessPage(); + } + + @Test + public void loggingInPasswordIsIncorrect() { + setProcessBean(LOGGING_IN, NO_USER, URL_LOGIN, URL_WITH_LINK); + setLoginNameAndPassword(NEW_DBA_NAME, "bogus_password"); + + doTheRequest(); + + assertProcessBean(LOGGING_IN, NEW_DBA_NAME, NO_MSG, + "The email or password you entered is incorrect.", URL_LOGIN, URL_WITH_LINK); assertRedirectToLoginProcessPage(); } - @Ignore - @Test - public void loggingInPasswordIsIncorrect() { - fail("loggingInPasswordIsIncorrect not implemented"); - } - - @Ignore @Test public void loggingInSuccessful() { - fail("loggingInSuccessful not implemented"); + setProcessBean(LOGGING_IN, NO_USER, URL_LOGIN, URL_WITH_LINK); + setLoginNameAndPassword(OLD_DBA_NAME, OLD_DBA_PW); + + doTheRequest(); + + assertNoProcessBean(); + assertNewLoginSessions(OLD_DBA_NAME); + assertRedirectToAfterLoginPage(); } - @Ignore @Test - public void loggingInSuccessfulFirstTime() { - fail("loggingInSuccessfulFirstTime not implemented"); + public void loggingInForcesPasswordChange() { + setProcessBean(LOGGING_IN, NO_USER, URL_LOGIN, URL_WITH_LINK); + setLoginNameAndPassword(NEW_DBA_NAME, NEW_DBA_PW); + + doTheRequest(); + + assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG, NO_MSG, + URL_LOGIN, URL_WITH_LINK); + assertNewLoginSessions(); + assertRedirectToLoginProcessPage(); } - @Ignore @Test public void changingPasswordCancel() { - fail("changingPasswordCancel not implemented"); + setProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, URL_LOGIN, + URL_WITH_LINK); + setCancel(); + + doTheRequest(); + + assertNoProcessBean(); + assertNewLoginSessions(); + assertRedirectToCancelUrl(); } - @Ignore @Test public void changingPasswordWrongLength() { - fail("changingPasswordWrongLength not implemented"); + setProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, URL_LOGIN, + URL_WITH_LINK); + setNewPasswordAttempt("HI", "HI"); + + doTheRequest(); + + assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG, + "Please enter a password between 6 and 12 " + + "characters in length.", URL_LOGIN, URL_WITH_LINK); + assertRedirectToLoginProcessPage(); } - @Ignore @Test public void changingPasswordDontMatch() { - fail("changingPasswordDontMatch not implemented"); + setProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, URL_LOGIN, + URL_WITH_LINK); + setNewPasswordAttempt("LongEnough", "DoesNotMatch"); + + doTheRequest(); + + assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG, + "The passwords entered do not match.", URL_LOGIN, URL_WITH_LINK); + assertRedirectToLoginProcessPage(); } - @Ignore @Test public void changingPasswordSameAsBefore() { - fail("changingPasswordSameAsBefore not implemented"); + setProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, URL_LOGIN, + URL_WITH_LINK); + setNewPasswordAttempt(NEW_DBA_PW, NEW_DBA_PW); + + doTheRequest(); + + assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG, + "Please choose a different password from the temporary " + + "one provided initially.", URL_LOGIN, URL_WITH_LINK); + assertRedirectToLoginProcessPage(); } - @Ignore @Test public void changingPasswordSuccess() { - fail("changingPasswordSuccess not implemented"); + setProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, URL_LOGIN, + URL_WITH_LINK); + setNewPasswordAttempt("NewPassword", "NewPassword"); + + doTheRequest(); + + assertNoProcessBean(); + assertNewLoginSessions(NEW_DBA_NAME); + assertPasswordChanges(NEW_DBA_NAME, "NewPassword"); + assertRedirectToAfterLoginPage(); } - @Ignore @Test public void alreadyLoggedIn() { - fail("alreadyLoggedIn not implemented"); + LoginStatusBean statusBean = new LoginStatusBean(OLD_DBA_URI, + OLD_DBA_NAME, OLD_DBA_SECURITY_LEVEL, + AuthenticationSource.INTERNAL); + LoginStatusBean.setBean(session, statusBean); + setRequestFromLoginLink(URL_WITH_LINK); + + doTheRequest(); + + assertNoProcessBean(); + assertNewLoginSessions(); + assertRedirect(URL_WITH_LINK); } // ---------------------------------------------------------------------- // EXIT TESTS // ---------------------------------------------------------------------- - @Ignore + @Test public void exitSelfEditor() { - fail("exitSelfEditor not implemented"); + setProcessBean(LOGGING_IN, NO_USER, URL_LOGIN, URL_WITH_LINK); + setLoginNameAndPassword(OLD_SELF_NAME, OLD_SELF_PW); + + doTheRequest(); + + assertNoProcessBean(); + assertNewLoginSessions(OLD_SELF_NAME); + assertRedirect(URL_SELF_PROFILE); } - @Ignore @Test public void exitUnrecognizedSelfEditor() { - fail("exitUnrecognizedSelfEditor not implemented"); + setProcessBean(LOGGING_IN, NO_USER, URL_LOGIN, URL_WITH_LINK); + setLoginNameAndPassword(OLD_STRANGER_NAME, OLD_STRANGER_PW); + + doTheRequest(); + + assertNoProcessBean(); + assertNewLoginSessions(OLD_STRANGER_NAME); + assertRedirect(URL_HOME); } - @Ignore @Test - public void exitDba() { - fail("exitDbaFromLoginLink not implemented"); + public void exitDbaNormal() { + setProcessBean(LOGGING_IN, NO_USER, URL_LOGIN, URL_RESTRICTED); + setLoginNameAndPassword(OLD_DBA_NAME, OLD_DBA_PW); + + doTheRequest(); + + assertNoProcessBean(); + assertNewLoginSessions(OLD_DBA_NAME); + assertRedirect(URL_RESTRICTED); } - /** - * TODO - * - *
-	 * INTERRUPT TESTS (RESTARTS):
-	 *   Establish a specific process bean.
-	 *   Set up the request with parameters and referrer.
-	 *   Call the servlet.
-	 *   Examine the redirect.
-	 *   Examine the process bean.
-	 *   
-	 * PROCESS TESTS:
-	 *   Establish a specific process bean.
-	 *   Set up the request with parameters and referrer.
-	 *   Call the servlet.
-	 *   Examine the redirect.
-	 *   Examine the process bean (and perhaps the status bean).
-	 *   
-	 * EXIT TESTS:
-	 *   Mimic the simple success, but with different users.
-	 *   Establish a process bean that reflects the entry.
-	 *   Call the servlet.
-	 *   Examine the redirect.
-	 *   Confirm that the status bean is as expected, and there is no process bean.
-	 * 
- */ - + @Test + public void exitDbaFromLoginPage() { + setProcessBean(LOGGING_IN, NO_USER, URL_LOGIN, URL_LOGIN); + setLoginNameAndPassword(OLD_DBA_NAME, OLD_DBA_PW); + + doTheRequest(); + + assertNoProcessBean(); + assertNewLoginSessions(OLD_DBA_NAME); + assertRedirect(URL_SITE_ADMIN); + } + // ---------------------------------------------------------------------- // Helper methods // ---------------------------------------------------------------------- @@ -395,6 +483,7 @@ public class AuthenticateTest extends AbstractTestClass { request.setHeader("referer", urlWidget); } + /** Create a LoginProcessBean in the session, and keep a reference to it. */ private void setProcessBean(State state, String username, String loginProcessUrl, String afterLoginUrl) { LoginProcessBean bean = LoginProcessBean.getBean(request); @@ -402,6 +491,8 @@ public class AuthenticateTest extends AbstractTestClass { bean.setUsername(username); bean.setLoginPageUrl(loginProcessUrl); bean.setAfterLoginUrl(afterLoginUrl); + + initialProcessBean = bean; } private void setLoginNameAndPassword(String loginName, String password) { @@ -409,10 +500,27 @@ public class AuthenticateTest extends AbstractTestClass { request.addParameter("loginPassword", password); } + private void setCancel() { + request.addParameter("cancel", "true"); + } + + private void setNewPasswordAttempt(String newPassword, + String confirmPassword) { + request.addParameter("newPassword", newPassword); + request.addParameter("confirmPassword", confirmPassword); + } + private void doTheRequest() { auth.doPost(request, response); } + private void assertNoProcessBean() { + if (LoginProcessBean.isBean(request)) { + fail("Process bean: expected , but was <" + + LoginProcessBean.getBean(request) + ">"); + } + } + private void assertProcessBean(State state, String username, String infoMessage, String errorMessage, String loginProcessUrl, String afterLoginUrl) { @@ -447,6 +555,46 @@ public class AuthenticateTest extends AbstractTestClass { assertRedirect(LoginProcessBean.getBean(request).getLoginPageUrl()); } + private void assertRedirectToAfterLoginPage() { + assertNotNull("No reference to the initial LoginProcessBean", + initialProcessBean); + assertRedirect(initialProcessBean.getAfterLoginUrl()); + } + + private void assertRedirectToCancelUrl() { + String afterLoginUrl = initialProcessBean.getAfterLoginUrl(); + if ((afterLoginUrl == null) || (afterLoginUrl.equals(URL_LOGIN))) { + assertRedirect(URL_HOME); + } else { + assertRedirect(afterLoginUrl); + } + } + + /** What logins were completed in this test? */ + private void assertNewLoginSessions(String... usernames) { + Set expected = new HashSet(Arrays.asList(usernames)); + + Set actualRecorded = new HashSet( + authenticator.getRecordedLoginUsernames()); + assertEquals("recorded logins", expected, actualRecorded); + } + + /** What passwords were changed in this test? */ + private void assertPasswordChanges(String... strings) { + if ((strings.length % 2) != 0) { + throw new RuntimeException( + "supply even number of args: username and password"); + } + + Map expected = new HashMap(); + for (int i = 0; i < strings.length; i += 2) { + expected.put(strings[i], strings[i + 1]); + } + + assertEquals("password changes", expected, + authenticator.getNewPasswordMap()); + } + // ---------------------------------------------------------------------- // Helper classes // ----------------------------------------------------------------------