fix(frontend): error when post.author null

This commit is contained in:
roschaefer 2020-02-04 12:53:42 +01:00
parent b7896f9c4e
commit f2e2db0bc7
3 changed files with 95 additions and 63 deletions

View File

@ -1,13 +1,13 @@
<template>
<div id="comments" class="comment-list">
<h3 class="title">
<counter-icon icon="comments" :count="post.comments.length" />
<counter-icon icon="comments" :count="postComments.length" />
{{ $t('common.comment', null, 0) }}
</h3>
<ds-space margin-bottom="large" />
<div v-if="post.comments && post.comments.length" id="comments" class="comments">
<div id="comments" class="comments">
<comment
v-for="comment in post.comments"
v-for="comment in postComments"
:key="comment.id"
:comment="comment"
:post="post"
@ -36,6 +36,11 @@ export default {
routeHash: { type: String, default: () => '' },
post: { type: Object, default: () => {} },
},
computed: {
postComments() {
return (this.post && this.post.comments) || []
},
},
methods: {
reply(message) {
this.$emit('reply', message)
@ -44,7 +49,7 @@ export default {
return anchor === '#comments'
},
updateCommentList(updatedComment) {
this.post.comments = this.post.comments.map(comment => {
this.postComments = this.postComments.map(comment => {
return comment.id === updatedComment.id ? updatedComment : comment
})
},

View File

@ -1,5 +1,6 @@
import { config, mount } from '@vue/test-utils'
import Vuex from 'vuex'
import Vue from 'vue'
import PostSlug from './index.vue'
import CommentList from '~/components/CommentList/CommentList'
@ -11,85 +12,103 @@ const localVue = global.localVue
localVue.directive('scrollTo', jest.fn())
describe('PostSlug', () => {
let store, propsData, mocks, stubs, wrapper, Wrapper
let wrapper, Wrapper, backendData, mocks, stubs
beforeEach(() => {
store = new Vuex.Store({
getters: {
'auth/user': () => {
return { id: '1stUser' }
},
'auth/isModerator': () => false,
},
})
propsData = {}
mocks = {
$t: jest.fn(),
$filters: {
truncate: a => a,
removeHtml: a => a,
},
$route: {
hash: '',
},
// 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(),
},
},
$toast: {
success: jest.fn(),
error: jest.fn(),
},
$apollo: {
mutate: jest.fn().mockResolvedValue(),
query: jest.fn().mockResolvedValue({ data: { PostEmotionsCountByEmotion: {} } }),
},
$scrollTo: jest.fn(),
}
stubs = {
HcEditor: { render: () => {}, methods: { insertReply: jest.fn(() => null) } },
ContentViewer: true,
}
jest.useFakeTimers()
wrapper = Wrapper()
wrapper.setData({
const author = { id: '1stUser', slug: '1st-user' }
backendData = {
post: {
id: '1',
author: {
id: '1stUser',
},
author,
comments: [
{
id: 'comment134',
contentExcerpt: 'this is a comment',
content: 'this is a comment',
author: {
id: '1stUser',
slug: '1st-user',
},
author,
},
],
},
ready: true,
})
}
})
describe('mount', () => {
Wrapper = () => {
return mount(PostSlug, {
Wrapper = async (opts = {}) => {
jest.useFakeTimers()
const store = new Vuex.Store({
getters: {
'auth/user': () => {
return { id: '1stUser' }
},
'auth/isModerator': () => false,
},
})
const propsData = {}
mocks = {
$t: jest.fn(),
$filters: {
truncate: a => a,
removeHtml: a => a,
},
$route: {
hash: '',
},
// 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(),
},
},
$toast: {
success: jest.fn(),
error: jest.fn(),
},
$apollo: {
mutate: jest.fn().mockResolvedValue(),
query: jest.fn().mockResolvedValue({ data: { PostEmotionsCountByEmotion: {} } }),
},
$scrollTo: jest.fn(),
}
stubs = {
HcEditor: { render: () => {}, methods: { insertReply: jest.fn(() => null) } },
ContentViewer: true,
}
const defaults = {
store,
mocks,
localVue,
propsData,
stubs,
}
const wrapper = mount(PostSlug, {
...defaults,
...opts,
})
wrapper.setData(backendData)
await Vue.nextTick()
return wrapper
}
describe('given author is `null`', () => {
it('does not crash', async () => {
backendData = {
post: {
id: '1',
author: null,
comments: [],
},
ready: true,
}
wrapper = await Wrapper()
expect(wrapper.find('.info.anonymous').exists()).toBe(true)
})
})
describe('test Post callbacks', () => {
describe('deletion of Post from Page by invoking "deletePostCallback()"', () => {
beforeEach(async () => {
wrapper = await Wrapper()
await wrapper.vm.deletePostCallback()
})
@ -113,6 +132,7 @@ describe('PostSlug', () => {
describe('reply method called when emitted reply received', () => {
it('CommentList', async () => {
wrapper = await Wrapper()
wrapper.find(CommentList).vm.$emit('reply', {
id: 'commentAuthorId',
slug: 'ogerly',

View File

@ -30,7 +30,7 @@
resource-type="contribution"
:resource="post"
:modalsData="menuModalsData"
:is-owner="isAuthor(post.author ? post.author.id : null)"
:is-owner="isAuthor"
@pinPost="pinPost"
@unpinPost="unpinPost"
/>
@ -74,7 +74,7 @@
>
<hc-shout-button
v-if="post.author"
:disabled="isAuthor(post.author.id)"
:disabled="isAuthor"
:count="post.shoutedCount"
:is-shouted="post.shoutedByCurrentUser"
:post-id="post.id"
@ -92,12 +92,12 @@
/>
<ds-space margin-bottom="large" />
<comment-form
v-if="showNewCommentForm && !post.author.blocked"
v-if="showNewCommentForm && !isBlocked"
ref="commentForm"
:post="post"
@createComment="createComment"
/>
<ds-placeholder v-if="post.author.blocked">
<ds-placeholder v-if="isBlocked">
{{ $t('settings.blocked-users.explanation.commenting-disabled') }}
<br />
{{ $t('settings.blocked-users.explanation.commenting-explanation') }}
@ -170,14 +170,21 @@ export default {
this.deletePostCallback,
)
},
isBlocked() {
const { author } = this.post
if (!author) return false
return author.blocked
},
isAuthor() {
const { author } = this.post
if (!author) return false
return this.$store.getters['auth/user'].id === author.id
},
},
methods: {
reply(message) {
this.$refs.commentForm && this.$refs.commentForm.reply(message)
},
isAuthor(id) {
return this.$store.getters['auth/user'].id === id
},
async deletePostCallback() {
try {
await this.$apollo.mutate(deletePostMutation(this.post.id))