easycare.cuke.steps.PasswordSteps.java Source code

Java tutorial

Introduction

Here is the source code for easycare.cuke.steps.PasswordSteps.java

Source

package easycare.cuke.steps;

import static easycare.web.password.ChangePasswordController.LOGIN_USE_NEW_PASSWORD_MESSAGE;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import gherkin.formatter.model.DataTableRow;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cucumber.annotation.en.Given;
import cucumber.annotation.en.Then;
import cucumber.table.DataTable;
import easycare.builder.service.UserBuilderService;
import easycare.common.ApplicationMessageSource;
import easycare.cuke.WebSite;
import easycare.cuke.pageObjects.AbstractChangePasswordPage;
import easycare.cuke.pageObjects.FirstTimeLoginPage;
import easycare.cuke.pageObjects.LicenseAgreementPage;
import easycare.cuke.pageObjects.LoginPage;
import easycare.cuke.pageObjects.ManualResetPasswordPage;
import easycare.cuke.pageObjects.behaviors.HasNotificationBehavior;
import easycare.cuke.steps.support.LoginStepsSupport;
import easycare.cuke.util.SeleniumUtils;
import easycare.dao.UserPasswordTokenRepository;
import easycare.model.User;
import easycare.model.UserBuilder;
import easycare.model.UserPasswordToken;
import easycare.service.SecurityService;
import easycare.service.UserPasswordService;
import easycare.service.UserService;
import easycare.util.db.generator.UserGeneratorHelper;
import easycare.web.password.ManualResetPasswordController;
import easycare.web.password.PasswordTokenController;

@Component
public class PasswordSteps extends AbstractSteps {
    private static final Random R = new Random();
    private static final String NO_CONFIRM_STRING = "( \\(No password confirmation required\\)|)?";

    @Autowired
    private WebSite webSite;

    @Autowired
    private CommonSteps commonSteps;

    @Autowired
    private LoginStepsSupport loginStepsSupport;

    @Autowired
    private UserPasswordTokenRepository userSetPasswordRepository;

    @Autowired
    private UserPasswordService userSetPasswordService;

    @Autowired
    private UserService userService;

    @Autowired
    private ApplicationMessageSource messageSource;

    @Autowired
    private UserBuilderService userBuilderService;

    @Autowired
    protected SecurityService securityService;

    @Given("^the following reset password token exists for user \"?([^\"]*)\"?$")
    public void theFollowingTokenResetPasswordExist(String username, DataTable userValues) {
        UserBuilder userBuilder = new UserBuilder().withRandomValues()
                .withPassword(UserGeneratorHelper.DEFAULT_PASSWORD).withUsername(username);
        User user = userBuilderService.findOrBuildUser(userBuilder);

        for (Map<String, String> tokenMap : userValues.asMaps()) {
            String token = StepUtils.getMapAttribute(tokenMap, "token");
            LocalDateTime date = StepUtils.getMapAttributeAsLocalDateTime(tokenMap, "date");
            boolean expired = new Boolean(StepUtils.getMapAttribute(tokenMap, "expired"));
            UserPasswordToken ufp = new UserPasswordToken();
            ufp.setUser(user);
            ufp.setUuid(token);
            ufp.setDate(date);
            ufp.setUsed(expired);
            this.userSetPasswordService.save(ufp);
        }
    }

    @Given("^I use the reset password token \"?([^\"]+)\"?$")
    public void iUseTheResetPasswordToken(String token) throws InterruptedException {
        this.webSite.openRelativeUrl(PasswordTokenController.RESET_PASSWORD_URL + "?id=" + token);
        commonSteps.iWaitForNumberSeconds("3");
    }

    @Given("^I use the first time login token \"?([^\"]+)\"?$")
    public void iUseTheFirstTimeLoginToken(String token) {
        this.webSite.openRelativeUrl(PasswordTokenController.NEW_USER_SET_PASSWORD_URL + "?id=" + token);
    }

    @Given("^I accept the License Agreement$")
    public void iAcceptTheLicenseAgreement() {

        LicenseAgreementPage page = currentPage(LicenseAgreementPage.class);
        page.acceptLicenseAgreement();
    }

    @Given("user \"?([^\"]+)\"? asks for a reset password")
    public void userAsksForAPasswordReset(String username) {
        User user = this.userService.findByUsernameWithContactInformation(username);
        this.userService.resetUserPasswordAndSendEmail(user);
    }

