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