Login" />

Login" />

Login"/>

How to test if a form submit was successful with Vue Test Utils?

22 Views Asked by At

How do I test if a login was successful ?

I have a Login component

<template>
    <NavBar></NavBar>    
    <div id="login">
        <h1 style="text-align: center;">Login</h1>
        <form class="form">
            <label class="form-label" for="username">Username</label>
            <br/>
            <input class="form-field" type="text" name="username" v-model="input.username" placeholder="Username" />
            <br/>        
            <label class="form-label" for="password">Password</label>
            <br/>
            <input class="form-field" type="password" name="password" v-model="input.password" placeholder="Password" />
            <br/>
            <div style="text-align: center;" >
                <button class="form-field" type="button" v-on:click="login()">Login</button>
            </div>
            
            <br/>
            <span v-if="status==1">Authenticating...</span>
        </form>
        <div id="powered">
            Powered by <a href="#">TinyDrive</a>
        </div>
    </div>
</template>

<script>

import { store } from '../store';
import { api } from '../api';
import NavBar from '../components/NavBar.vue';

export default {
    name: 'Login',
    components: {
        NavBar
    },
    data() {
        return {
            input: {
                password: '',
                username: '',                
            },
            status: 0,
        };
    },
    methods: {
        async login() {
            if (this.input.username != "" && this.input.password != "") {
                this.status = 1; //loading
                const response = await api.login(this.input.username, this.input.password);
                // if (this.input.username == store.state.data.mockAccount.username && this.input.password == store.state.data.mockAccount.password) {
                if (response.status == true) {
                    store.setToken(response.token);
                    store.setAuthenticated(true);                    
                    // this.$emit("authenticated", true);
                    this.$router.replace({ name: "filemanager" });
                } else {
                    console.log(response.message);
                }
                this.status = 0; //default
            } else {
                console.log("A username and password must be present");
            }
        }
    }
}
</script>

and I want to test if, upon successful login, the rendered context will change with the following test snippet

test('submit the form', async () => {
    const wrapper = mount(Login, {
        global: {
            plugins: [router]
        }
    }) 
    
    expect(wrapper.html()).to.contain('class="form-field" type="text" name="username" placeholder="Username"')


    let username = wrapper.find("input[name=username]")
    username.element.value = 'test';

    let password = wrapper.find("input[type=password]")
    password.element.value = 'test1234';

    await wrapper.find('form').trigger('submit')
    
    //TODO: how do I test if either the rendered result or the current route?

})
1

There are 1 best solutions below

0
kondz1v On

You should mock store.api to control whether the api call is resolved/rejected. There should be two separate test cases for that.

Then, in the "successful" case you can assert if $router.replace was called with proper arguments. Docs: https://test-utils.vuejs.org/guide/advanced/vue-router

Router should be mocked as well. I'd suggest to make factory function for the component mounting to avoid redundancy.