    @Given("the two last the reset password tokens should be different")
    public void theResetPasswordTokensShouldBeDifferent() {
        List<String> tokens = new ArrayList<String>();
        for (UserPasswordToken ufp : this.userSetPasswordRepository.findAll()) {
            assertThat("Token is no unique", !tokens.contains(ufp.getUuid()));
            tokens.add(ufp.getUuid());
        }
    }

    @Given("^I use the emailed reset password link$")
    public void iUseTheLastResetPasswordToken() throws InterruptedException {
        // Get the first valid token from repository

        UserPasswordToken findMostRecentlyCreatedToken = this.userSetPasswordRepository
                .findMostRecentlyCreatedToken();
        assertThat("No valid token found to reset password", findMostRecentlyCreatedToken, notNullValue());
        this.iUseTheResetPasswordToken(findMostRecentlyCreatedToken.getUuid());
    }

    @Given("^I use the emailed first time login password link$")
    public void iUseTheLastFirstTimeLoginPasswordToken() {
        // Get the first valid token from repository

        UserPasswordToken findMostRecentlyCreatedToken = this.userSetPasswordRepository
                .findMostRecentlyCreatedToken();
        assertThat("No valid token found to reset password", findMostRecentlyCreatedToken, notNullValue());
        this.iUseTheFirstTimeLoginToken(findMostRecentlyCreatedToken.getUuid());
    }

    /**
     * Update user password on change password page.<br/>
     * <ol>
     * <li>Fills in <strong>Password</strong> and <strong>Confirm
     * Password</strong> fields with a password matching ResMed policy</li>
     * <li>Checks the message "<strong>Passwords match</strong>" is displayed</li>
     * <li>Clicks on the <strong>Continue</strong> button</li>
     * </ol>
     */
    @Given("^I change my password using a valid ResMed password" + NO_CONFIRM_STRING + "$")
    public void iChangeMyPassword(String isConfirmationRequired) throws Exception {
        String password = "Password" + R.nextInt(1000);
        changePassword(password, password, isConfirmationRequired);
        commonSteps.iShouldSee(messageSource.getMessage("user.password.match.success"));
        commonSteps.clickButton(AbstractChangePasswordPage.CONTINUE_BUTTON);
    }

    /**
     * Test invalid passwords.<br/>
     * <ul>
     * <li>Empty Password</li>
     * <li>Invalid Passwords</li>
     * <li>Password same as Username</li>
     * <li>Mismatching passwords</li>
     * </ul>
     */
    @Given("^I enter non-ResMed passwords for user \"?([^\"]+)\"? it should fail" + NO_CONFIRM_STRING + "$")
    public void iEnterNonResMedPasswordsItShouldFail(String username, String isConfirmationRequired)
            throws Exception {
        if (StringUtils.isEmpty(isConfirmationRequired)) {
            iEnterEmptyPassword();
        } else {
            iEnterEmptyPasswordNoConfirmation();
        }

        this.iEnterInvalidPassword(isConfirmationRequired);

        this.iEnterInvalidPassword(username);

        if (StringUtils.isEmpty(isConfirmationRequired)) {
            this.iEnterMismatchingPasswords(isConfirmationRequired);
        }
    }

    /**
     * Trying to change the password using blank values should fail.<br/>
     * <ol>
     * <li>Clicks on the <strong>Continue</strong> button without entering
     * password</li>
     * <li>Checks the message "<strong>Passwords is mandatory</strong>" is
     * displayed</li>
     * </ol>
     */
    @Given("^I enter an empty password it should fail$")
    public void iEnterEmptyPassword() throws Exception {
        commonSteps.clickButton("Continue");
        commonSteps.iShouldSeeMessageCode("NotEmpty.changePasswordForm.password");
    }

    private void iEnterEmptyPasswordNoConfirmation() throws Exception {
        changePassword("", "", NO_CONFIRM_STRING);
        commonSteps.clickButton("Continue");
        commonSteps.iShouldSeeMessageCode("NotEmpty.password");
    }

