Add component test for direct reply to comment

- we have found it challenging to add component tests that mount the
  tiptap editor, so we are stubbing it, which means that we will add e2e
tests to up the coverage of how much of the workflow has automated tests
This commit is contained in:
mattwr18 2020-01-23 13:05:36 +01:00
parent 9776efe760
commit d15037607c
5 changed files with 67 additions and 67 deletions

View File

@ -3,8 +3,11 @@ import Comment from './Comment.vue'
import Vuex from 'vuex' import Vuex from 'vuex'
const localVue = global.localVue const localVue = global.localVue
localVue.directive('scrollTo', jest.fn())
config.stubs['client-only'] = '<span><slot /></span>' config.stubs['client-only'] = '<span><slot /></span>'
config.stubs['nuxt-link'] = '<span><slot /></span>'
config.stubs['content-viewer'] = '<span><slot /></span>'
describe('Comment.vue', () => { describe('Comment.vue', () => {
let propsData let propsData

View File

@ -52,6 +52,7 @@ export default {
}, },
methods: { methods: {
reply(message) { reply(message) {
if (!this.$refs.editor.insertReply) return null
this.$refs.editor.insertReply(message) this.$refs.editor.insertReply(message)
}, },
updateEditorContent(value) { updateEditorContent(value) {
@ -136,8 +137,8 @@ export default {
query() { query() {
return minimisedUserQuery() return minimisedUserQuery()
}, },
result(result) { update({ User }) {
this.users = result.data.User this.users = User
}, },
}, },
}, },

View File

@ -1,10 +1,13 @@
import { config, mount } from '@vue/test-utils' import { config, mount } from '@vue/test-utils'
import CommentList from './CommentList' import CommentList from './CommentList'
import Comment from '~/components/Comment/Comment'
import Vuex from 'vuex' import Vuex from 'vuex'
import Vue from 'vue'
const localVue = global.localVue const localVue = global.localVue
localVue.filter('truncate', string => string) localVue.filter('truncate', string => string)
localVue.directive('scrollTo', jest.fn())
config.stubs['v-popover'] = '<span><slot /></span>' config.stubs['v-popover'] = '<span><slot /></span>'
config.stubs['nuxt-link'] = '<span><slot /></span>' config.stubs['nuxt-link'] = '<span><slot /></span>'
@ -102,8 +105,12 @@ describe('CommentList.vue', () => {
beforeEach(() => { beforeEach(() => {
wrapper = Wrapper() wrapper = Wrapper()
}) })
it.only('Comment emitted reply()', () => { it('Comment emitted reply()', () => {
wrapper.find('.comment-tag').vm.$emit('reply') wrapper.find(Comment).vm.$emit('reply', {
id: 'commentAuthorId',
slug: 'ogerly',
})
Vue.nextTick()
expect(wrapper.emitted('reply')).toEqual([ expect(wrapper.emitted('reply')).toEqual([
[ [
{ {

View File

@ -1,20 +1,20 @@
import { config, mount } from '@vue/test-utils' import { config, mount } from '@vue/test-utils'
import PostSlug from './index.vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import Vue from 'vue' import PostSlug from './index.vue'
import CommentList from '~/components/CommentList/CommentList'
config.stubs['client-only'] = '<span><slot /></span>' config.stubs['client-only'] = '<span><slot /></span>'
config.stubs['nuxt-link'] = '<span><slot /></span>' config.stubs['nuxt-link'] = '<span><slot /></span>'
config.stubs['router-link'] = '<span><slot /></span>' config.stubs['router-link'] = '<span><slot /></span>'
config.stubs['content-viewer'] = '<span><slot /></span>'
config.stubs['hc-editor'] = '<span><slot /></span>'
config.stubs['hc-emotions'] = '<span><slot /></span>'
const localVue = global.localVue const localVue = global.localVue
localVue.directive('scrollTo', jest.fn())
describe('PostSlug', () => { describe('PostSlug', () => {
let wrapper let wrapper, Wrapper, store, mocks, propsData, spy
let Wrapper
let store
let mocks
let propsData
beforeEach(() => { beforeEach(() => {
store = new Vuex.Store({ store = new Vuex.Store({
@ -50,7 +50,38 @@ describe('PostSlug', () => {
query: jest.fn().mockResolvedValue(), query: jest.fn().mockResolvedValue(),
}, },
$scrollTo: jest.fn(), $scrollTo: jest.fn(),
$refs: {
editor: {
insertReply: jest.fn(),
},
commentForm: {
reply: jest.fn(),
},
},
} }
jest.useFakeTimers()
wrapper = Wrapper()
wrapper.setData({
post: {
id: '1',
author: {
id: '1stUser',
},
comments: [
{
id: 'comment134',
contentExcerpt: 'this is a comment',
content: 'this is a comment',
author: {
id: '1stUser',
slug: '1st-user',
},
},
],
},
ready: true,
})
spy = jest.spyOn(wrapper.vm, 'reply')
}) })
describe('mount', () => { describe('mount', () => {
@ -64,22 +95,9 @@ describe('PostSlug', () => {
} }
describe('test Post callbacks', () => { describe('test Post callbacks', () => {
beforeEach(() => {
wrapper = Wrapper()
// wrapper.setData({
// post: {
// id: 'p23',
// name: 'It is a post',
// author: {
// id: 'u1',
// },
// },
// })
})
describe('deletion of Post from Page by invoking "deletePostCallback()"', () => { describe('deletion of Post from Page by invoking "deletePostCallback()"', () => {
beforeEach(() => { beforeEach(async () => {
wrapper.vm.deletePostCallback() await wrapper.vm.deletePostCallback()
}) })
describe('after timeout', () => { describe('after timeout', () => {
@ -100,35 +118,13 @@ describe('PostSlug', () => {
}) })
}) })
describe('test Post callbacks', () => { describe('reply method called when emitted reply received', () => {
beforeEach(() => { it('CommentList', async () => {
beforeEach(jest.useFakeTimers) wrapper.find(CommentList).vm.$emit('reply', {
wrapper = Wrapper() id: 'commentAuthorId',
}) slug: 'ogerly',
it('CommentList', () => {
wrapper.setData({
post: {
id: 1,
author: {
id: '1stUser',
},
comments: [
{
id: 'comment134',
contentExcerpt: 'this is a comment',
content: 'this is a comment',
author: {
id: '1stUser',
slug: '1st-user',
},
},
],
},
}) })
jest.runAllTimers() expect(spy).toHaveBeenCalledTimes(1)
Vue.nextTick()
const spy = jest.spyOn(wrapper.vm, 'reply')
expect(spy).toBe(true)
}) })
}) })
}) })

View File

@ -84,8 +84,7 @@
</ds-space> </ds-space>
<!-- Comments --> <!-- Comments -->
<ds-section slot="footer"> <ds-section slot="footer">
<hc-comment-list <comment-list
class="hc-comment-list-for-test"
:post="post" :post="post"
:routeHash="$route.hash" :routeHash="$route.hash"
@toggleNewCommentForm="toggleNewCommentForm" @toggleNewCommentForm="toggleNewCommentForm"
@ -111,7 +110,7 @@ import ContentMenu from '~/components/ContentMenu/ContentMenu'
import UserTeaser from '~/components/UserTeaser/UserTeaser' import UserTeaser from '~/components/UserTeaser/UserTeaser'
import HcShoutButton from '~/components/ShoutButton.vue' import HcShoutButton from '~/components/ShoutButton.vue'
import HcCommentForm from '~/components/CommentForm/CommentForm' import HcCommentForm from '~/components/CommentForm/CommentForm'
import HcCommentList from '~/components/CommentList/CommentList' import CommentList from '~/components/CommentList/CommentList'
import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers' import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers'
import PostQuery from '~/graphql/PostQuery' import PostQuery from '~/graphql/PostQuery'
import HcEmotions from '~/components/Emotions/Emotions' import HcEmotions from '~/components/Emotions/Emotions'
@ -130,7 +129,7 @@ export default {
HcShoutButton, HcShoutButton,
ContentMenu, ContentMenu,
HcCommentForm, HcCommentForm,
HcCommentList, CommentList,
HcEmotions, HcEmotions,
ContentViewer, ContentViewer,
}, },
@ -142,19 +141,12 @@ export default {
data() { data() {
return { return {
post: null, post: null,
ready: true, ready: false,
title: 'loading', title: 'loading',
showNewCommentForm: true, showNewCommentForm: true,
blurred: false, blurred: false,
} }
}, },
watch: {
Post(post) {
this.post = post[0] || {}
this.title = this.post.title
this.blurred = this.post.imageBlurred
},
},
mounted() { mounted() {
setTimeout(() => { setTimeout(() => {
// NOTE: quick fix for jumping flexbox implementation // NOTE: quick fix for jumping flexbox implementation
@ -227,8 +219,9 @@ export default {
} }
}, },
update({ Post }) { update({ Post }) {
this.post = Post this.post = Post[0] || {}
this.title = this.post.title this.title = this.post.title
this.blurred = this.post.imageBlurred
}, },
fetchPolicy: 'cache-and-network', fetchPolicy: 'cache-and-network',
}, },