/**
* The contents of this file are subject to the OpenMRS Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://license.openmrs.org
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* Copyright (C) OpenMRS, LLC. All Rights Reserved.
*/
package org.openmrs.web;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openmrs.User;
import org.openmrs.api.context.Context;
import org.openmrs.web.controller.ForgotPasswordFormController;
import org.openmrs.web.test.BaseWebContextSensitiveTest;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
/**
* Test the different aspects of {@link org.openmrs.web.controller.ForgotPasswordFormController}
*/
public class ForgotPasswordFormControllerTest extends BaseWebContextSensitiveTest {
/**
* Log out before every test (authentication is done in the "@Before" in the parent class)
*
* @throws Exception
*/
@Before
public void runBeforeEachTest() throws Exception {
executeDataSet("org/openmrs/web/include/ForgotPasswordFormControllerTest.xml");
Context.logout();
}
/**
* Log out the current user after all unit test cases just in case the password was reset
*/
@After
public void cleanupAndLogoutUserAfterEachTest() {
Context.logout();
}
/**
* Just check for no errors on normal page load
*
* @throws Exception
*/
@Test
public void shouldLoadPageNormallyWithNoInput() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/forgotPassword.form");
new ForgotPasswordFormController().handleRequest(request, new MockHttpServletResponse());
}
/**
* Check to see if the admin's secret question comes back
*
* @throws Exception
*/
@Test
public void shouldNotNotFailOnNotFoundUsername() throws Exception {
ForgotPasswordFormController controller = new ForgotPasswordFormController();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("POST");
request.addParameter("uname", "validuser");
HttpServletResponse response = new MockHttpServletResponse();
controller.handleRequest(request, response);
Assert.assertEquals("validuser", request.getAttribute("uname"));
Assert.assertEquals("valid secret question", request.getAttribute("secretQuestion"));
}
/**
* Check to see if the admin's secret question comes back
*
* @throws Exception
*/
@Test
public void shouldAuthenticateAsUserWithValidSecretQuestion() throws Exception {
ForgotPasswordFormController controller = new ForgotPasswordFormController();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("POST");
request.addParameter("uname", "validuser");
request.addParameter("secretAnswer", "valid secret answer");
HttpServletResponse response = new MockHttpServletResponse();
controller.handleRequest(request, response);
Assert.assertEquals(new User(2), Context.getAuthenticatedUser());
}
/**
* If a user enters the wrong secret answer, they should be kicked back to the form and not be
* authenticated
*
* @throws Exception
*/
@Test
public void shouldNotAuthenticateAsUserWithValidSecretQuestion() throws Exception {
ForgotPasswordFormController controller = new ForgotPasswordFormController();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("POST");
request.addParameter("uname", "validuser");
request.addParameter("secretAnswer", "invalid secret answer");
HttpServletResponse response = new MockHttpServletResponse();
controller.handleRequest(request, response);
Assert.assertFalse(Context.isAuthenticated());
}
/**
* If a user enters 5 requests, the 6th should fail even if that one has a valid username in it
*
* @throws Exception
*/
@Test
public void shouldLockOutAfterFiveFailedInvalidUsernames() throws Exception {
ForgotPasswordFormController controller = new ForgotPasswordFormController();
for (int x = 1; x <= 5; x++) {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/forgotPassword.form");
request.addParameter("uname", "invaliduser");
controller.handleRequest(request, new MockHttpServletResponse());
}
// those were the first five, now the sixth request (with a valid user) should fail
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/forgotPassword.form");
request.addParameter("uname", "validuser");
controller.handleRequest(request, new MockHttpServletResponse());
Assert.assertNull(request.getAttribute("secretQuestion"));
}
/**
* If a user enters 5 requests, the 6th should fail even if that one has a valid username and a
* secret answer associated with it
*
* @throws Exception
*/
@Test
public void shouldNotAuthenticateAfterFiveFailedInvalidUsernames() throws Exception {
ForgotPasswordFormController controller = new ForgotPasswordFormController();
for (int x = 1; x <= 5; x++) {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/forgotPassword.form");
request.addParameter("uname", "invaliduser");
controller.handleRequest(request, new MockHttpServletResponse());
}
// those were the first five, now the sixth request (with a valid user) should fail
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/forgotPassword.form");
request.addParameter("uname", "validuser");
request.addParameter("secretAnswer", "valid secret answer");
controller.handleRequest(request, new MockHttpServletResponse());
Assert.assertFalse(Context.isAuthenticated());
}
/**
* If a user enters 5 requests with username+secret answer, the 6th should fail even if that one
* has a valid answer in it
*
* @throws Exception
*/
@Test
public void shouldLockOutAfterFiveFailedInvalidSecretAnswers() throws Exception {
ForgotPasswordFormController controller = new ForgotPasswordFormController();
for (int x = 1; x <= 5; x++) {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/forgotPassword.form");
request.addParameter("uname", "validuser");
request.addParameter("secretAnswer", "invalid secret answer");
controller.handleRequest(request, new MockHttpServletResponse());
}
// those were the first five, now the sixth request (with a valid user) should fail
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/forgotPassword.form");
request.addParameter("uname", "validuser");
request.addParameter("secretAnswer", "valid secret answer");
controller.handleRequest(request, new MockHttpServletResponse());
Assert.assertFalse(Context.isAuthenticated());
}
/**
* If a user enters 4 username requests, the 5th one should reset the lockout and they should be
* allowed 5 attempts at the secret answer
*
* @throws Exception
*/
@Test
public void shouldGiveUserFiveSecretAnswerAttemptsAfterLessThanFiveFailedUsernameAttempts() throws Exception {
ForgotPasswordFormController controller = new ForgotPasswordFormController();
for (int x = 1; x <= 4; x++) {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/forgotPassword.form");
request.addParameter("uname", "invaliduser");
controller.handleRequest(request, new MockHttpServletResponse());
}
// those were the first four, now the fifth is a valid username
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/forgotPassword.form");
request.addParameter("uname", "validuser");
controller.handleRequest(request, new MockHttpServletResponse());
Assert.assertNotNull(request.getAttribute("secretQuestion"));
// now the user has 5 chances at the secret answer
// fifth request
MockHttpServletRequest request5 = new MockHttpServletRequest("POST", "/forgotPassword.form");
request5.addParameter("uname", "validuser");
request5.addParameter("secretAnswer", "invalid answer");
controller.handleRequest(request5, new MockHttpServletResponse());
Assert.assertNotNull(request5.getAttribute("secretQuestion"));
// sixth request (should not lock out because is after valid username)
MockHttpServletRequest request6 = new MockHttpServletRequest("POST", "/forgotPassword.form");
request6.addParameter("uname", "validuser");
request6.addParameter("secretAnswer", "invalid answer");
controller.handleRequest(request6, new MockHttpServletResponse());
Assert.assertNotNull(request6.getAttribute("secretQuestion"));
// seventh request (should authenticate with valid answer)
MockHttpServletRequest request7 = new MockHttpServletRequest("POST", "/forgotPassword.form");
request7.addParameter("uname", "validuser");
request7.addParameter("secretAnswer", "valid secret answer");
controller.handleRequest(request7, new MockHttpServletResponse());
Assert.assertTrue(Context.isAuthenticated());
}
}