4

I have this function which checks that the password and confirmPassword fields have the same value. If not, the form is marked a invalid

confirmPasswordValidator(passwordGroupForm: AbstractControl){

    let password = passwordGroupForm.get('password');
    let confirmPassword = passwordGroupForm.get('confirmPassword');
    console.log("password is "+password +"and confirmPassword is "+confirmPassword);


    console.log("confirm password touched",confirmPassword.touched );
    if(!confirmPassword.touched) return null ;//don't mark form invalid if the user hasn't interacted with confirmPassword field
    else {
      return (password.value === confirmPassword.value) ? null : {
          confirmPasswordValidator: {
            valid: false,
            message: 'Password and Verify Password fields do not match'
          }
        }
      }
    }

I have written the following test case to check that the function works.

it('should not submit form if password and confirm password are not the same',()=>{
    let formControls = component.signupForm.controls;
    let userService = TestBed.get(UserManagementService);
    spyOn(userService,'addUser');
    formControls['firstName'].setValue("first");
    formControls['lastName'].setValue("last");
    formControls['email'].setValue("e@e.com");
    formControls['password'].setValue("aA1!1111");
    formControls['confirmPassword'].setValue("aA1!11112");

    fixture.detectChanges();
    formControls['confirmPassword'].markAsTouched();
console.log("after control touched, touch value is",formControls['confirmPassword'].markAsTouched());
    component.addUser();
    expect(component.signupForm.valid).toBeFalsy();
    expect(userService.addUser).not.toHaveBeenCalled();
  });

But the test case is failing with error Expected true to be falsy. In the browser window I can see that it is showing touched property as true as well as false!! (see the picture)

enter image description here

I can see that the confirmPassword field is not touched. What am I doing wrong?

Manu Chadha
  • 15,555
  • 19
  • 91
  • 184

1 Answers1

5

I had to mark the field dirty before setting its value

formControls['confirmPassword'].markAsTouched({onlySelf:true});
    formControls['confirmPassword'].setValue("aA1!11112");

It seems setValue runs the form validation and as the field is not marked touched at that time, the confirmPasswordValidator is run by Angular and it returns null making the form valid. Calling markAsTouched doesn't re-run the form validation and addUser then finds the form valid.

Manu Chadha
  • 15,555
  • 19
  • 91
  • 184