From 8bcb250951e626bbc7f7bc6e4af08f435a1e0609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 23 May 2019 10:22:36 +0200 Subject: [PATCH] Started to rewrite the tests of DeleteModal.vue --- webapp/components/ContentMenu.vue | 2 +- webapp/components/Modal.vue | 5 +- webapp/components/Modal/DeleteModal.spec.js | 31 ++- webapp/components/Modal/DeleteModal.vue | 11 +- webapp/components/Modal/DisableModal.spec.js | 1 + webapp/components/Modal/DisableModal.vue | 9 +- webapp/components/Modal/ReportModal.spec.js | 12 +- webapp/components/Modal/ReportModal.vue | 7 + webapp/components/PostCard/index.vue | 6 +- .../{Post.js => PostMutationHelpers.js} | 3 + webapp/mixins/PostMutationHelpers.spec.js | 71 +++++ webapp/package.json | 1 - webapp/pages/post/_id/_slug/index.vue | 4 +- webapp/pages/profile/_id/_slug.spec.js | 243 ++++++++++++++++++ webapp/pages/profile/_id/_slug.vue | 4 +- 15 files changed, 384 insertions(+), 26 deletions(-) rename webapp/mixins/{Post.js => PostMutationHelpers.js} (84%) create mode 100644 webapp/mixins/PostMutationHelpers.spec.js create mode 100644 webapp/pages/profile/_id/_slug.spec.js diff --git a/webapp/components/ContentMenu.vue b/webapp/components/ContentMenu.vue index 6ab42453c..2aaaafc13 100644 --- a/webapp/components/ContentMenu.vue +++ b/webapp/components/ContentMenu.vue @@ -61,7 +61,7 @@ export default { return value.match(/(contribution|comment|organization|user)/) } }, - callbacks: { type: Object, default: () => {} } + callbacks: { type: Object, required: true } }, computed: { routes() { diff --git a/webapp/components/Modal.vue b/webapp/components/Modal.vue index 0db4b74fd..6c0d33aba 100644 --- a/webapp/components/Modal.vue +++ b/webapp/components/Modal.vue @@ -6,6 +6,7 @@ :id="data.resource.id" :type="data.type" :name="name" + :callbacks="data.callbacks" @close="close" /> diff --git a/webapp/components/Modal/DeleteModal.spec.js b/webapp/components/Modal/DeleteModal.spec.js index 6127607a9..037e21351 100644 --- a/webapp/components/Modal/DeleteModal.spec.js +++ b/webapp/components/Modal/DeleteModal.spec.js @@ -1,4 +1,5 @@ import { shallowMount, mount, createLocalVue } from '@vue/test-utils' +import PostMutationHelpers from '~/mixins/PostMutationHelpers' import DeleteModal from './DeleteModal.vue' import Vue from 'vue' import Vuex from 'vuex' @@ -22,7 +23,11 @@ describe('DeleteModal.vue', () => { beforeEach(() => { propsData = { type: 'contribution', - id: 'p23' + id: 'p23', + callbacks: { + confirm: () => Post.methods.deletePostCallback('list'), + cancel: null + } } mocks = { $t: jest.fn(), @@ -59,7 +64,11 @@ describe('DeleteModal.vue', () => { propsData = { type: 'contribution', id: 'p23', - name: 'It is a post' + name: 'It is a post', + callbacks: { + confirm: () => Post.methods.deletePostCallback('list'), + cancel: null + } } }) @@ -78,7 +87,11 @@ describe('DeleteModal.vue', () => { propsData = { type: 'comment', id: 'c3', - name: 'It is the user of the comment' + name: 'It is the user of the comment', + callbacks: { + confirm: () => Post.methods.deletePostCallback('list'), + cancel: null + } } }) @@ -108,7 +121,11 @@ describe('DeleteModal.vue', () => { beforeEach(() => { propsData = { type: 'contribution', - id: 'p23' + id: 'p23', + callbacks: { + confirm: () => Post.methods.deletePostCallback('list'), + cancel: null + } } wrapper = Wrapper() }) @@ -177,7 +194,11 @@ describe('DeleteModal.vue', () => { beforeEach(() => { propsData = { type: 'comment', - id: 'c3' + id: 'c3', + callbacks: { + confirm: () => Post.methods.deletePostCallback('list'), + cancel: null + } } wrapper = Wrapper() }) diff --git a/webapp/components/Modal/DeleteModal.vue b/webapp/components/Modal/DeleteModal.vue index ace5d9097..d0ff2b791 100644 --- a/webapp/components/Modal/DeleteModal.vue +++ b/webapp/components/Modal/DeleteModal.vue @@ -53,8 +53,7 @@ export default { props: { name: { type: String, default: '' }, type: { type: String, required: true }, - confirmCallback: { type: Function, required: true }, - cancelCallback: { type: Function, default: null }, + callbacks: { type: Object, required: true }, id: { type: String, required: true } }, data() { @@ -75,8 +74,8 @@ export default { }, methods: { async cancel() { - if (!!this.cancelCallback) { - await this.cancelCallback() + if (!!this.callbacks.cancel) { + await this.callbacks.cancel() } this.isOpen = false setTimeout(() => { @@ -86,7 +85,9 @@ export default { async confirm() { this.loading = true try { - await this.confirmCallback() + if (!!this.callbacks.confirm) { + await this.callbacks.confirm() + } this.success = true setTimeout(() => { this.isOpen = false diff --git a/webapp/components/Modal/DisableModal.spec.js b/webapp/components/Modal/DisableModal.spec.js index e4debdc70..69c549833 100644 --- a/webapp/components/Modal/DisableModal.spec.js +++ b/webapp/components/Modal/DisableModal.spec.js @@ -17,6 +17,7 @@ describe('DisableModal.vue', () => { propsData = { type: 'contribution', name: 'blah', + callbacks: { confirm: null, cancel: null }, id: 'c42' } mocks = { diff --git a/webapp/components/Modal/DisableModal.vue b/webapp/components/Modal/DisableModal.vue index 4ab0293cd..19ac0f9b7 100644 --- a/webapp/components/Modal/DisableModal.vue +++ b/webapp/components/Modal/DisableModal.vue @@ -34,6 +34,7 @@ export default { props: { name: { type: String, default: '' }, type: { type: String, required: true }, + callbacks: { type: Object, required: true }, id: { type: String, required: true } }, data() { @@ -53,7 +54,10 @@ export default { } }, methods: { - cancel() { + async cancel() { + if (!!this.callbacks.cancel) { + await this.callbacks.cancel() + } this.isOpen = false setTimeout(() => { this.$emit('close') @@ -61,6 +65,9 @@ export default { }, async confirm() { try { + if (!!this.callbacks.confirm) { + await this.callbacks.confirm() + } await this.$apollo.mutate({ mutation: gql` mutation($id: ID!) { diff --git a/webapp/components/Modal/ReportModal.spec.js b/webapp/components/Modal/ReportModal.spec.js index 865348512..f9326e2d9 100644 --- a/webapp/components/Modal/ReportModal.spec.js +++ b/webapp/components/Modal/ReportModal.spec.js @@ -18,7 +18,8 @@ describe('ReportModal.vue', () => { beforeEach(() => { propsData = { type: 'contribution', - id: 'c43' + id: 'c43', + callbacks: { confirm: null, cancel: null } } mocks = { $t: jest.fn(), @@ -55,7 +56,8 @@ describe('ReportModal.vue', () => { propsData = { type: 'user', id: 'u4', - name: 'Bob Ross' + name: 'Bob Ross', + callbacks: { confirm: null, cancel: null } } }) @@ -72,7 +74,8 @@ describe('ReportModal.vue', () => { propsData = { id: 'p23', type: 'post', - name: 'It is a post' + name: 'It is a post', + callbacks: { confirm: null, cancel: null } } }) @@ -100,7 +103,8 @@ describe('ReportModal.vue', () => { beforeEach(() => { propsData = { type: 'user', - id: 'u4711' + id: 'u4711', + callbacks: { confirm: null, cancel: null } } wrapper = Wrapper() }) diff --git a/webapp/components/Modal/ReportModal.vue b/webapp/components/Modal/ReportModal.vue index 846fe5420..382e8df60 100644 --- a/webapp/components/Modal/ReportModal.vue +++ b/webapp/components/Modal/ReportModal.vue @@ -53,6 +53,7 @@ export default { props: { name: { type: String, default: '' }, type: { type: String, required: true }, + callbacks: { type: Object, required: true }, id: { type: String, required: true } }, data() { @@ -73,6 +74,9 @@ export default { }, methods: { async cancel() { + if (!!this.callbacks.cancel) { + await this.callbacks.cancel() + } this.isOpen = false setTimeout(() => { this.$emit('close') @@ -81,6 +85,9 @@ export default { async confirm() { this.loading = true try { + if (!!this.callbacks.confirm) { + await this.callbacks.confirm() + } await this.$apollo.mutate({ mutation: gql` mutation($id: ID!) { diff --git a/webapp/components/PostCard/index.vue b/webapp/components/PostCard/index.vue index dfee29c8f..58b38e285 100644 --- a/webapp/components/PostCard/index.vue +++ b/webapp/components/PostCard/index.vue @@ -82,7 +82,7 @@ import HcUser from '~/components/User' import ContentMenu from '~/components/ContentMenu' import { randomBytes } from 'crypto' import { mapGetters } from 'vuex' -import Post from '~/mixins/Post' +import PostMutationHelpers from '~/mixins/PostMutationHelpers' export default { name: 'HcPostCard', @@ -90,7 +90,7 @@ export default { HcUser, ContentMenu }, - mixins: [Post], + mixins: [PostMutationHelpers], props: { post: { type: Object, @@ -98,7 +98,7 @@ export default { }, width: { type: Object, - required: true + default: () => {} } }, computed: { diff --git a/webapp/mixins/Post.js b/webapp/mixins/PostMutationHelpers.js similarity index 84% rename from webapp/mixins/Post.js rename to webapp/mixins/PostMutationHelpers.js index 24779bab1..830c56a26 100644 --- a/webapp/mixins/Post.js +++ b/webapp/mixins/PostMutationHelpers.js @@ -3,6 +3,7 @@ import gql from 'graphql-tag' export default { methods: { async deletePostCallback(postDisplayType = 'list') { + console.log('inside "deletePostCallback" !!! ', this.post) try { var gqlMutation = gql` mutation($id: ID!) { @@ -19,8 +20,10 @@ export default { switch (postDisplayType) { case 'list': this.$emit('deletePost') + console.log('emitted "deletePost" !!!') break default: + // case 'page' this.$router.history.push('/') // Single page type: Redirect to index break } diff --git a/webapp/mixins/PostMutationHelpers.spec.js b/webapp/mixins/PostMutationHelpers.spec.js new file mode 100644 index 000000000..5854917df --- /dev/null +++ b/webapp/mixins/PostMutationHelpers.spec.js @@ -0,0 +1,71 @@ +import { shallowMount, mount, createLocalVue } from '@vue/test-utils' +import Methods from '~/mixins/PostMutationHelpers' + +const { + methods: { deletePostCallback } +} = Methods +// console.log(deletePostCallback()) + +describe('PostMutationHelpers.js', () => { + let post + let mocks + + beforeEach(() => { + post = { + id: 'p23' + } + mocks = { + $t: jest.fn(), + $filters: { + truncate: a => a + }, + $emit: jest.fn(), + $router: { + history: { + push: jest.fn() + } + }, + $toast: { + success: () => {}, + error: () => {} + }, + $apollo: { + mutate: jest.fn().mockResolvedValue() + } + } + }) + + describe('given post id', () => { + describe('delete post in general', () => { + beforeEach(() => { + deletePostCallback() + }) + + it('calls delete mutation', () => { + expect(mocks.$apollo.mutate).toHaveBeenCalled() + }) + + it('displays a success message', () => { + const calls = mocks.$t.mock.calls + const expected = [['delete.contribution.success']] + expect(calls).toEqual(expect.arrayContaining(expected)) + }) + + it.todo('displays an error message') + }) + + describe('delete Post from list', () => { + it('calls delete in list', () => { + deletePostCallback('list') + expect(mocks.$emit).toHaveBeenCalled() + }) + }) + + describe('delete Post displayed on post page', () => { + it('routs to index (main page) on post page', () => { + deletePostCallback('page') + expect($router.history.push).toHaveBeenCalled() + }) + }) + }) +}) diff --git a/webapp/package.json b/webapp/package.json index a3e8b44b9..e6e149b73 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -29,7 +29,6 @@ "!**/?(*.)+(spec|test).js?(x)" ], "coverageReporters": [ - "text", "lcov" ], "transform": { diff --git a/webapp/pages/post/_id/_slug/index.vue b/webapp/pages/post/_id/_slug/index.vue index 102d9007c..cefc90792 100644 --- a/webapp/pages/post/_id/_slug/index.vue +++ b/webapp/pages/post/_id/_slug/index.vue @@ -115,7 +115,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 Post from '~/mixins/Post' +import PostMutationHelpers from '~/mixins/PostMutationHelpers' export default { transition: { @@ -131,7 +131,7 @@ export default { HcCommentForm, HcCommentList }, - mixins: [Post], + mixins: [PostMutationHelpers], head() { return { title: this.title diff --git a/webapp/pages/profile/_id/_slug.spec.js b/webapp/pages/profile/_id/_slug.spec.js new file mode 100644 index 000000000..c2f342b49 --- /dev/null +++ b/webapp/pages/profile/_id/_slug.spec.js @@ -0,0 +1,243 @@ +import { shallowMount, mount, createLocalVue } from '@vue/test-utils' +// import PostMutationHelpers from '~/mixins/PostMutationHelpers' +import PostSlug from './_slug.vue' +import Vue from 'vue' +import Vuex from 'vuex' +import Styleguide from '@human-connection/styleguide' +import VueRouter from 'vue-router' + +const routes = [{ path: '/' }] +const router = new VueRouter({ routes }) +const localVue = createLocalVue() + +localVue.use(Vuex) +localVue.use(Styleguide) +localVue.use(VueRouter) + +describe('PostSlug', () => { + let wrapper + let Wrapper + let propsData + let mocks + + beforeEach(() => { + propsData = {} + mocks = { + post: { + id: 'p23' + }, + $t: jest.fn(), + // $filters: { + // truncate: a => a + // }, + $toast: { + success: () => {}, + error: () => {} + }, + $apollo: { + mutate: jest.fn().mockResolvedValue() + } + } + }) + +// describe('shallowMount', () => { +// Wrapper = () => { +// return shallowMount(PostSlug, { propsData, mocks, localVue, router }) +// } + +// describe('defaults', () => { +// it('success false', () => { +// console.log(Wrapper().vm) +// expect(Wrapper().vm.success).toBe(false) +// }) + +// it('loading false', () => { +// expect(Wrapper().vm.loading).toBe(false) +// }) +// }) + + // describe('given a post', () => { + // beforeEach(() => { + // propsData = { + // type: 'contribution', + // id: 'p23', + // name: 'It is a post' + // // callbacks: { + // // confirm: () => Post.methods.deletePostCallback('list'), + // // cancel: null + // // } + // } + // }) + + // it('mentions post title', () => { + // Wrapper() + // const calls = mocks.$t.mock.calls + // const expected = [ + // ['delete.contribution.message', { name: 'It is a post' }] + // ] + // expect(calls).toEqual(expect.arrayContaining(expected)) + // }) + // }) + + // describe('given a comment', () => { + // beforeEach(() => { + // propsData = { + // type: 'comment', + // id: 'c3', + // name: 'It is the user of the comment' + // // callbacks: { + // // confirm: () => Post.methods.deletePostCallback('list'), + // // cancel: null + // // } + // } + // }) + + // it('mentions comments user name', () => { + // Wrapper() + // const calls = mocks.$t.mock.calls + // const expected = [ + // ['delete.comment.message', { name: 'It is the user of the comment' }] + // ] + // expect(calls).toEqual(expect.arrayContaining(expected)) + // }) + // }) +// }) + + describe('mount', () => { + Wrapper = () => { + return mount(PostSlug, { propsData, mocks, localVue, router }) + } + + beforeEach(jest.useFakeTimers) + + it('renders', () => { + // console.log(Wrapper().vm) + expect(Wrapper().is('div')).toBe(true) + }) + + describe('given post id', () => { + beforeEach(() => { + // post = { + // id: 'p23' + // } + wrapper = Wrapper() + }) + + describe('confirm deletion of Post from List by invoking "deletePostCallback"', () => { + beforeEach(() => { + wrapper = Wrapper() + wrapper.vm.deletePostCallback('list') + }) + + describe('after timeout', () => { + beforeEach(jest.runAllTimers) + + // it('fades away', () => { + // expect(wrapper.vm.isOpen).toBe(false) + // }) + + it('emits "deletePost"', () => { + expect(wrapper.emitted().deletePost).toBeTruthy() + }) + + it('does call mutation', () => { + expect(mocks.$apollo.mutate).toHaveBeenCalled() + }) + }) + }) + + // describe('click cancel button and do not delete the post', () => { + // beforeEach(() => { + // wrapper = Wrapper() + // wrapper.find('button.cancel').trigger('click') + // }) + + // describe('after timeout', () => { + // beforeEach(jest.runAllTimers) + + // it('fades away', () => { + // expect(wrapper.vm.isOpen).toBe(false) + // }) + + // it('emits "close"', () => { + // expect(wrapper.emitted().close).toBeTruthy() + // }) + + // it('does not call mutation', () => { + // expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + // }) + // }) + // }) + +// describe('click confirm button and delete the post', () => { +// beforeEach(() => { +// wrapper.find('button.confirm').trigger('click') +// }) + +// it('calls delete mutation', () => { +// expect(mocks.$apollo.mutate).toHaveBeenCalled() +// }) + +// it('sets success', () => { +// expect(wrapper.vm.success).toBe(true) +// }) + +// it('displays a success message', () => { +// const calls = mocks.$t.mock.calls +// const expected = [['delete.contribution.success']] +// expect(calls).toEqual(expect.arrayContaining(expected)) +// }) + +// describe('after timeout', () => { +// beforeEach(jest.runAllTimers) + +// it('fades away', () => { +// expect(wrapper.vm.isOpen).toBe(false) +// }) + +// it('emits close', () => { +// expect(wrapper.emitted().close).toBeTruthy() +// }) + +// it('resets success', () => { +// expect(wrapper.vm.success).toBe(false) +// }) +// }) +// }) + }) + +// describe('given comment id', () => { +// beforeEach(() => { +// propsData = { +// type: 'comment', +// id: 'c3' +// // callbacks: { +// // confirm: () => Post.methods.deletePostCallback('list'), +// // cancel: null +// // } +// } +// wrapper = Wrapper() +// }) + +// describe('click confirm button and delete the comment', () => { +// beforeEach(() => { +// wrapper.find('button.confirm').trigger('click') +// }) + +// it('calls delete mutation', () => { +// expect(mocks.$apollo.mutate).toHaveBeenCalled() +// }) + +// it('sets success', () => { +// expect(wrapper.vm.success).toBe(true) +// }) + +// it('displays a success message', () => { +// const calls = mocks.$t.mock.calls +// const expected = [['delete.comment.success']] +// expect(calls).toEqual(expect.arrayContaining(expected)) +// }) +// }) +// }) + }) +}) diff --git a/webapp/pages/profile/_id/_slug.vue b/webapp/pages/profile/_id/_slug.vue index d4db41fb5..613967553 100644 --- a/webapp/pages/profile/_id/_slug.vue +++ b/webapp/pages/profile/_id/_slug.vue @@ -328,7 +328,7 @@ import HcBadges from '~/components/Badges.vue' import HcLoadMore from '~/components/LoadMore.vue' import HcEmpty from '~/components/Empty.vue' import ContentMenu from '~/components/ContentMenu' -import Post from '~/mixins/Post' +import PostMutationHelpers from '~/mixins/PostMutationHelpers' export default { components: { @@ -341,7 +341,7 @@ export default { HcEmpty, ContentMenu }, - mixins: [Post], + mixins: [PostMutationHelpers], transition: { name: 'slide-up', mode: 'out-in'