mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Merge pull request #2608 from Human-Connection/1680-Direct_answer_on_Comment
feat: 🍰 Direct Reply On Comment
This commit is contained in:
commit
4170e62f7a
@ -55,7 +55,19 @@ export default function create() {
|
|||||||
if (authorId) author = await neodeInstance.find('User', authorId)
|
if (authorId) author = await neodeInstance.find('User', authorId)
|
||||||
author = author || (await factoryInstance.create('User'))
|
author = author || (await factoryInstance.create('User'))
|
||||||
const post = await neodeInstance.create('Post', args)
|
const post = await neodeInstance.create('Post', args)
|
||||||
|
|
||||||
|
const { commentContent } = args
|
||||||
|
let comment
|
||||||
|
delete args.commentContent
|
||||||
|
if (commentContent)
|
||||||
|
comment = await factoryInstance.create('Comment', {
|
||||||
|
contentExcerpt: commentContent,
|
||||||
|
post,
|
||||||
|
author,
|
||||||
|
})
|
||||||
|
|
||||||
await post.relateTo(author, 'author')
|
await post.relateTo(author, 'author')
|
||||||
|
if (comment) await post.relateTo(comment, 'comments')
|
||||||
|
|
||||||
if (args.pinned) {
|
if (args.pinned) {
|
||||||
args.pinnedAt = args.pinnedAt || new Date().toISOString()
|
args.pinnedAt = args.pinnedAt || new Date().toISOString()
|
||||||
|
|||||||
@ -41,6 +41,16 @@ export default {
|
|||||||
language: { type: 'string', allow: [null] },
|
language: { type: 'string', allow: [null] },
|
||||||
imageBlurred: { type: 'boolean', default: false },
|
imageBlurred: { type: 'boolean', default: false },
|
||||||
imageAspectRatio: { type: 'float', default: 1.0 },
|
imageAspectRatio: { type: 'float', default: 1.0 },
|
||||||
|
comments: {
|
||||||
|
type: 'relationship',
|
||||||
|
relationship: 'COMMENTS',
|
||||||
|
target: 'Comment',
|
||||||
|
direction: 'in',
|
||||||
|
properties: {
|
||||||
|
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
|
||||||
|
updatedAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
|
||||||
|
},
|
||||||
|
},
|
||||||
pinned: { type: 'boolean', default: null, valid: [null, true] },
|
pinned: { type: 'boolean', default: null, valid: [null, true] },
|
||||||
pinnedAt: { type: 'string', isoDate: true },
|
pinnedAt: { type: 'string', isoDate: true },
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,8 +17,13 @@ Then("I click on the {string} button", text => {
|
|||||||
.click();
|
.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Then("I click on the reply button", () => {
|
||||||
|
cy.get(".reply-button")
|
||||||
|
.click();
|
||||||
|
});
|
||||||
|
|
||||||
Then("my comment should be successfully created", () => {
|
Then("my comment should be successfully created", () => {
|
||||||
cy.get(".iziToast-message").contains("Comment Submitted");
|
cy.get(".iziToast-message").contains("Comment submitted!");
|
||||||
});
|
});
|
||||||
|
|
||||||
Then("I should see my comment", () => {
|
Then("I should see my comment", () => {
|
||||||
@ -45,6 +50,12 @@ Then("the editor should be cleared", () => {
|
|||||||
cy.get(".ProseMirror p").should("have.class", "is-empty");
|
cy.get(".ProseMirror p").should("have.class", "is-empty");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Then("it should create a mention in the CommentForm", () => {
|
||||||
|
cy.get(".ProseMirror a")
|
||||||
|
.should('have.class', 'mention')
|
||||||
|
.should('contain', '@peter-pan')
|
||||||
|
})
|
||||||
|
|
||||||
When("I open the content menu of post {string}", (title)=> {
|
When("I open the content menu of post {string}", (title)=> {
|
||||||
cy.contains('.post-card', title)
|
cy.contains('.post-card', title)
|
||||||
.find('.content-menu .base-button')
|
.find('.content-menu .base-button')
|
||||||
|
|||||||
@ -4,10 +4,10 @@ Feature: Post Comment
|
|||||||
To be able to express my thoughts and emotions about these, discuss, and add give further information.
|
To be able to express my thoughts and emotions about these, discuss, and add give further information.
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
Given we have the following posts in our database:
|
Given I have a user account
|
||||||
| id | title | slug |
|
And we have the following posts in our database:
|
||||||
| bWBjpkTKZp | 101 Essays that will change the way you think | 101-essays |
|
| id | title | slug | authorId | commentContent |
|
||||||
And I have a user account
|
| bWBjpkTKZp | 101 Essays that will change the way you think | 101-essays | id-of-peter-pan | @peter-pan reply to me |
|
||||||
And I am logged in
|
And I am logged in
|
||||||
|
|
||||||
Scenario: Comment creation
|
Scenario: Comment creation
|
||||||
@ -36,3 +36,8 @@ Feature: Post Comment
|
|||||||
Then my comment should be successfully created
|
Then my comment should be successfully created
|
||||||
And I should see an abreviated version of my comment
|
And I should see an abreviated version of my comment
|
||||||
And the editor should be cleared
|
And the editor should be cleared
|
||||||
|
|
||||||
|
Scenario: Direct reply to Comment
|
||||||
|
Given I visit "post/bWBjpkTKZp/101-essays"
|
||||||
|
And I click on the reply button
|
||||||
|
Then it should create a mention in the CommentForm
|
||||||
|
|||||||
@ -15,7 +15,6 @@
|
|||||||
/* globals Cypress cy */
|
/* globals Cypress cy */
|
||||||
import "cypress-file-upload";
|
import "cypress-file-upload";
|
||||||
import helpers from "./helpers";
|
import helpers from "./helpers";
|
||||||
import users from "../fixtures/users.json";
|
|
||||||
import { GraphQLClient, request } from 'graphql-request'
|
import { GraphQLClient, request } from 'graphql-request'
|
||||||
import { gql } from '../../backend/src/helpers/jest'
|
import { gql } from '../../backend/src/helpers/jest'
|
||||||
import config from '../../backend/src/config'
|
import config from '../../backend/src/config'
|
||||||
|
|||||||
5
webapp/assets/_new/icons/svgs/level-down.svg
Executable file
5
webapp/assets/_new/icons/svgs/level-down.svg
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
|
<title>level-down</title>
|
||||||
|
<path d="M5 5h17v19.063l4.281-4.281 1.438 1.438-6 6-0.719 0.688-0.719-0.688-6-6 1.438-1.438 4.281 4.281v-17.063h-15v-2z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 293 B |
@ -1,17 +1,15 @@
|
|||||||
import { config, shallowMount } from '@vue/test-utils'
|
import { config, mount } from '@vue/test-utils'
|
||||||
import Comment from './Comment.vue'
|
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>'
|
||||||
|
|
||||||
describe('Comment.vue', () => {
|
describe('Comment.vue', () => {
|
||||||
let propsData
|
let propsData, mocks, stubs, getters, wrapper, Wrapper
|
||||||
let mocks
|
|
||||||
let getters
|
|
||||||
let wrapper
|
|
||||||
let Wrapper
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
propsData = {}
|
propsData = {}
|
||||||
@ -39,6 +37,9 @@ describe('Comment.vue', () => {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
stubs = {
|
||||||
|
ContentViewer: true,
|
||||||
|
}
|
||||||
getters = {
|
getters = {
|
||||||
'auth/user': () => {
|
'auth/user': () => {
|
||||||
return {}
|
return {}
|
||||||
@ -47,18 +48,19 @@ describe('Comment.vue', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('shallowMount', () => {
|
describe('mount', () => {
|
||||||
beforeEach(jest.useFakeTimers)
|
beforeEach(jest.useFakeTimers)
|
||||||
|
|
||||||
Wrapper = () => {
|
Wrapper = () => {
|
||||||
const store = new Vuex.Store({
|
const store = new Vuex.Store({
|
||||||
getters,
|
getters,
|
||||||
})
|
})
|
||||||
return shallowMount(Comment, {
|
return mount(Comment, {
|
||||||
store,
|
store,
|
||||||
propsData,
|
propsData,
|
||||||
mocks,
|
mocks,
|
||||||
localVue,
|
localVue,
|
||||||
|
stubs,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +70,7 @@ describe('Comment.vue', () => {
|
|||||||
id: '2',
|
id: '2',
|
||||||
contentExcerpt: 'Hello I am a comment content',
|
contentExcerpt: 'Hello I am a comment content',
|
||||||
content: 'Hello I am comment content',
|
content: 'Hello I am comment content',
|
||||||
|
author: { id: 'commentAuthorId', slug: 'ogerly' },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -199,6 +202,24 @@ describe('Comment.vue', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('click reply button', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
wrapper = Wrapper()
|
||||||
|
await wrapper.find('.reply-button').trigger('click')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('emits "reply"', () => {
|
||||||
|
expect(wrapper.emitted('reply')).toEqual([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id: 'commentAuthorId',
|
||||||
|
slug: 'ogerly',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -54,6 +54,15 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<ds-space margin-bottom="small" />
|
<ds-space margin-bottom="small" />
|
||||||
|
<base-button
|
||||||
|
:title="this.$t('post.comment.reply')"
|
||||||
|
icon="level-down"
|
||||||
|
class="reply-button"
|
||||||
|
circle
|
||||||
|
size="small"
|
||||||
|
v-scroll-to="'.editor'"
|
||||||
|
@click.prevent="reply"
|
||||||
|
></base-button>
|
||||||
</ds-card>
|
</ds-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -67,6 +76,7 @@ import ContentViewer from '~/components/Editor/ContentViewer'
|
|||||||
import CommentForm from '~/components/CommentForm/CommentForm'
|
import CommentForm from '~/components/CommentForm/CommentForm'
|
||||||
import CommentMutations from '~/graphql/CommentMutations'
|
import CommentMutations from '~/graphql/CommentMutations'
|
||||||
import scrollToAnchor from '~/mixins/scrollToAnchor.js'
|
import scrollToAnchor from '~/mixins/scrollToAnchor.js'
|
||||||
|
import BaseButton from '~/components/_new/generic/BaseButton/BaseButton'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [scrollToAnchor],
|
mixins: [scrollToAnchor],
|
||||||
@ -86,6 +96,7 @@ export default {
|
|||||||
ContentMenu,
|
ContentMenu,
|
||||||
ContentViewer,
|
ContentViewer,
|
||||||
CommentForm,
|
CommentForm,
|
||||||
|
BaseButton,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
routeHash: { type: String, default: () => '' },
|
routeHash: { type: String, default: () => '' },
|
||||||
@ -105,7 +116,6 @@ export default {
|
|||||||
if (this.isLongComment && this.isCollapsed) {
|
if (this.isLongComment && this.isCollapsed) {
|
||||||
return this.$filters.truncate(this.comment.content, COMMENT_TRUNCATE_TO_LENGTH)
|
return this.$filters.truncate(this.comment.content, COMMENT_TRUNCATE_TO_LENGTH)
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.comment.content
|
return this.comment.content
|
||||||
},
|
},
|
||||||
displaysComment() {
|
displaysComment() {
|
||||||
@ -141,6 +151,10 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
reply() {
|
||||||
|
const message = { slug: this.comment.author.slug, id: this.comment.author.id }
|
||||||
|
this.$emit('reply', message)
|
||||||
|
},
|
||||||
checkAnchor(anchor) {
|
checkAnchor(anchor) {
|
||||||
return `#${this.anchor}` === anchor
|
return `#${this.anchor}` === anchor
|
||||||
},
|
},
|
||||||
@ -193,6 +207,14 @@ export default {
|
|||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reply-button {
|
||||||
|
float: right;
|
||||||
|
top: 0px;
|
||||||
|
}
|
||||||
|
.reply-button:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes highlight {
|
@keyframes highlight {
|
||||||
0% {
|
0% {
|
||||||
border: 1px solid $color-primary;
|
border: 1px solid $color-primary;
|
||||||
|
|||||||
@ -51,6 +51,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
reply(message) {
|
||||||
|
this.$refs.editor.insertReply(message)
|
||||||
|
},
|
||||||
updateEditorContent(value) {
|
updateEditorContent(value) {
|
||||||
const sanitizedContent = this.$filters.removeHtml(value, false)
|
const sanitizedContent = this.$filters.removeHtml(value, false)
|
||||||
if (!this.update) {
|
if (!this.update) {
|
||||||
@ -133,8 +136,8 @@ export default {
|
|||||||
query() {
|
query() {
|
||||||
return minimisedUserQuery()
|
return minimisedUserQuery()
|
||||||
},
|
},
|
||||||
result(result) {
|
update({ User }) {
|
||||||
this.users = result.data.User
|
this.users = User
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -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>'
|
||||||
@ -97,5 +100,27 @@ describe('CommentList.vue', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('Comment', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = Wrapper()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Comment emitted reply()', () => {
|
||||||
|
wrapper.find(Comment).vm.$emit('reply', {
|
||||||
|
id: 'commentAuthorId',
|
||||||
|
slug: 'ogerly',
|
||||||
|
})
|
||||||
|
Vue.nextTick()
|
||||||
|
expect(wrapper.emitted('reply')).toEqual([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id: 'commentAuthorId',
|
||||||
|
slug: 'ogerly',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -12,9 +12,11 @@
|
|||||||
:comment="comment"
|
:comment="comment"
|
||||||
:post="post"
|
:post="post"
|
||||||
:routeHash="routeHash"
|
:routeHash="routeHash"
|
||||||
|
class="comment-tag"
|
||||||
@deleteComment="updateCommentList"
|
@deleteComment="updateCommentList"
|
||||||
@updateComment="updateCommentList"
|
@updateComment="updateCommentList"
|
||||||
@toggleNewCommentForm="toggleNewCommentForm"
|
@toggleNewCommentForm="toggleNewCommentForm"
|
||||||
|
@reply="reply"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,6 +37,9 @@ export default {
|
|||||||
post: { type: Object, default: () => {} },
|
post: { type: Object, default: () => {} },
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
reply(message) {
|
||||||
|
this.$emit('reply', message)
|
||||||
|
},
|
||||||
checkAnchor(anchor) {
|
checkAnchor(anchor) {
|
||||||
return anchor === '#comments'
|
return anchor === '#comments'
|
||||||
},
|
},
|
||||||
|
|||||||
@ -141,7 +141,6 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
openSuggestionList({ items, query, range, command, virtualNode }, suggestionType) {
|
openSuggestionList({ items, query, range, command, virtualNode }, suggestionType) {
|
||||||
this.suggestionType = suggestionType
|
this.suggestionType = suggestionType
|
||||||
|
|
||||||
this.query = this.sanitizeQuery(query)
|
this.query = this.sanitizeQuery(query)
|
||||||
this.filteredItems = items
|
this.filteredItems = items
|
||||||
this.suggestionRange = range
|
this.suggestionRange = range
|
||||||
@ -237,6 +236,9 @@ export default {
|
|||||||
const content = e.getHTML()
|
const content = e.getHTML()
|
||||||
this.$emit('input', content)
|
this.$emit('input', content)
|
||||||
},
|
},
|
||||||
|
insertReply(message) {
|
||||||
|
this.editor.commands.mention({ id: message.id, label: message.slug })
|
||||||
|
},
|
||||||
toggleLinkInput(attrs, element) {
|
toggleLinkInput(attrs, element) {
|
||||||
if (!this.isLinkInputActive && attrs && element) {
|
if (!this.isLinkInputActive && attrs && element) {
|
||||||
this.$refs.linkInput.linkUrl = attrs.href
|
this.$refs.linkInput.linkUrl = attrs.href
|
||||||
|
|||||||
@ -105,7 +105,7 @@ export default {
|
|||||||
postId: this.post.id,
|
postId: this.post.id,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
result({ data: { PostsEmotionsByCurrentUser } }) {
|
update({ PostsEmotionsByCurrentUser }) {
|
||||||
this.selectedEmotions = PostsEmotionsByCurrentUser
|
this.selectedEmotions = PostsEmotionsByCurrentUser
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -279,8 +279,9 @@
|
|||||||
},
|
},
|
||||||
"comment": {
|
"comment": {
|
||||||
"submit": "Kommentiere",
|
"submit": "Kommentiere",
|
||||||
"submitted": "Kommentar gesendet",
|
"submitted": "Kommentar gesendet!",
|
||||||
"updated": "Änderungen gespeichert"
|
"updated": "Änderungen gespeichert",
|
||||||
|
"reply": "Antworten"
|
||||||
},
|
},
|
||||||
"edited": "bearbeitet"
|
"edited": "bearbeitet"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -444,8 +444,9 @@
|
|||||||
},
|
},
|
||||||
"comment": {
|
"comment": {
|
||||||
"submit": "Comment",
|
"submit": "Comment",
|
||||||
"submitted": "Comment Submitted",
|
"submitted": "Comment submitted!",
|
||||||
"updated": "Changes Saved"
|
"updated": "Changes saved!",
|
||||||
|
"reply": "Reply"
|
||||||
},
|
},
|
||||||
"edited": "edited"
|
"edited": "edited"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,29 +1,33 @@
|
|||||||
import { config, shallowMount } 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 PostSlug from './index.vue'
|
||||||
const localVue = global.localVue
|
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['router-link'] = '<span><slot /></span>'
|
||||||
|
|
||||||
|
const localVue = global.localVue
|
||||||
|
localVue.directive('scrollTo', jest.fn())
|
||||||
|
|
||||||
describe('PostSlug', () => {
|
describe('PostSlug', () => {
|
||||||
let wrapper
|
let store, propsData, mocks, stubs, wrapper, Wrapper
|
||||||
let Wrapper
|
|
||||||
let store
|
|
||||||
let mocks
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
store = new Vuex.Store({
|
store = new Vuex.Store({
|
||||||
getters: {
|
getters: {
|
||||||
'auth/user': () => {
|
'auth/user': () => {
|
||||||
return {}
|
return { id: '1stUser' }
|
||||||
},
|
},
|
||||||
|
'auth/isModerator': () => false,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
propsData = {}
|
||||||
mocks = {
|
mocks = {
|
||||||
$t: jest.fn(),
|
$t: jest.fn(),
|
||||||
$filters: {
|
$filters: {
|
||||||
truncate: a => a,
|
truncate: a => a,
|
||||||
|
removeHtml: a => a,
|
||||||
},
|
},
|
||||||
$route: {
|
$route: {
|
||||||
hash: '',
|
hash: '',
|
||||||
@ -40,38 +44,53 @@ describe('PostSlug', () => {
|
|||||||
},
|
},
|
||||||
$apollo: {
|
$apollo: {
|
||||||
mutate: jest.fn().mockResolvedValue(),
|
mutate: jest.fn().mockResolvedValue(),
|
||||||
|
query: jest.fn().mockResolvedValue({ data: { PostEmotionsCountByEmotion: {} } }),
|
||||||
},
|
},
|
||||||
|
$scrollTo: jest.fn(),
|
||||||
}
|
}
|
||||||
})
|
stubs = {
|
||||||
|
HcEditor: { render: () => {}, methods: { insertReply: jest.fn(() => null) } },
|
||||||
describe('shallowMount', () => {
|
ContentViewer: true,
|
||||||
Wrapper = () => {
|
|
||||||
return shallowMount(PostSlug, {
|
|
||||||
store,
|
|
||||||
mocks,
|
|
||||||
localVue,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
jest.useFakeTimers()
|
||||||
beforeEach(jest.useFakeTimers)
|
|
||||||
|
|
||||||
describe('test Post callbacks', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
wrapper.setData({
|
wrapper.setData({
|
||||||
post: {
|
post: {
|
||||||
id: 'p23',
|
id: '1',
|
||||||
name: 'It is a post',
|
|
||||||
author: {
|
author: {
|
||||||
id: 'u1',
|
id: '1stUser',
|
||||||
|
},
|
||||||
|
comments: [
|
||||||
|
{
|
||||||
|
id: 'comment134',
|
||||||
|
contentExcerpt: 'this is a comment',
|
||||||
|
content: 'this is a comment',
|
||||||
|
author: {
|
||||||
|
id: '1stUser',
|
||||||
|
slug: '1st-user',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
ready: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('mount', () => {
|
||||||
|
Wrapper = () => {
|
||||||
|
return mount(PostSlug, {
|
||||||
|
store,
|
||||||
|
mocks,
|
||||||
|
localVue,
|
||||||
|
propsData,
|
||||||
|
stubs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('test Post callbacks', () => {
|
||||||
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', () => {
|
||||||
@ -91,5 +110,18 @@ describe('PostSlug', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('reply method called when emitted reply received', () => {
|
||||||
|
it('CommentList', async () => {
|
||||||
|
wrapper.find(CommentList).vm.$emit('reply', {
|
||||||
|
id: 'commentAuthorId',
|
||||||
|
slug: 'ogerly',
|
||||||
|
})
|
||||||
|
expect(stubs.HcEditor.methods.insertReply).toHaveBeenCalledWith({
|
||||||
|
id: 'commentAuthorId',
|
||||||
|
slug: 'ogerly',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -84,14 +84,16 @@
|
|||||||
</ds-space>
|
</ds-space>
|
||||||
<!-- Comments -->
|
<!-- Comments -->
|
||||||
<ds-section slot="footer">
|
<ds-section slot="footer">
|
||||||
<hc-comment-list
|
<comment-list
|
||||||
:post="post"
|
:post="post"
|
||||||
:routeHash="$route.hash"
|
:routeHash="$route.hash"
|
||||||
@toggleNewCommentForm="toggleNewCommentForm"
|
@toggleNewCommentForm="toggleNewCommentForm"
|
||||||
|
@reply="reply"
|
||||||
/>
|
/>
|
||||||
<ds-space margin-bottom="large" />
|
<ds-space margin-bottom="large" />
|
||||||
<comment-form
|
<comment-form
|
||||||
v-if="showNewCommentForm && !post.author.blocked"
|
v-if="showNewCommentForm && !post.author.blocked"
|
||||||
|
ref="commentForm"
|
||||||
:post="post"
|
:post="post"
|
||||||
@createComment="createComment"
|
@createComment="createComment"
|
||||||
/>
|
/>
|
||||||
@ -114,7 +116,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 CommentForm from '~/components/CommentForm/CommentForm'
|
import CommentForm 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'
|
||||||
@ -133,7 +135,7 @@ export default {
|
|||||||
HcShoutButton,
|
HcShoutButton,
|
||||||
ContentMenu,
|
ContentMenu,
|
||||||
CommentForm,
|
CommentForm,
|
||||||
HcCommentList,
|
CommentList,
|
||||||
HcEmotions,
|
HcEmotions,
|
||||||
ContentViewer,
|
ContentViewer,
|
||||||
},
|
},
|
||||||
@ -170,6 +172,9 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
reply(message) {
|
||||||
|
this.$refs.commentForm && this.$refs.commentForm.reply(message)
|
||||||
|
},
|
||||||
isAuthor(id) {
|
isAuthor(id) {
|
||||||
return this.$store.getters['auth/user'].id === id
|
return this.$store.getters['auth/user'].id === id
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user