mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Merge pull request #5332 from Ocelot-Social-Community/5059-groups/5318-group-profile-second
feat: 🍰 Implement Group Profile – Visibility
This commit is contained in:
commit
017a764812
@ -120,36 +120,8 @@ export const changeGroupMemberRoleMutation = gql`
|
||||
// ------ queries
|
||||
|
||||
export const groupQuery = gql`
|
||||
query (
|
||||
$isMember: Boolean
|
||||
$id: ID
|
||||
$name: String
|
||||
$slug: String
|
||||
$createdAt: String
|
||||
$updatedAt: String
|
||||
$about: String
|
||||
$description: String
|
||||
$locationName: String
|
||||
$first: Int
|
||||
$offset: Int
|
||||
$orderBy: [_GroupOrdering]
|
||||
$filter: _GroupFilter
|
||||
) {
|
||||
Group(
|
||||
isMember: $isMember
|
||||
id: $id
|
||||
name: $name
|
||||
slug: $slug
|
||||
createdAt: $createdAt
|
||||
updatedAt: $updatedAt
|
||||
about: $about
|
||||
description: $description
|
||||
locationName: $locationName
|
||||
first: $first
|
||||
offset: $offset
|
||||
orderBy: $orderBy
|
||||
filter: $filter
|
||||
) {
|
||||
query ($isMember: Boolean, $id: ID, $slug: String) {
|
||||
Group(isMember: $isMember, id: $id, slug: $slug) {
|
||||
id
|
||||
name
|
||||
slug
|
||||
|
||||
@ -4,20 +4,25 @@ import CONFIG from '../../config'
|
||||
import { CATEGORIES_MIN, CATEGORIES_MAX } from '../../constants/categories'
|
||||
import { DESCRIPTION_WITHOUT_HTML_LENGTH_MIN } from '../../constants/groups'
|
||||
import { removeHtmlTags } from '../../middleware/helpers/cleanHtml.js'
|
||||
import Resolver from './helpers/Resolver'
|
||||
import Resolver, {
|
||||
removeUndefinedNullValuesFromObject,
|
||||
convertObjectToCypherMapLiteral,
|
||||
} from './helpers/Resolver'
|
||||
import { mergeImage } from './images/images'
|
||||
|
||||
export default {
|
||||
Query: {
|
||||
Group: async (_object, params, context, _resolveInfo) => {
|
||||
const { id: groupId, isMember } = params
|
||||
const { isMember, id, slug } = params
|
||||
const matchParams = { id, slug }
|
||||
removeUndefinedNullValuesFromObject(matchParams)
|
||||
const session = context.driver.session()
|
||||
const readTxResultPromise = session.readTransaction(async (txc) => {
|
||||
const groupIdCypher = groupId ? ` {id: "${groupId}"}` : ''
|
||||
const groupMatchParamsCypher = convertObjectToCypherMapLiteral(matchParams, true)
|
||||
let groupCypher
|
||||
if (isMember === true) {
|
||||
groupCypher = `
|
||||
MATCH (:User {id: $userId})-[membership:MEMBER_OF]->(group:Group${groupIdCypher})
|
||||
MATCH (:User {id: $userId})-[membership:MEMBER_OF]->(group:Group${groupMatchParamsCypher})
|
||||
WITH group, membership
|
||||
WHERE (group.groupType IN ['public', 'closed']) OR (group.groupType = 'hidden' AND membership.role IN ['usual', 'admin', 'owner'])
|
||||
RETURN group {.*, myRole: membership.role}
|
||||
@ -25,7 +30,7 @@ export default {
|
||||
} else {
|
||||
if (isMember === false) {
|
||||
groupCypher = `
|
||||
MATCH (group:Group${groupIdCypher})
|
||||
MATCH (group:Group${groupMatchParamsCypher})
|
||||
WHERE (NOT (:User {id: $userId})-[:MEMBER_OF]->(group))
|
||||
WITH group
|
||||
WHERE group.groupType IN ['public', 'closed']
|
||||
@ -33,7 +38,7 @@ export default {
|
||||
`
|
||||
} else {
|
||||
groupCypher = `
|
||||
MATCH (group:Group${groupIdCypher})
|
||||
MATCH (group:Group${groupMatchParamsCypher})
|
||||
OPTIONAL MATCH (:User {id: $userId})-[membership:MEMBER_OF]->(group)
|
||||
WITH group, membership
|
||||
WHERE (group.groupType IN ['public', 'closed']) OR (group.groupType = 'hidden' AND membership.role IN ['usual', 'admin', 'owner'])
|
||||
|
||||
@ -503,6 +503,72 @@ describe('in mode', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('with given slug', () => {
|
||||
describe("slug = 'the-best-group'", () => {
|
||||
it('finds only the listed group with this slug', async () => {
|
||||
const result = await query({
|
||||
query: groupQuery,
|
||||
variables: { slug: 'the-best-group' },
|
||||
})
|
||||
expect(result).toMatchObject({
|
||||
data: {
|
||||
Group: [
|
||||
expect.objectContaining({
|
||||
id: 'my-group',
|
||||
slug: 'the-best-group',
|
||||
myRole: 'owner',
|
||||
}),
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
expect(result.data.Group.length).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe("slug = 'third-investigative-journalism-group'", () => {
|
||||
it("finds only the hidden group where I'm 'usual' member", async () => {
|
||||
const result = await query({
|
||||
query: groupQuery,
|
||||
variables: { slug: 'third-investigative-journalism-group' },
|
||||
})
|
||||
expect(result).toMatchObject({
|
||||
data: {
|
||||
Group: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: 'third-hidden-group',
|
||||
slug: 'third-investigative-journalism-group',
|
||||
myRole: 'usual',
|
||||
}),
|
||||
]),
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
expect(result.data.Group.length).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe("slug = 'second-investigative-journalism-group'", () => {
|
||||
it("finds no hidden group where I'm 'pending' member", async () => {
|
||||
const result = await query({
|
||||
query: groupQuery,
|
||||
variables: { slug: 'second-investigative-journalism-group' },
|
||||
})
|
||||
expect(result.data.Group.length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("slug = 'investigative-journalism-group'", () => {
|
||||
it("finds no hidden group where I'm not(!) a member at all", async () => {
|
||||
const result = await query({
|
||||
query: groupQuery,
|
||||
variables: { slug: 'investigative-journalism-group' },
|
||||
})
|
||||
expect(result.data.Group.length).toBe(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('isMember = true', () => {
|
||||
it('finds only listed groups where user is member', async () => {
|
||||
const result = await query({ query: groupQuery, variables: { isMember: true } })
|
||||
|
||||
@ -121,3 +121,25 @@ export default function Resolver(type, options = {}) {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const removeUndefinedNullValuesFromObject = (obj) => {
|
||||
Object.keys(obj).forEach((key) => {
|
||||
if ([undefined, null].includes(obj[key])) {
|
||||
delete obj[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const convertObjectToCypherMapLiteral = (params, addSpaceInfrontIfMapIsNotEmpty = false) => {
|
||||
// I have found no other way yet. maybe "apoc.convert.fromJsonMap(key)" can help, but couldn't get it how, see: https://stackoverflow.com/questions/43217823/neo4j-cypher-inline-conversion-of-string-to-a-map
|
||||
// result looks like: '{id: "g0", slug: "yoga"}'
|
||||
const paramsEntries = Object.entries(params)
|
||||
let mapLiteral = ''
|
||||
paramsEntries.forEach((ele, index) => {
|
||||
mapLiteral += index === 0 ? '{' : ''
|
||||
mapLiteral += `${ele[0]}: "${ele[1]}"`
|
||||
mapLiteral += index < paramsEntries.length - 1 ? ', ' : '}'
|
||||
})
|
||||
mapLiteral = (addSpaceInfrontIfMapIsNotEmpty && mapLiteral.length > 0 ? ' ' : '') + mapLiteral
|
||||
return mapLiteral
|
||||
}
|
||||
|
||||
@ -61,27 +61,19 @@ type Query {
|
||||
Group(
|
||||
isMember: Boolean # if 'undefined' or 'null' then get all groups
|
||||
id: ID
|
||||
name: String
|
||||
slug: String
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
about: String
|
||||
description: String
|
||||
# groupType: GroupType # test this
|
||||
# actionRadius: GroupActionRadius # test this
|
||||
# avatar: ImageInput # test this
|
||||
locationName: String
|
||||
first: Int
|
||||
offset: Int
|
||||
orderBy: [_GroupOrdering]
|
||||
# first: Int # not implemented yet
|
||||
# offset: Int # not implemented yet
|
||||
# orderBy: [_GroupOrdering] # not implemented yet
|
||||
# filter: _GroupFilter # not implemented yet
|
||||
): [Group]
|
||||
|
||||
GroupMembers(
|
||||
id: ID!
|
||||
first: Int
|
||||
offset: Int
|
||||
orderBy: [_UserOrdering]
|
||||
filter: _UserFilter
|
||||
# first: Int # not implemented yet
|
||||
# offset: Int # not implemented yet
|
||||
# orderBy: [_UserOrdering] # not implemented yet
|
||||
# filter: _UserFilter # not implemented yet
|
||||
): [User]
|
||||
|
||||
# AvailableGroupTypes: [GroupType]!
|
||||
|
||||
@ -120,36 +120,8 @@ export const changeGroupMemberRoleMutation = gql`
|
||||
// ------ queries
|
||||
|
||||
export const groupQuery = gql`
|
||||
query (
|
||||
$isMember: Boolean
|
||||
$id: ID
|
||||
$name: String
|
||||
$slug: String
|
||||
$createdAt: String
|
||||
$updatedAt: String
|
||||
$about: String
|
||||
$description: String
|
||||
$locationName: String
|
||||
$first: Int
|
||||
$offset: Int
|
||||
$orderBy: [_GroupOrdering]
|
||||
$filter: _GroupFilter
|
||||
) {
|
||||
Group(
|
||||
isMember: $isMember
|
||||
id: $id
|
||||
name: $name
|
||||
slug: $slug
|
||||
createdAt: $createdAt
|
||||
updatedAt: $updatedAt
|
||||
about: $about
|
||||
description: $description
|
||||
locationName: $locationName
|
||||
first: $first
|
||||
offset: $offset
|
||||
orderBy: $orderBy
|
||||
filter: $filter
|
||||
) {
|
||||
query ($isMember: Boolean, $id: ID, $slug: String) {
|
||||
Group(isMember: $isMember, id: $id, slug: $slug) {
|
||||
id
|
||||
name
|
||||
slug
|
||||
|
||||
@ -10,22 +10,24 @@ export default function (options = {}) {
|
||||
} = context
|
||||
const idOrSlug = id || slug
|
||||
|
||||
const variables = { idOrSlug }
|
||||
const client = apolloProvider.defaultClient
|
||||
if (idOrSlug) {
|
||||
const variables = { idOrSlug }
|
||||
const client = apolloProvider.defaultClient
|
||||
|
||||
let response
|
||||
let resource
|
||||
response = await client.query({ query: queryId, variables })
|
||||
resource = response.data[Object.keys(response.data)[0]][0]
|
||||
if (resource && resource.slug === slug) return // all good
|
||||
if (resource && resource.slug !== slug) {
|
||||
return redirect(`/${path}/${resource.id}/${resource.slug}`)
|
||||
let response
|
||||
let resource
|
||||
response = await client.query({ query: queryId, variables })
|
||||
resource = response.data[Object.keys(response.data)[0]][0]
|
||||
if (resource && resource.slug === slug) return // all good
|
||||
if (resource && resource.slug !== slug) {
|
||||
return redirect(`/${path}/${resource.id}/${resource.slug}`)
|
||||
}
|
||||
|
||||
response = await client.query({ query: querySlug, variables })
|
||||
resource = response.data[Object.keys(response.data)[0]][0]
|
||||
if (resource) return redirect(`/${path}/${resource.id}/${resource.slug}`)
|
||||
}
|
||||
|
||||
response = await client.query({ query: querySlug, variables })
|
||||
resource = response.data[Object.keys(response.data)[0]][0]
|
||||
if (resource) return redirect(`/${path}/${resource.id}/${resource.slug}`)
|
||||
|
||||
return error({ statusCode: 404, key: message })
|
||||
},
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user