mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
feat(backend): pin public group posts (#8606)
* feat(backend): pin more than one post * add postPinnedCount query, better names for env variable * add store and mixin for pinned posts counts * test pinned post store * context menu for pin posts * fix typos * unpin posts is always possible * feat(backend): pin public group posts * allow posts in public groups to be pinned by admins --------- Co-authored-by: Wolfgang Huß <wolle.huss@pjannto.com>
This commit is contained in:
parent
b736a2a2e3
commit
fb2ef852a1
@ -10,6 +10,7 @@ import CONFIG from '@config/index'
|
||||
import databaseContext from '@context/database'
|
||||
import Factory, { cleanDatabase } from '@db/factories'
|
||||
import Image from '@db/models/Image'
|
||||
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
||||
import { createPostMutation } from '@graphql/queries/createPostMutation'
|
||||
import createServer, { getContext } from '@src/server'
|
||||
|
||||
@ -1305,6 +1306,130 @@ describe('pin posts', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('post in public group', () => {
|
||||
beforeEach(async () => {
|
||||
await mutate({
|
||||
mutation: createGroupMutation(),
|
||||
variables: {
|
||||
name: 'Public Group',
|
||||
id: 'public-group',
|
||||
about: 'This is a public group',
|
||||
groupType: 'public',
|
||||
actionRadius: 'regional',
|
||||
description:
|
||||
'This is a public group to test if the posts of this group can be pinned.',
|
||||
categoryIds,
|
||||
},
|
||||
})
|
||||
await mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
id: 'public-group-post',
|
||||
title: 'Public group post',
|
||||
content: 'This is a post in a public group',
|
||||
groupId: 'public-group',
|
||||
categoryIds,
|
||||
},
|
||||
})
|
||||
variables = { ...variables, id: 'public-group-post' }
|
||||
})
|
||||
|
||||
it('can be pinned', async () => {
|
||||
await expect(mutate({ mutation: pinPostMutation, variables })).resolves.toMatchObject({
|
||||
data: {
|
||||
pinPost: {
|
||||
id: 'public-group-post',
|
||||
author: {
|
||||
slug: 'testuser',
|
||||
},
|
||||
pinnedBy: {
|
||||
id: 'current-user',
|
||||
name: 'Admin',
|
||||
role: 'admin',
|
||||
},
|
||||
},
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('post in closed group', () => {
|
||||
beforeEach(async () => {
|
||||
await mutate({
|
||||
mutation: createGroupMutation(),
|
||||
variables: {
|
||||
name: 'Closed Group',
|
||||
id: 'closed-group',
|
||||
about: 'This is a closed group',
|
||||
groupType: 'closed',
|
||||
actionRadius: 'regional',
|
||||
description:
|
||||
'This is a closed group to test if the posts of this group can be pinned.',
|
||||
categoryIds,
|
||||
},
|
||||
})
|
||||
await mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
id: 'closed-group-post',
|
||||
title: 'Closed group post',
|
||||
content: 'This is a post in a closed group',
|
||||
groupId: 'closed-group',
|
||||
categoryIds,
|
||||
},
|
||||
})
|
||||
variables = { ...variables, id: 'closed-group-post' }
|
||||
})
|
||||
|
||||
it('can not be pinned', async () => {
|
||||
await expect(mutate({ mutation: pinPostMutation, variables })).resolves.toMatchObject({
|
||||
data: {
|
||||
pinPost: null,
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('post in hidden group', () => {
|
||||
beforeEach(async () => {
|
||||
await mutate({
|
||||
mutation: createGroupMutation(),
|
||||
variables: {
|
||||
name: 'Hidden Group',
|
||||
id: 'hidden-group',
|
||||
about: 'This is a hidden group',
|
||||
groupType: 'hidden',
|
||||
actionRadius: 'regional',
|
||||
description:
|
||||
'This is a hidden group to test if the posts of this group can be pinned.',
|
||||
categoryIds,
|
||||
},
|
||||
})
|
||||
await mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
id: 'hidden-group-post',
|
||||
title: 'Hidden group post',
|
||||
content: 'This is a post in a hidden group',
|
||||
groupId: 'hidden-group',
|
||||
categoryIds,
|
||||
},
|
||||
})
|
||||
variables = { ...variables, id: 'hidden-group-post' }
|
||||
})
|
||||
|
||||
it('can not be pinned', async () => {
|
||||
await expect(mutate({ mutation: pinPostMutation, variables })).resolves.toMatchObject({
|
||||
data: {
|
||||
pinPost: null,
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('PostOrdering', () => {
|
||||
beforeEach(async () => {
|
||||
await Factory.build('post', {
|
||||
|
||||
@ -351,7 +351,8 @@ export default {
|
||||
const pinPostCypher = `
|
||||
MATCH (user:User {id: $userId}) WHERE user.role = 'admin'
|
||||
MATCH (post:Post {id: $params.id})
|
||||
WHERE NOT((post)-[:IN]->(:Group))
|
||||
WHERE NOT EXISTS((post)-[:IN]->(:Group)) OR
|
||||
(post)-[:IN]->(:Group { groupType: 'public'})
|
||||
MERGE (user)-[pinned:PINNED {createdAt: toString(datetime())}]->(post)
|
||||
SET post.pinned = true
|
||||
RETURN post, pinned.createdAt as pinnedAt`
|
||||
|
||||
@ -197,6 +197,79 @@ describe('ContentMenu.vue', () => {
|
||||
],
|
||||
])
|
||||
})
|
||||
|
||||
describe('post in public group', () => {
|
||||
it('can pin unpinned post', async () => {
|
||||
getters['auth/isAdmin'] = () => true
|
||||
const wrapper = await openContentMenu({
|
||||
isOwner: false,
|
||||
resourceType: 'contribution',
|
||||
resource: {
|
||||
id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8',
|
||||
pinnedBy: null,
|
||||
group: {
|
||||
groupType: 'public',
|
||||
},
|
||||
},
|
||||
})
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter((item) => item.text() === 'post.menu.pin')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(wrapper.emitted('pinPost')).toEqual([
|
||||
[
|
||||
{
|
||||
id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8',
|
||||
pinnedBy: null,
|
||||
group: {
|
||||
groupType: 'public',
|
||||
},
|
||||
},
|
||||
],
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe('post in closed group', () => {
|
||||
it('can not be pinned', async () => {
|
||||
getters['auth/isAdmin'] = () => true
|
||||
const wrapper = await openContentMenu({
|
||||
isOwner: false,
|
||||
resourceType: 'contribution',
|
||||
resource: {
|
||||
id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8',
|
||||
pinnedBy: null,
|
||||
group: {
|
||||
groupType: 'closed',
|
||||
},
|
||||
},
|
||||
})
|
||||
expect(
|
||||
wrapper.findAll('.ds-menu-item').filter((item) => item.text() === 'post.menu.pin'),
|
||||
).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('post in hidden group', () => {
|
||||
it('can not be pinned', async () => {
|
||||
getters['auth/isAdmin'] = () => true
|
||||
const wrapper = await openContentMenu({
|
||||
isOwner: false,
|
||||
resourceType: 'contribution',
|
||||
resource: {
|
||||
id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8',
|
||||
pinnedBy: null,
|
||||
group: {
|
||||
groupType: 'hidden',
|
||||
},
|
||||
},
|
||||
})
|
||||
expect(
|
||||
wrapper.findAll('.ds-menu-item').filter((item) => item.text() === 'post.menu.pin'),
|
||||
).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when maxPinnedPosts = 3', () => {
|
||||
|
||||
@ -82,7 +82,7 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
if (this.isAdmin && !this.resource.group) {
|
||||
if (this.isAdmin && (!this.resource.group || this.resource.group.groupType === 'public')) {
|
||||
if (!this.resource.pinnedBy && this.canBePinned) {
|
||||
routes.push({
|
||||
label: this.$t(`post.menu.pin`),
|
||||
|
||||
@ -53,6 +53,7 @@ export default (i18n) => {
|
||||
id
|
||||
name
|
||||
slug
|
||||
groupType
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -95,6 +96,7 @@ export const filterPosts = (i18n) => {
|
||||
id
|
||||
name
|
||||
slug
|
||||
groupType
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,6 +138,7 @@ export const profilePagePosts = (i18n) => {
|
||||
id
|
||||
name
|
||||
slug
|
||||
groupType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user