@Test
 public void testSpacesPermittted() throws Exception {
   ChangePasswordForm form = new ChangePasswordForm();
   form.setPassword("Ben Kingsley  is my no. 1 actor");
   form.setRetypedPassword("Ben Kingsley  is my no. 1 actor");
   form.setOldPassword("ååååååå1å");
   Set<ConstraintViolation<ChangePasswordForm>> errors = validator.validate(form);
   assertEquals("Should be no errors", 0, errors.size());
 }
 @Test
 public void allValuesPopulatedHappyPath() {
   ChangePasswordForm form = new ChangePasswordForm();
   form.setOldPassword("0ldPassw$rd");
   form.setPassword("passw0rd");
   form.setRetypedPassword("passw0rd");
   Set<ConstraintViolation<ChangePasswordForm>> errors = validator.validate(form);
   assertEquals("Should be no errors", 0, errors.size());
 }
 @Test
 public void testNonUsAsciiCharsPermitted() throws Exception {
   ChangePasswordForm form = new ChangePasswordForm();
   form.setOldPassword("passw0rd");
   form.setPassword("ååååååå1å");
   form.setRetypedPassword("ååååååå1å");
   Set<ConstraintViolation<ChangePasswordForm>> errors = validator.validate(form);
   assertEquals("Should be no errors", 0, errors.size());
 }
  @Test
  public void testPasswordLengthMin8() {
    ChangePasswordForm form = new ChangePasswordForm();
    form.setPassword("a$1");
    Set<ConstraintViolation<ChangePasswordForm>> violations = validator.validate(form);
    Map<String, String> allErrorValues = retrieveErrorKeyAndMessage(violations);
    String password = allErrorValues.get("password");
    assertEquals(
        "Passwords must be 8 or more characters and contain at least 1 number and at least 1 alpha character or symbol",
        password);

    form.setPassword("a$1a$1a$1");
    violations = validator.validate(form);
    allErrorValues = retrieveErrorKeyAndMessage(violations);
    password = allErrorValues.get("password");
    assertNull(password);
  }
  @Test
  public void testPasswordsMatchValidation() throws Exception {
    String eightMixedCharactersDigitsAndSymbol = "p4s]sW[rd";
    String incorrectRetype = "p4s]sT]rd";

    ChangePasswordForm form = new ChangePasswordForm();
    form.setPassword(eightMixedCharactersDigitsAndSymbol);
    form.setRetypedPassword(incorrectRetype);

    Set<ConstraintViolation<ChangePasswordForm>> 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("New password values don’t match. Please try again"));

    // 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"));
  }
  @Test
  public void testPasswordFormMissingData() {
    ChangePasswordForm form = new ChangePasswordForm();
    form.setOldPassword("");
    form.setPassword("");
    form.setRetypedPassword("");
    Set<ConstraintViolation<ChangePasswordForm>> violations = validator.validate(form);
    Map<String, String> allErrorValues = retrieveErrorKeyAndMessage(violations);

    String password = allErrorValues.get("password");
    String confirmedPassword = allErrorValues.get("retypedPassword");
    String oldPassword = allErrorValues.get("oldPassword");

    assertEquals(
        "Passwords must be 8 or more characters and contain at least 1 number and at least 1 alpha character or symbol",
        password);
    assertEquals(
        "Passwords must be 8 or more characters and contain at least 1 number and at least 1 alpha character or symbol",
        confirmedPassword);
    assertEquals(
        "Passwords must be 8 or more characters and contain at least 1 number and at least 1 alpha character or symbol",
        oldPassword);
  }
  @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 = "******";
    ChangePasswordForm form = new ChangePasswordForm();
    form.setPassword(tooShortPassword);
    Set<ConstraintViolation<ChangePasswordForm>> 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 testSymbolsPermitttedButNotRequired() throws Exception {
    ChangePasswordForm form = new ChangePasswordForm();
    form.setOldPassword("Ben Kingsley  is my no. 1 actor");
    form.setPassword("passw0rd");
    form.setRetypedPassword("passw0rd");
    Set<ConstraintViolation<ChangePasswordForm>> 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());
  }