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