/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.frontend.web.forms.validate; import org.junit.Before; import org.junit.Test; import org.orcid.frontend.web.forms.ManagePasswordOptionsForm; import org.springframework.test.context.web.WebAppConfiguration; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import java.util.Map; import java.util.Set; import static org.junit.Assert.*; /** * Test Scenarios for the validation of fields on the password options form on * the Manage Profile Screen. Much of the validation is similar to the * {@link VerifyRegistrationForm} but the forms use delegation so any validation * can be split out in future if need be. * * @author jamesb * @See {@link VerifyRegistrationForm} * */ @WebAppConfiguration public class ManagePasswordOptionsValidationFormTest extends AbstractConstraintValidator<ManagePasswordOptionsForm> { Validator validator; @Before public void resetValidator() { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); validator = factory.getValidator(); } @Test public void allValuesPopulatedHappyPath() { ManagePasswordOptionsForm form = new ManagePasswordOptionsForm(); form.setPassword("passw0rd"); form.setRetypedPassword("passw0rd"); form.setSecurityQuestionId(1); form.setSecurityQuestionAnswer("stan"); form.setVerificationNumber("9999"); Set<ConstraintViolation<ManagePasswordOptionsForm>> errors = validator.validate(form); assertEquals("Should be no errors", 0, errors.size()); } @Test public void testNonUsAsciiCharsPermitted() throws Exception { ManagePasswordOptionsForm form = new ManagePasswordOptionsForm(); form.setPassword("ååååååå1å"); form.setRetypedPassword("ååååååå1å"); form.setSecurityQuestionId(1); form.setSecurityQuestionAnswer("stan"); form.setVerificationNumber("9999"); Set<ConstraintViolation<ManagePasswordOptionsForm>> errors = validator.validate(form); assertEquals("Should be no errors", 0, errors.size()); } @Test public void testSpacesPermittted() throws Exception { ManagePasswordOptionsForm form = new ManagePasswordOptionsForm(); form.setPassword("Stellan Skasgård is my no. 1 actor"); form.setRetypedPassword("Stellan Skasgård is my no. 1 actor"); form.setSecurityQuestionId(1); form.setSecurityQuestionAnswer("stan"); form.setVerificationNumber("9999"); Set<ConstraintViolation<ManagePasswordOptionsForm>> errors = validator.validate(form); assertEquals("Should be no errors", 0, errors.size()); } @Test public void testSymbolsPermitttedButNotRequired() throws Exception { ManagePasswordOptionsForm form = new ManagePasswordOptionsForm(); form.setPassword("passw0rd"); form.setRetypedPassword("passw0rd"); form.setSecurityQuestionId(1); form.setSecurityQuestionAnswer("stan"); form.setVerificationNumber("9999"); Set<ConstraintViolation<ManagePasswordOptionsForm>> errors = validator.validate(form); assertEquals("Should be no errors", 0, errors.size()); //check that the test doesn't break when symbols introduced form.setPassword("p$ssw0rd"); form.setRetypedPassword("p$ssw0rd"); errors = validator.validate(form); assertEquals("Should be no errors", 0, errors.size()); } @Test public void testPasswordFormMissingData() { ManagePasswordOptionsForm form = new ManagePasswordOptionsForm(); form.setPassword(""); form.setRetypedPassword(""); Set<ConstraintViolation<ManagePasswordOptionsForm>> violations = validator.validate(form); Map<String, String> allErrorValues = retrieveErrorKeyAndMessage(violations); String password = allErrorValues.get("password"); String confirmedPassword = allErrorValues.get("retypedPassword"); String securityQuestion = allErrorValues.get("securityQuestionId"); String securityAnswer = allErrorValues.get("securityQuestionAnswer"); String digits = allErrorValues.get("verificationNumber"); assertEquals("Passwords must be 8 or more characters and contain at least 1 number and at least 1 alpha character or symbol", password); assertEquals("The confirm password field is invalid.", confirmedPassword); assertEquals("Please select a security question.", securityQuestion); assertEquals("Please provide an answer to your security question.", securityAnswer); assertEquals("Please enter a 4 digit verification number", digits); } @Test public void testRegistrationFormInvalidData() throws Exception { ManagePasswordOptionsForm form = new ManagePasswordOptionsForm(); form.setSecurityQuestionId(0); form.setVerificationNumber("999"); Set<ConstraintViolation<ManagePasswordOptionsForm>> violations = validator.validate(form); Map<String, String> allErrorValues = retrieveErrorKeyAndMessage(violations); String securityQuestion = allErrorValues.get("securityQuestionId"); String digits = allErrorValues.get("verificationNumber"); assertEquals("Please select a security question.", securityQuestion); assertEquals("Please enter a 4 digit verification number", digits); // also try a negative verification number just to make sure form.setVerificationNumber("-7299"); violations = validator.validate(form); allErrorValues = retrieveErrorKeyAndMessage(violations); digits = allErrorValues.get("verificationNumber"); assertEquals("Please enter a 4 digit verification number", digits); } @Test public void testPasswordFormatValidation() throws Exception { String pwErrorMessage = "Passwords must be 8 or more characters and contain at least 1 number and at least 1 alpha character or symbol"; String tooShortPassword = "pssword"; ManagePasswordOptionsForm form = new ManagePasswordOptionsForm(); form.setPassword(tooShortPassword); Set<ConstraintViolation<ManagePasswordOptionsForm>> violations = validator.validate(form); Map<String, String> allErrorValues = retrieveErrorKeyAndMessage(violations); String passwordValidationError = allErrorValues.get("password"); assertEquals(pwErrorMessage, passwordValidationError); String eightDigitsButLowerCaseAlphaOnly = "password"; form.setPassword(eightDigitsButLowerCaseAlphaOnly); violations = validator.validate(form); allErrorValues = retrieveErrorKeyAndMessage(violations); passwordValidationError = allErrorValues.get("password"); assertEquals(pwErrorMessage, passwordValidationError); String eightDigitsLowerUpperCaseButAlphaOnly = "pAssword"; form.setPassword(eightDigitsLowerUpperCaseButAlphaOnly); violations = validator.validate(form); allErrorValues = retrieveErrorKeyAndMessage(violations); passwordValidationError = allErrorValues.get("password"); assertEquals(pwErrorMessage, passwordValidationError); String eightCharactersLowerUpperCaseSymbol = "pAssw%rd"; form.setPassword(eightCharactersLowerUpperCaseSymbol); violations = validator.validate(form); allErrorValues = retrieveErrorKeyAndMessage(violations); passwordValidationError = allErrorValues.get("password"); assertEquals(pwErrorMessage, passwordValidationError); String eightMixedCharactersDigitsAndSymbol = "p4ssW&rd"; form.setPassword(eightMixedCharactersDigitsAndSymbol); violations = validator.validate(form); allErrorValues = retrieveErrorKeyAndMessage(violations); passwordValidationError = allErrorValues.get("password"); assertNull(passwordValidationError); String eightUpperCaseCharactersOnlyDigitsAndSymbol = "P4SSW&RD"; form.setPassword(eightUpperCaseCharactersOnlyDigitsAndSymbol); violations = validator.validate(form); allErrorValues = retrieveErrorKeyAndMessage(violations); passwordValidationError = allErrorValues.get("password"); assertNull(passwordValidationError); } @Test public void testPasswordsMatchValidation() throws Exception { String eightMixedCharactersDigitsAndSymbol = "p4s]sW[rd"; String incorrectRetype = "p4s]sT]rd"; ManagePasswordOptionsForm form = new ManagePasswordOptionsForm(); form.setPassword(eightMixedCharactersDigitsAndSymbol); form.setRetypedPassword(incorrectRetype); Set<ConstraintViolation<ManagePasswordOptionsForm>> violations = validator.validate(form); Map<String, String> allErrorValues = retrieveErrorKeyAndMessage(violations); String passwordFormatError = allErrorValues.get("password"); String retypedPasswordFormatError = allErrorValues.get("retypedPassword"); allErrorValues = retrieveErrorKeyAndMessage(violations); // the passwords themselves should be ok as they conform to the format, // problem is they don't match assertNull(passwordFormatError); assertNull(retypedPasswordFormatError); Set<String> fieldLevelErrors = retrieveErrorValuesOnly(violations); assertTrue(fieldLevelErrors.contains("The password and confirm password field must match")); // now match them form.setRetypedPassword("p4s]sW[rd"); violations = validator.validate(form); allErrorValues = retrieveErrorKeyAndMessage(violations); passwordFormatError = allErrorValues.get("password"); retypedPasswordFormatError = allErrorValues.get("retypedPassword"); allErrorValues = retrieveErrorKeyAndMessage(violations); assertNull(passwordFormatError); assertNull(retypedPasswordFormatError); fieldLevelErrors = retrieveErrorValuesOnly(violations); assertFalse(fieldLevelErrors.contains("The password and confirmed password must match")); } }