Write component tests, refactor

This commit is contained in:
Matt Rider 2019-08-02 10:52:36 +02:00
parent 76a720caec
commit 3da986518e
5 changed files with 166 additions and 37 deletions

View File

@ -0,0 +1,124 @@
import { mount, createLocalVue } from '@vue/test-utils'
import EmotionsButtons from './EmotionsButtons.vue'
import Styleguide from '@human-connection/styleguide'
import Vuex from 'vuex'
import PostMutations from '~/graphql/PostMutations.js'
const localVue = createLocalVue()
localVue.use(Styleguide)
localVue.use(Vuex)
describe('EmotionsButtons.vue', () => {
let wrapper
let mocks
let propsData
let getters
let funnyButton
let funnyImage
const funnyImageSrc = '/img/svg/emoji/funny_color.svg'
beforeEach(() => {
mocks = {
$apollo: {
mutate: jest
.fn()
.mockResolvedValueOnce({
data: {
AddPostEmotions: {
from: { id: 'u176' },
to: { id: 'p143' },
data: { emotion: 'happy' },
},
},
})
.mockResolvedValueOnce({
data: {
RemovePostEmotions: true,
},
}),
query: jest.fn().mockResolvedValue({
data: {
postsEmotionsCountByEmotion: 1,
},
}),
},
$t: jest.fn(),
}
propsData = {
post: { id: 'p143' },
}
getters = {
'auth/user': () => {
return { id: 'u176' }
},
}
})
describe('mount', () => {
const Wrapper = () => {
const store = new Vuex.Store({
getters,
})
return mount(EmotionsButtons, { mocks, propsData, store, localVue })
}
beforeEach(() => {
wrapper = Wrapper()
})
it("queries the post's emotions count for each of the 5 emotions", () => {
expect(mocks.$apollo.query).toHaveBeenCalledTimes(5)
})
describe('adding emotions', () => {
let expectedParams
beforeEach(() => {
wrapper.vm.postsEmotionsCountByEmotion.funny = 0
funnyButton = wrapper.findAll('button').at(0)
funnyButton.trigger('click')
})
it('shows the colored image when the button is active', () => {
funnyImage = wrapper.findAll('img').at(0)
expect(funnyImage.attributes().src).toEqual(funnyImageSrc)
})
it('sends the addPostEmotionsMutation for an emotion when clicked', () => {
expectedParams = {
mutation: PostMutations().addPostEmotionsMutation,
variables: { from: { id: 'u176' }, to: { id: 'p143' }, data: { emotion: 'funny' } },
}
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
})
it('increases the postEmotionsCountByEmotion for the emotion clicked', () => {
expect(wrapper.vm.postsEmotionsCountByEmotion.funny).toEqual(1)
})
it('adds an emotion to selectedEmotions to show the colored image when the button is active', () => {
expect(wrapper.vm.selectedEmotions).toEqual(['funny'])
})
describe('removing emotions', () => {
beforeEach(() => {
funnyButton.trigger('click')
})
it('sends the removePostEmotionsMutation when a user clicks on an active emotion', () => {
expectedParams = {
mutation: PostMutations().removePostEmotionsMutation,
variables: { from: { id: 'u176' }, to: { id: 'p143' }, data: { emotion: 'funny' } },
}
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
})
it('decreases the postEmotionsCountByEmotion for the emotion clicked', async () => {
expect(wrapper.vm.postsEmotionsCountByEmotion.funny).toEqual(0)
})
it('removes an emotion from selectedEmotions to show the default image', async () => {
expect(wrapper.vm.selectedEmotions).toEqual([])
})
})
})
})
})

View File