    /**
     * Trying to change the password using an invalid password.
     * <ol>
     * <li>Fills in <strong>Password</strong> and <strong>Confirm
     * Password</strong> fields with an invalid password</li>
     * <li>Checks the message "<strong>Passwords match</strong>" is displayed</li>
     * <li>Clicks on the <strong>Continue</strong> button</li>
     * <li>Checks the message
     * "<strong>Password does not meet the requirements</strong>" is displayed</li>
     * </ol>
     */
    @Given("^I enter an invalid password it should fail" + NO_CONFIRM_STRING + "$")
    public void iEnterInvalidPassword(String isConfirmationRequired) throws Exception {
        String[] invalidPasswords = { "Ecoblu1", "easycare@123", "PasswOrd" };
        for (String password : invalidPasswords) {
            try {
                changePassword(password, password, isConfirmationRequired);
                this.commonSteps.iShouldSee(this.messageSource.getMessage("password.change.fail"));
                this.commonSteps.clickButton("Continue");
                this.commonSteps.iShouldSee(this.messageSource.getMessage("password.change.fail"));
            } catch (AssertionError e) {
                throw new AssertionError("Error when validating password " + password + ": " + e.getMessage());
            }
        }
    }

    /**
     * Trying to change the password using an invalid password.
     * <ol>
     * <li>Fills in <strong>Password</strong> and <strong>Confirm
     * Password</strong> fields with an invalid password</li>
     * <li>Checks the message "<strong>Passwords match</strong>" is displayed</li>
     * <li>Clicks on the <strong>Continue</strong> button</li>
     * <li>Checks the message
     * "<strong>Password does not meet the requirements</strong>" is displayed</li>
     * </ol>
     */
    @Given("^I enter invalid password \"?([^\"]+)\"? it should fail" + NO_CONFIRM_STRING + "$")
    public void iEnterInvalidPassword(String password, String isConfirmationRequired) throws Exception {
        changePassword(password, password, isConfirmationRequired);
        this.commonSteps.iShouldSee(this.messageSource.getMessage("password.change.fail"));
    }

    @Given("^I enter mismatching passwords it should fail" + NO_CONFIRM_STRING + "$")
    public void iEnterMismatchingPasswords(String isConfirmationRequired) throws Exception {
        String password = "Password" + R.nextInt(1000);
        String confirmPassword = "ConfirmPassword" + R.nextInt(1000);
        changePassword(password, confirmPassword, isConfirmationRequired);
        this.commonSteps.theUserClicksOnField("Password");
        this.commonSteps.iShouldSee(this.messageSource.getMessage("user.password.match.error"));
        this.commonSteps.clickButton("Continue");
        this.commonSteps.iShouldSee(this.messageSource.getMessage("user.password.match.error"));
    }

    @Given("^I change my password to \"([^\"]+)\" and accept the licence agreement")
    public void iChangePasswordAndAcceptLicenceAgreement(String newPassword) throws Exception {
        currentPage(FirstTimeLoginPage.class).changeMyPassword(newPassword, LicenseAgreementPage.class)
                .acceptLicenseAgreement();
    }

    @Given("^I change my password to \"?([^\"]+)\"?" + NO_CONFIRM_STRING + "$")
    public void iChangePassword(String password, String isConfirmationRequired) throws Exception {
        changePassword(password, password, isConfirmationRequired);
        this.commonSteps.clickButton("Continue");
    }

    @Given("^I change my password to old password \"?([^\"]+)\"? it should fail" + NO_CONFIRM_STRING + "$")
    public void iEnterOldPasswordItFails(String oldPassword, String isConfirmationRequired) throws Exception {
        changePassword(oldPassword, oldPassword, isConfirmationRequired);
        this.commonSteps.clickButton("Continue");
        this.commonSteps.iShouldSee(this.messageSource.getMessage("password.change.history.error"));
    }

    @Then("User is informed that licence agreement will follow password reset")
    public void acceptenceIsPending() {
        AbstractChangePasswordPage currentPage = currentPage(AbstractChangePasswordPage.class);
        currentPage.assertAcceptanceIsPending(messageSource);
    }

    @Then("User is shown page as password reset only")
    public void acceptenceIsNotending() {
        AbstractChangePasswordPage currentPage = currentPage(AbstractChangePasswordPage.class);
        currentPage.assertAcceptanceIsNotPending(messageSource);
    }

    @Then("^I fill in temporary password \"([^\"]*)\"$")
    public void fillInPassword(String passwordString) {
        currentPage(AbstractChangePasswordPage.class).fillInPassword(passwordString);
    }

