Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing Vee-Validate confirmed rule

I am having some difficulty in testing a Vee-Validate confirmed function on a Vue form built with Vuetify. The component that I am trying to test looks like this:

<template>
    <form novalidate ref="loginForm" v-model="formValid" @submit.stop.prevent="formSubmitted" @keyup.enter="formSubmitted">
      <v-container grid-list-md text-xs-center>
        <v-layout column>
          <v-flex>
            <v-text-field
              name="passwordField"
              label="Enter your Password"
              hint="At least 6 characters"
              v-model="submissionDetails.password"
              :type="passwordShown ? 'text' : 'password'"
              min="6"
              required
              :append-icon="passwordShown ? 'visibility_off': 'visibility'"
              :append-icon-cb="()=>(passwordShown = !passwordShown)"
              v-validate="'required|min:6'"
              data-vv-name="password"
              :error-messages="errors.collect('password')"
              ref="password"
              @change="inputTriggered"
              @input="inputTriggered"
            />
          </v-flex>
          <v-flex v-show="createAccountTicked">
            <v-text-field
              name="confirmPasswordField"
              label="Confirm your Password"
              hint="At least 6 characters"
              v-model="confirmPassword"
              :type="passwordShown ? 'text' : 'password'"
              min="6"
              required
              :append-icon="passwordShown ? 'visibility_off': 'visibility'"
              :append-icon-cb="()=>(passwordShown = !passwordShown)"
              v-validate="'required|confirmed:$password'"
              data-vv-name="confirmPassword"
              :error-messages="errors.collect('confirmPassword')"/>
          </v-flex>
        </v-layout>
      </v-container>
    </form>
  </template>
  <script>
  export default {
    name: 'email-password-form',
    data () {
      return {
        submissionDetails: {
          email: '',
          password: ''
        },
        confirmPassword: '',
        passwordShown: false,
        createAccountTicked: false
      };
    }
  };
</script>

The above works fine with the error messages being displayed on the screen correctly and removed when the passwords match, but the below test fails:

 describe.only('validation', () => {
    it('should not attach an error to confirm password when it does match the password', async () => {
      const wrapper = mount(EmailPasswordForm, { localVue });
      wrapper.setData({
        submissionDetails: {
          password: 'wwwwww'
        },
        createAccountTicked: true,
        confirmPassword: 'wwwwww'
      });
      // await wrapper.vm.$validator.validateAll();
      // await wrapper.vm.$validator.validate('password');

      await wrapper.vm.$validator.validate('confirmPassword');

      console.log(wrapper.vm.errors.collect('confirmPassword'));
      // ['The confirmPassword confirmation does not match.']

      console.log(wrapper.vm.submissionDetails.password === wrapper.vm.confirmPassword);
      // true

      expect(wrapper.vm.errors.has('confirmPassword')).to.be.false;
      // AssertionError: expected true to be false
    });
  });

As can be seen from the above code, it appears that while the password and confirmPassword strings do match, the validator still flags the confirm password field as having an error. I can't understand why that might be but any help would be appreciated.

like image 592
JoeWemyss Avatar asked Dec 06 '22 12:12

JoeWemyss


2 Answers

So it turns out that this behaviour is due to how Vee-Validate compares values for multi-field validation, and how those values are propagated. (See this issue)

The easiest solution was to use the new is validation rule, which allows me to compare against the model, instead of the contents of the field. I just changed the v-validate rule contents from 'required|confirmed:$password' to v-validate="{required: true, is: submissionDetails.password}"

I'll leave this here in case anyone else has this issue.

like image 102
JoeWemyss Avatar answered Dec 18 '22 14:12

JoeWemyss


On my case, either one of this two methods works for me:

<input 
 v-validate="{ required : true,  confirmed: 'password'}" 
 type="password" name="confirm_password"  
 class="form-control" 
 placeholder="Confirm Password" 
 v-model="field.confirm_password" 
 data-vv-as="confirm password">

<input 
 v-validate="{ required : true,  confirmed: field.password}" 
 type="password" name="confirm_password"  
 class="form-control" 
 placeholder="Confirm Password" 
 v-model="field.confirm_password" 
 data-vv-as="confirm password">
like image 42
setsuna_shou Avatar answered Dec 18 '22 14:12

setsuna_shou