@ -3,13 +3,7 @@
<ds-flex :gutter="{ lg: 'large' }" class="emotions-flex"> <ds-flex :gutter="{ lg: 'large' }" class="emotions-flex">
<div v-for="emotion in Object.keys(postsEmotionsCountByEmotion)" :key="emotion"> <div v-for="emotion in Object.keys(postsEmotionsCountByEmotion)" :key="emotion">
<ds-flex-item :width="{ lg: '100%' }"> <ds-flex-item :width="{ lg: '100%' }">
<ds-button <ds-button size="large" ghost @click="toggleEmotion(emotion)" class="emotions-buttons">
:loading="loading"
size="large"
ghost
@click="toggleEmotion(emotion)"
class="emotions-buttons"
>
<img :src="iconPath(emotion)" width="53" /> <img :src="iconPath(emotion)" width="53" />
</ds-button> </ds-button>
<ds-space margin-bottom="xx-small" /> <ds-space margin-bottom="xx-small" />
@ -32,6 +26,8 @@
<script> <script>
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { postsEmotionsCountByCurrentUser } from '~/graphql/PostQuery.js'
import PostMutations from '~/graphql/PostMutations.js'
export default { export default {
props: { props: {
@ -39,7 +35,6 @@ export default {
}, },
data() { data() {
return { return {
loading: false,
selectedEmotions: [], selectedEmotions: [],
postsEmotionsCountByEmotion: { funny: 0, happy: 0, surprised: 0, cry: 0, angry: 0 }, postsEmotionsCountByEmotion: { funny: 0, happy: 0, surprised: 0, cry: 0, angry: 0 },
} }
@ -50,7 +45,6 @@ export default {
}), }),
}, },
mounted() { mounted() {
this.myEmotions()
Object.keys(this.postsEmotionsCountByEmotion).map(emotion => { Object.keys(this.postsEmotionsCountByEmotion).map(emotion => {
this.emotionsCount(emotion) this.emotionsCount(emotion)
}) })
@ -63,28 +57,18 @@ export default {
return `/img/svg/emoji/${emotion}.svg` return `/img/svg/emoji/${emotion}.svg`
}, },
toggleEmotion(emotion) { toggleEmotion(emotion) {
const addPostEmotionsMutation = gql`
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) {
AddPostEmotions(from: $from, to: $to, data: $data) {
emotion
}
}
`
const removePostEmotionsMutation = gql`
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) {
RemovePostEmotions(from: $from, to: $to, data: $data)
}
`
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: this.isActive(emotion) ? removePostEmotionsMutation : addPostEmotionsMutation, mutation: this.isActive(emotion)
? PostMutations().removePostEmotionsMutation
: PostMutations().addPostEmotionsMutation,
variables: { variables: {
from: { id: this.currentUser.id }, from: { id: this.currentUser.id },
to: { id: this.post.id }, to: { id: this.post.id },
data: { emotion }, data: { emotion },
}, },
}) })
.then(response => { .then(() => {
this.isActive(emotion) this.isActive(emotion)
? this.postsEmotionsCountByEmotion[emotion]-- ? this.postsEmotionsCountByEmotion[emotion]--
: this.postsEmotionsCountByEmotion[emotion]++ : this.postsEmotionsCountByEmotion[emotion]++
@ -117,19 +101,20 @@ export default {
this.postsEmotionsCountByEmotion[emotion] = postsEmotionsCountByEmotion this.postsEmotionsCountByEmotion[emotion] = postsEmotionsCountByEmotion
}) })
}, },
myEmotions() { },
this.$apollo apollo: {
.query({ postsEmotionsCountByCurrentUser: {
query: gql` query() {
query($postId: ID!) { return postsEmotionsCountByCurrentUser()
postsEmotionsCountByCurrentUser(postId: $postId) },
} variables() {
`, return {
variables: { postId: this.post.id }, postId: this.post.id,
}) }
.then(({ data: { postsEmotionsCountByCurrentUser } }) => { },
this.selectedEmotions = postsEmotionsCountByCurrentUser result({ data: { postsEmotionsCountByCurrentUser } }) {
}) this.selectedEmotions = postsEmotionsCountByCurrentUser
},
}, },
}, },
} }

View File

@ -60,5 +60,17 @@ export default () => {
} }
} }
`, `,
addPostEmotionsMutation: gql`
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) {
AddPostEmotions(from: $from, to: $to, data: $data) {
emotion
}
}
`,
removePostEmotionsMutation: gql`
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) {
RemovePostEmotions(from: $from, to: $to, data: $data)
}
`,
} }
} }

View File

@ -121,3 +121,11 @@ export const filterPosts = i18n => {
} }
` `
} }
export const postsEmotionsCountByCurrentUser = () => {
return gql`
query postsEmotionsCountByCurrentUser($postId: ID!) {
postsEmotionsCountByCurrentUser(postId: $postId)
}
`
}

View File

@ -31,7 +31,7 @@ describe('PostSlug', () => {
$filters: { $filters: {
truncate: a => a, truncate: a => a,
}, },
// If you mocking router, than don't use VueRouter with lacalVue: https://vue-test-utils.vuejs.org/guides/using-with-vue-router.html // If you are mocking the router, then don't use VueRouter with localVue: https://vue-test-utils.vuejs.org/guides/using-with-vue-router.html
$router: { $router: {
history: { history: {
push: jest.fn(), push: jest.fn(),