From 482ac1572b9dea37af8d516b96542b69e8df3460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 13 Jun 2019 19:23:13 +0200 Subject: [PATCH] Refactored and created the tests of DeletePostCallback Created a folder `utils` for PostHelpers.js. Fixed a new incoming problem of the master with deleting Posts on the User Profile. Co-Authored-By: mattwr18 --- webapp/components/Comment.spec.js | 6 +- webapp/components/Comment.vue | 33 ++--- webapp/components/Modal/ConfirmModal.spec.js | 7 +- webapp/components/Modal/DisableModal.spec.js | 12 +- webapp/components/Modal/ReportModal.spec.js | 4 - webapp/components/Modal/ReportModal.vue | 4 +- webapp/components/PostCard/index.spec.js | 130 ++++++++++++++++++ webapp/components/PostCard/index.vue | 6 +- webapp/components/PostCard/spec.js | 61 -------- .../comments/CommentList/CommentList.spec.js | 22 ++- webapp/components/{ => utils}/PostHelpers.js | 0 webapp/pages/post/_id/_slug/index.spec.js | 18 +-- webapp/pages/post/_id/_slug/index.vue | 6 +- webapp/pages/profile/_id/_slug.spec.js | 55 ++++---- webapp/pages/profile/_id/_slug.vue | 19 ++- 15 files changed, 233 insertions(+), 150 deletions(-) create mode 100644 webapp/components/PostCard/index.spec.js delete mode 100644 webapp/components/PostCard/spec.js rename webapp/components/{ => utils}/PostHelpers.js (100%) diff --git a/webapp/components/Comment.spec.js b/webapp/components/Comment.spec.js index 6057599a0..4fdc48bbd 100644 --- a/webapp/components/Comment.spec.js +++ b/webapp/components/Comment.spec.js @@ -25,12 +25,12 @@ describe('Comment.vue', () => { success: jest.fn(), error: jest.fn(), }, - $apollo: { - mutate: jest.fn().mockResolvedValue(), - }, $filters: { truncate: a => a, }, + $apollo: { + mutate: jest.fn().mockResolvedValue(), + }, } getters = { 'auth/user': () => { diff --git a/webapp/components/Comment.vue b/webapp/components/Comment.vue index 9ff0536ca..67bdb92a8 100644 --- a/webapp/components/Comment.vue +++ b/webapp/components/Comment.vue @@ -15,7 +15,6 @@ placement="bottom-end" resource-type="comment" :resource="comment" - :callbacks="{ confirm: deleteCommentCallback, cancel: null }" :modalsData="menuModalsData" style="float-right" :is-owner="isAuthor(author.id)" @@ -49,9 +48,20 @@ export default { }, dateTime: { type: [Date, String], default: null }, }, - data() { - return { - menuModalsData: { + computed: { + ...mapGetters({ + user: 'auth/user', + isModerator: 'auth/isModerator', + }), + displaysComment() { + return !this.unavailable || this.isModerator + }, + author() { + if (this.deleted) return {} + return this.comment.author || {} + }, + menuModalsData() { + return { delete: { titleIdent: 'delete.comment.title', messageIdent: 'delete.comment.message', @@ -72,20 +82,7 @@ export default { }, }, }, - }, - } - }, - computed: { - ...mapGetters({ - user: 'auth/user', - isModerator: 'auth/isModerator', - }), - displaysComment() { - return !this.unavailable || this.isModerator - }, - author() { - if (this.deleted) return {} - return this.comment.author || {} + } }, }, methods: { diff --git a/webapp/components/Modal/ConfirmModal.spec.js b/webapp/components/Modal/ConfirmModal.spec.js index affd766dd..86a6dd39d 100644 --- a/webapp/components/Modal/ConfirmModal.spec.js +++ b/webapp/components/Modal/ConfirmModal.spec.js @@ -2,7 +2,7 @@ import { shallowMount, mount, createLocalVue } from '@vue/test-utils' import Vuex from 'vuex' import Styleguide from '@human-connection/styleguide' import ConfirmModal from './ConfirmModal.vue' -import PostHelpers from '~/components/PostHelpers' +import { postMenuModalsData } from '~/components/utils/PostHelpers' const localVue = createLocalVue() @@ -23,7 +23,7 @@ describe('ConfirmModal.vue', () => { type: 'contribution', id: 'p23', name: postName, - modalData: PostHelpers.postMenuModalsData(postName, confirmCallback, cancelCallback).delete, + modalData: postMenuModalsData(postName, confirmCallback, cancelCallback).delete, } mocks = { $t: jest.fn(), @@ -143,7 +143,8 @@ describe('ConfirmModal.vue', () => { it('does call the confirm callback', () => { expect(confirmCallback).toHaveBeenCalledTimes(1) }) - it('emits close', () => { + + it('emits "close"', () => { expect(wrapper.emitted().close).toHaveLength(1) }) diff --git a/webapp/components/Modal/DisableModal.spec.js b/webapp/components/Modal/DisableModal.spec.js index 4780657ee..b5ebf888c 100644 --- a/webapp/components/Modal/DisableModal.spec.js +++ b/webapp/components/Modal/DisableModal.spec.js @@ -16,10 +16,6 @@ describe('DisableModal.vue', () => { type: 'contribution', id: 'c42', name: 'blah', - callbacks: { - confirm: jest.fn(), - cancel: jest.fn(), - }, } mocks = { $filters: { @@ -33,8 +29,12 @@ describe('DisableModal.vue', () => { $apollo: { mutate: jest .fn() - .mockResolvedValueOnce({ enable: 'u4711' }) - .mockRejectedValue({ message: 'Not Authorised!' }), + .mockResolvedValueOnce({ + enable: 'u4711', + }) + .mockRejectedValue({ + message: 'Not Authorised!', + }), }, location: { reload: jest.fn(), diff --git a/webapp/components/Modal/ReportModal.spec.js b/webapp/components/Modal/ReportModal.spec.js index 27262e998..7f6fb33f1 100644 --- a/webapp/components/Modal/ReportModal.spec.js +++ b/webapp/components/Modal/ReportModal.spec.js @@ -17,10 +17,6 @@ describe('ReportModal.vue', () => { propsData = { type: 'contribution', id: 'c43', - callbacks: { - confirm: jest.fn(), - cancel: jest.fn(), - }, } mocks = { $t: jest.fn(), diff --git a/webapp/components/Modal/ReportModal.vue b/webapp/components/Modal/ReportModal.vue index 19b226951..54721839e 100644 --- a/webapp/components/Modal/ReportModal.vue +++ b/webapp/components/Modal/ReportModal.vue @@ -66,9 +66,9 @@ export default { }, async confirm() { this.loading = true - // TODO: Use the "modalData" structure introduced in "ConfirmModal" and refactor this here. Be aware that all the Jest tests have to be refactored as well !!! - // await this.modalData.buttons.confirm.callback() try { + // TODO: Use the "modalData" structure introduced in "ConfirmModal" and refactor this here. Be aware that all the Jest tests have to be refactored as well !!! + // await this.modalData.buttons.confirm.callback() await this.$apollo.mutate({ mutation: gql` mutation($id: ID!) { diff --git a/webapp/components/PostCard/index.spec.js b/webapp/components/PostCard/index.spec.js new file mode 100644 index 000000000..390396383 --- /dev/null +++ b/webapp/components/PostCard/index.spec.js @@ -0,0 +1,130 @@ +import { config, shallowMount, mount, createLocalVue, RouterLinkStub } from '@vue/test-utils' +import Styleguide from '@human-connection/styleguide' +import Vuex from 'vuex' +import Filters from '~/plugins/vue-filters' +import PostCard from '.' + +const localVue = createLocalVue() + +localVue.use(Vuex) +localVue.use(Styleguide) +localVue.use(Filters) + +config.stubs['no-ssr'] = '' +config.stubs['v-popover'] = '' + +describe('PostCard', () => { + let store + let stubs + let mocks + let propsData + let getters + let Wrapper + let wrapper + + beforeEach(() => { + propsData = { + post: { + id: 'p23', + name: 'It is a post', + author: { + id: 'u1', + }, + disabled: false, + }, + } + store = new Vuex.Store({ + getters: { + 'auth/user': () => { + return {} + }, + }, + }) + stubs = { + NuxtLink: RouterLinkStub, + } + mocks = { + $t: jest.fn(), + $toast: { + success: jest.fn(), + error: jest.fn(), + }, + $apollo: { + mutate: jest.fn().mockResolvedValue(), + }, + } + getters = { + 'auth/user': () => { + return {} + }, + } + }) + + describe('shallowMount', () => { + Wrapper = () => { + return shallowMount(PostCard, { + store, + propsData, + mocks, + localVue, + }) + } + + beforeEach(jest.useFakeTimers) + + describe('test Post callbacks', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + describe('deletion of Post from Page by invoking "deletePostCallback()"', () => { + beforeEach(() => { + wrapper.vm.deletePostCallback() + }) + + describe('after timeout', () => { + beforeEach(jest.runAllTimers) + + it('does call mutation', () => { + expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1) + }) + + it('mutation is successful', () => { + expect(mocks.$toast.success).toHaveBeenCalledTimes(1) + }) + + it('emits "removePostFromList"', () => { + expect(wrapper.emitted().removePostFromList).toHaveLength(1) + }) + }) + }) + }) + }) + + describe('mount', () => { + Wrapper = () => { + const store = new Vuex.Store({ + getters, + }) + return mount(PostCard, { + stubs, + mocks, + propsData, + store, + localVue, + }) + } + + describe('given a post', () => { + beforeEach(() => { + propsData.post = { + title: "It's a title", + } + }) + + it('renders title', () => { + expect(Wrapper().text()).toContain("It's a title") + }) + }) + }) +}) diff --git a/webapp/components/PostCard/index.vue b/webapp/components/PostCard/index.vue index 383f879bd..288f3cd8a 100644 --- a/webapp/components/PostCard/index.vue +++ b/webapp/components/PostCard/index.vue @@ -70,7 +70,7 @@ import HcCategory from '~/components/Category' import HcRibbon from '~/components/Ribbon' // import { randomBytes } from 'crypto' import { mapGetters } from 'vuex' -import PostHelpers from '~/components/PostHelpers' +import { postMenuModalsData, deletePostMutationData } from '~/components/utils/PostHelpers' export default { name: 'HcPostCard', @@ -103,7 +103,7 @@ export default { return this.user.id === this.post.author.id }, menuModalsData() { - return PostHelpers.postMenuModalsData( + return postMenuModalsData( // "this.post" may not always be defined at the beginning … this.post ? this.$filters.truncate(this.post.title, 30) : '', this.deletePostCallback, @@ -113,7 +113,7 @@ export default { methods: { async deletePostCallback() { try { - await this.$apollo.mutate(PostHelpers.deletePostMutationData(this.post.id)) + await this.$apollo.mutate(deletePostMutationData(this.post.id)) this.$toast.success(this.$t('delete.contribution.success')) this.$emit('removePostFromList') } catch (err) { diff --git a/webapp/components/PostCard/spec.js b/webapp/components/PostCard/spec.js deleted file mode 100644 index 8f818b26b..000000000 --- a/webapp/components/PostCard/spec.js +++ /dev/null @@ -1,61 +0,0 @@ -import { config, mount, createLocalVue, RouterLinkStub } from '@vue/test-utils' -import PostCard from '.' -import Styleguide from '@human-connection/styleguide' -import Vuex from 'vuex' -import Filters from '~/plugins/vue-filters' - -const localVue = createLocalVue() - -localVue.use(Vuex) -localVue.use(Styleguide) -localVue.use(Filters) - -config.stubs['no-ssr'] = '' -config.stubs['v-popover'] = '' - -describe('PostCard', () => { - let stubs - let mocks - let propsData - let getters - - beforeEach(() => { - propsData = {} - stubs = { - NuxtLink: RouterLinkStub, - } - mocks = { - $t: jest.fn(), - } - getters = { - 'auth/user': () => { - return {} - }, - } - }) - - const Wrapper = () => { - const store = new Vuex.Store({ - getters, - }) - return mount(PostCard, { - stubs, - mocks, - propsData, - store, - localVue, - }) - } - - describe('given a post', () => { - beforeEach(() => { - propsData.post = { - title: "It's a title", - } - }) - - it('renders title', () => { - expect(Wrapper().text()).toContain("It's a title") - }) - }) -}) diff --git a/webapp/components/comments/CommentList/CommentList.spec.js b/webapp/components/comments/CommentList/CommentList.spec.js index 9bfa13ea5..c20ec069f 100644 --- a/webapp/components/comments/CommentList/CommentList.spec.js +++ b/webapp/components/comments/CommentList/CommentList.spec.js @@ -22,7 +22,9 @@ describe('CommentList.vue', () => { let data propsData = { - post: { id: 1 }, + post: { + id: 1, + }, } store = new Vuex.Store({ getters: { @@ -33,6 +35,9 @@ describe('CommentList.vue', () => { }) mocks = { $t: jest.fn(), + $filters: { + truncate: a => a, + }, $apollo: { queries: { Post: { @@ -49,13 +54,24 @@ describe('CommentList.vue', () => { describe('shallowMount', () => { const Wrapper = () => { - return mount(CommentList, { store, mocks, localVue, propsData, data }) + return mount(CommentList, { + store, + mocks, + localVue, + propsData, + data, + }) } beforeEach(() => { wrapper = Wrapper() wrapper.setData({ - comments: [{ id: 'c1', contentExcerpt: 'this is a comment' }], + comments: [ + { + id: 'c1', + contentExcerpt: 'this is a comment', + }, + ], }) }) diff --git a/webapp/components/PostHelpers.js b/webapp/components/utils/PostHelpers.js similarity index 100% rename from webapp/components/PostHelpers.js rename to webapp/components/utils/PostHelpers.js diff --git a/webapp/pages/post/_id/_slug/index.spec.js b/webapp/pages/post/_id/_slug/index.spec.js index 8a073ac6e..33916c7a5 100644 --- a/webapp/pages/post/_id/_slug/index.spec.js +++ b/webapp/pages/post/_id/_slug/index.spec.js @@ -56,7 +56,7 @@ describe('PostSlug', () => { beforeEach(jest.useFakeTimers) - describe('test "PostHelpers"', () => { + describe('test Post callbacks', () => { beforeEach(() => { wrapper = Wrapper() wrapper.setData({ @@ -70,22 +70,14 @@ describe('PostSlug', () => { }) }) - describe('deletion of Post from Page by invoking "deletePostCallback(`page`)"', () => { + describe('deletion of Post from Page by invoking "deletePostCallback()"', () => { beforeEach(() => { - wrapper.vm.deletePostCallback('page') + wrapper.vm.deletePostCallback() }) describe('after timeout', () => { beforeEach(jest.runAllTimers) - it('not emits "deletePost"', () => { - expect(wrapper.emitted().deletePost).toBeFalsy() - }) - - it('does go to index (main) page', () => { - expect(mocks.$router.history.push).toHaveBeenCalledTimes(1) - }) - it('does call mutation', () => { expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1) }) @@ -93,6 +85,10 @@ describe('PostSlug', () => { it('mutation is successful', () => { expect(mocks.$toast.success).toHaveBeenCalledTimes(1) }) + + it('does go to index (main) page', () => { + expect(mocks.$router.history.push).toHaveBeenCalledTimes(1) + }) }) }) }) diff --git a/webapp/pages/post/_id/_slug/index.vue b/webapp/pages/post/_id/_slug/index.vue index 899950514..45d9aae02 100644 --- a/webapp/pages/post/_id/_slug/index.vue +++ b/webapp/pages/post/_id/_slug/index.vue @@ -71,7 +71,7 @@ import HcUser from '~/components/User' import HcShoutButton from '~/components/ShoutButton.vue' import HcCommentForm from '~/components/comments/CommentForm' import HcCommentList from '~/components/comments/CommentList' -import PostHelpers from '~/components/PostHelpers' +import { postMenuModalsData, deletePostMutationData } from '~/components/utils/PostHelpers' export default { name: 'PostSlug', @@ -211,7 +211,7 @@ export default { }, computed: { menuModalsData() { - return PostHelpers.postMenuModalsData( + return postMenuModalsData( // "this.post" may not always be defined at the beginning … this.post ? this.$filters.truncate(this.post.title, 30) : '', this.deletePostCallback, @@ -224,7 +224,7 @@ export default { }, async deletePostCallback() { try { - await this.$apollo.mutate(PostHelpers.deletePostMutationData(this.post.id)) + await this.$apollo.mutate(deletePostMutationData(this.post.id)) this.$toast.success(this.$t('delete.contribution.success')) this.$router.history.push('/') // Redirect to index (main) page } catch (err) { diff --git a/webapp/pages/profile/_id/_slug.spec.js b/webapp/pages/profile/_id/_slug.spec.js index 4adb67024..c9faafffc 100644 --- a/webapp/pages/profile/_id/_slug.spec.js +++ b/webapp/pages/profile/_id/_slug.spec.js @@ -1,17 +1,17 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils' -import ProfileSlug from './_slug.vue' +import { config, mount } from '@vue/test-utils' +import HcUserProfile from './_slug.vue' import Vuex from 'vuex' -import Styleguide from '@human-connection/styleguide' +import Vue from 'vue' -const localVue = createLocalVue() +config.stubs['ds-space'] = '
Hello, Wolle
' -localVue.use(Vuex) -localVue.use(Styleguide) +Vue.use(Vuex) describe('ProfileSlug', () => { let wrapper let Wrapper let mocks + let getters beforeEach(() => { mocks = { @@ -21,6 +21,12 @@ describe('ProfileSlug', () => { }, $t: jest.fn(), // If you mocking router, than don't use VueRouter with lacalVue: https://vue-test-utils.vuejs.org/guides/using-with-vue-router.html + $route: { + params: { + id: '4711', + slug: 'john-doe', + }, + }, $router: { history: { push: jest.fn(), @@ -34,13 +40,24 @@ describe('ProfileSlug', () => { mutate: jest.fn().mockResolvedValue(), }, } + getters = { + 'auth/user': () => { + return { + slug: 'john-doe', + id: '4711', + } + }, + } }) - describe('shallowMount', () => { + describe('mount', () => { Wrapper = () => { - return shallowMount(ProfileSlug, { + const store = new Vuex.Store({ + getters, + }) + return mount(HcUserProfile, { + store, mocks, - localVue, }) } @@ -52,27 +69,13 @@ describe('ProfileSlug', () => { }) describe('deletion of Post from List by invoking "deletePostCallback(`list`)"', () => { - beforeEach(() => { - wrapper.vm.deletePostCallback('list') - }) + beforeEach(() => {}) describe('after timeout', () => { beforeEach(jest.runAllTimers) - it.skip('emits "deletePost"', () => { - expect(wrapper.emitted().deletePost).toHaveLength(1) - }) - - it.skip('does not go to index (main) page', () => { - expect(mocks.$router.history.push).not.toHaveBeenCalled() - }) - - it.skip('does call mutation', () => { - expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1) - }) - - it.skip('mutation is successful', () => { - expect(mocks.$toast.success).toHaveBeenCalledTimes(1) + it('fetches the user', () => { + expect(wrapper.is('div')).toBe(true) }) }) }) diff --git a/webapp/pages/profile/_id/_slug.vue b/webapp/pages/profile/_id/_slug.vue index 05d50e68b..e27f890a8 100644 --- a/webapp/pages/profile/_id/_slug.vue +++ b/webapp/pages/profile/_id/_slug.vue @@ -204,7 +204,7 @@ :key="post.id" :post="post" :width="{ base: '100%', md: '100%', xl: '50%' }" - @removePostFromList="user.contributions.splice(index, 1)" + @removePostFromList="activePosts.splice(index, 1)" />