    @Then("^I fill in temporary password \"([^\"]*)\" and save$")
    public void fillInPasswordAndSave(String passwordString) {
        currentPage(AbstractChangePasswordPage.class).fillInPassword(passwordString);
        currentPage(AbstractChangePasswordPage.class).submitPasswords();
        SeleniumUtils.pollForJqueryToComplete(getWebDriver());
    }

    @Then("^I should see \"([^\"]*)\" in temporary password as plain text$")
    public void passwordIsDisplayedInPasswordFieldAsPlainText(String passwordString) {
        currentPage(AbstractChangePasswordPage.class)
                .assertPasswordIsDisplayedInPasswordFieldAsPlainText(passwordString);
    }

    @Then("^I should see a confirmation message indicating that the password was manually reset successfully$")
    public void iShouldSeeAConfirmationMessageIndicatingThatThePasswordWasChanged() {
        String successMessage = messageSource
                .getMessage(ManualResetPasswordController.MANUAL_RESET_PASSWORD_SUCCESS);
        commonSteps.iShouldSee(successMessage);
    }

    @Then("^I should see a message indicating that I am able to login with new credentials$")
    public void iShouldSeeAMessageIndicatingThatIamAbleToLoginWithNewCredentials() {
        String message = messageSource.getMessage(LOGIN_USE_NEW_PASSWORD_MESSAGE);
        withBehavior(HasNotificationBehavior.class).assertNotificationMessage(message);
    }

    private void changePassword(String password, String confirmPassword, String isConfirmationRequired)
            throws Exception {
        commonSteps.theUserFillsInValueForField(password, AbstractChangePasswordPage.PASSWORD_FIELD);
        sendChangeEventByAlias(AbstractChangePasswordPage.PASSWORD_FIELD);
        if (StringUtils.isEmpty(isConfirmationRequired)) {
            commonSteps.theUserFillsInValueForField(confirmPassword,
                    AbstractChangePasswordPage.CONFIRM_PASSWORD_FIELD);
            sendChangeEventByAlias(AbstractChangePasswordPage.CONFIRM_PASSWORD_FIELD);
            unfocusElement(AbstractChangePasswordPage.CONFIRM_PASSWORD_FIELD);
        }
    }

    @Then("^I should be notified that password cannot be same as username$")
    public void iShouldBeNotifiedPasswordCannotBeSameAsUsername() {
        currentPage(ManualResetPasswordPage.class).assertPasswordValidationError(messageSource);
    }

    @Given("^the reset password token \"([^\"]*)\" is (\\d+) hours old$")
    public void theResetPasswordToken12345Is25HoursOld(String tokenId, int hours) {
        UserPasswordToken passwordToken = userSetPasswordService.findUserPasswordToken(tokenId);
        passwordToken.setDate(passwordToken.getDate().minusHours(hours));
        userSetPasswordService.save(passwordToken);
    }

    @Given("^I forgot my password$")
    public void iForgotMyPassword() {
        loginStepsSupport.iAmNotLoggedIn();
        currentPage(LoginPage.class).forgotPassword();
    }

    @Then("^I should see a message indicating that a new password must be set$")
    public void iShouldSeeMessageIndicatingNewPasswordMustBeSet() {
        commonSteps.iShouldSeeMessageCode("NotEmpty.changePasswordForm.password");
    }

    @Then("the password for user \"([^\"]*)\" should be \"([^\"]*)\"")
    public void thePasswordForUserShouldBe(String username, String password) {
        User user = userService.findByUsernameWithContactInformation(username);
        assertThat(user.getPassword(), is(securityService.digestPassword(password, user)));
    }

    @Then("^the following passwords do not meet requirements$")
    public void theFollowingPasswordsDoNotMeetRequirements(DataTable passwords) throws Exception {
        currentPage(AbstractChangePasswordPage.class).open();
        for (DataTableRow row : passwords.getGherkinRows()) {
            String password = row.getCells().get(0);
            changePassword(password, password, AbstractChangePasswordPage.CONFIRM_PASSWORD_FIELD);
            commonSteps.iShouldSeeMessageCode("password.change.fail");
        }
    }

    @Then("^the following passwords do not match$")
    public void theFollowingPasswordsDoNotMatch(DataTable passwords) throws Exception {
        for (Map<String, String> row : passwords.asMaps()) {
            row = new CaseInsensitiveMap(row);
            changePassword(row.get("new password"), row.get("retype"), null);
            commonSteps.iShouldSeeMessageCode("password.mismatch");
        }
    }

}