NIHVIVO-1568 continue new unit tests for Authenticate.

This commit is contained in:
jeb228 2011-01-07 22:20:16 +00:00
parent 00d144196a
commit ea78774a2d

View file

@ -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
*
* <pre>
* 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.
* </pre>
*/
@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 <null>, 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<String> expected = new HashSet<String>(Arrays.asList(usernames));
Set<String> actualRecorded = new HashSet<String>(
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<String, String> expected = new HashMap<String, String>();
for (int i = 0; i < strings.length; i += 2) {
expected.put(strings[i], strings[i + 1]);
}
assertEquals("password changes", expected,
authenticator.getNewPasswordMap());
}
// ----------------------------------------------------------------------
// Helper classes
// ----------------------------------------------------------------------