Problema entre store desde ACTIONS que llama a una API y testing con jest


#1

Hola, tengo un par de dudas, seguro que me podéis ayudar. Gracias de antemano.

La primera es:
Cuando yo entro a mi App.vue con ‘/’, este tiene que muestra un Main.vue.
La intención que yo tenía para/con este Main.vue, es que en el mounted, hacía un dispatch de una acción llamada FIND_USER.

Esta acción hacía una llamada a una API que me devuelve una Promise. Si no encuentra el usuario en la API se devuelve con reject y un error, y si lo encuentra con resolve.

En esta misma acción, pues tenía un then, un catch y un finally.
Al iniciar la acción seteo en el state un ‘loading’ que me muestra un spinner en la página.
Al hacer la petición, si todo va bien, hago con un commit en el estado ‘user’ para que el objeto que he recibido lo ponga.
Si ha habido un error, no me pone nada, y quería hacer un $router.push a una página de 404.
Y en el finally, quitaba el estado de ‘loading’, seteandolo a push con otro commit.

Los múltiples problemas que tengo vienen dados porque yo no puedo usar el router en las acciones. He visto soluciones y una sería setear el router como una variable global, lo cual no me gusta.

Así que lo que he hecho, y tampoco me gusta es llevarme al mounted de mi componente todo.
Es decir, importo la función (wrapper axios), que llama, y allí manejo el then, el catch y el finally.

Me gustaría llevarlo todo a estado, sobre todo porque en el comopnente también estoy haciendo la parte de setear el loading etc, y no sé, no me convence. Quería evitar también importar types y todo directamente en al vista.

Adjunto el código que he movido al componente.

mounted: function () {
if (this.onetimepw && this.onetimepw.length > 0) {
this.$store.commit(SET_LOADING)
user.getUser(this.onetimepw)
.then(user => {
this.$store.commit(SET_USER, user)
})
.catch(() => {
this.$router.push({ name: ‘404’ })
this.$store.commit(SET_USER, {})
})
.finally(() => {
this.$store.commit(REMOVE_LOADING)
})
} else {
this.$router.push({ name: ‘404’ })
}
}

Por otro lado, tengo problemas, desconocimiento para trabajar el test con jest, que compruebe que si está vacío o si no existe, me redirija al 404. De esta forma el componente si funciona así, pero el test no. Soy muy NOVATO con el tema de testing. Os adjunto el código.

describe('Main.vue', () => {
it('empty onetimepw redirect to 404', () => {
const localVue = createLocalVue()
localVue.use(VueRouter)
const router = new VueRouter()

shallowMount(maMain, {
  localVue,
  router,
  propsData: {
    onetimepw: 'dd'
  }
})

// todo
expect(window.location.pathname).toEqual('/404')

})

})

He probado de todo, con window.location.assign, o haciendo const mock = jest.fn(window.location.assign). El test falla porque me devuelve ‘/’ en vez de ‘/404’

Esta parte prácticamente comos i estuviera de cero. La prop que le paso viene del router, que se la paso como onetimepw.

props: route = ({ onetimepw: route.query.u })

Ahora el error que da el test es que no encuentra la función del dispatch of undefined.

Muchas gracias a todos por la ayuda.


#2

Hola @dmansof, ten en cuenta que esto es un foro de ayuda y todos dedican parte de su tiempo libre en ayudar. Para minimizar el tiempo que tendrian que invertir haz preguntas concretas y bien presentadas. Es decir una pregunta por post, con un ejemplo simple y comentado, en un contexto concreto, con pruebas de tu parte ya hechas, etc.

Voy a dar por solventado este post e invitarte a que abras uno o varios tickets nuevos teniendo en cuenta lo anterior. Saludos.


#3