Merge pull request #5317 from Ocelot-Social-Community/5059-groups/5316-in-be-hidden-groups-not-listed-for-none-or-pending-members

feat: 🍰 Hidden Groups Shall Not Be Visible For None Or Pending Members In Backend
This commit is contained in:
Wolfgang Huß 2022-09-08 15:42:18 +02:00 committed by GitHub
commit d87c0271a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 247 additions and 126 deletions

View File

@ -325,13 +325,6 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
userId: 'u2', userId: 'u2',
}, },
}), }),
mutate({
mutation: joinGroupMutation,
variables: {
groupId: 'g0',
userId: 'u3',
},
}),
mutate({ mutate({
mutation: joinGroupMutation, mutation: joinGroupMutation,
variables: { variables: {
@ -364,14 +357,6 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
roleInGroup: 'admin', roleInGroup: 'admin',
}, },
}), }),
mutate({
mutation: changeGroupMemberRoleMutation,
variables: {
groupId: 'g0',
userId: 'u3',
roleInGroup: 'owner',
},
}),
]) ])
authenticatedUser = await jennyRostock.toJson() authenticatedUser = await jennyRostock.toJson()
@ -430,7 +415,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
mutate({ mutate({
mutation: changeGroupMemberRoleMutation, mutation: changeGroupMemberRoleMutation,
variables: { variables: {
groupId: 'g0', groupId: 'g1',
userId: 'u1', userId: 'u1',
roleInGroup: 'usual', roleInGroup: 'usual',
}, },
@ -438,15 +423,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
mutate({ mutate({
mutation: changeGroupMemberRoleMutation, mutation: changeGroupMemberRoleMutation,
variables: { variables: {
groupId: 'g0', groupId: 'g1',
userId: 'u2',
roleInGroup: 'usual',
},
}),
mutate({
mutation: changeGroupMemberRoleMutation,
variables: {
groupId: 'g0',
userId: 'u5', userId: 'u5',
roleInGroup: 'admin', roleInGroup: 'admin',
}, },
@ -454,7 +431,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
mutate({ mutate({
mutation: changeGroupMemberRoleMutation, mutation: changeGroupMemberRoleMutation,
variables: { variables: {
groupId: 'g0', groupId: 'g1',
userId: 'u6', userId: 'u6',
roleInGroup: 'owner', roleInGroup: 'owner',
}, },
@ -477,6 +454,13 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
}), }),
]) ])
await Promise.all([ await Promise.all([
mutate({
mutation: joinGroupMutation,
variables: {
groupId: 'g2',
userId: 'u3',
},
}),
mutate({ mutate({
mutation: joinGroupMutation, mutation: joinGroupMutation,
variables: { variables: {
@ -510,7 +494,15 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
mutate({ mutate({
mutation: changeGroupMemberRoleMutation, mutation: changeGroupMemberRoleMutation,
variables: { variables: {
groupId: 'g0', groupId: 'g2',
userId: 'u3',
roleInGroup: 'pending',
},
}),
mutate({
mutation: changeGroupMemberRoleMutation,
variables: {
groupId: 'g2',
userId: 'u4', userId: 'u4',
roleInGroup: 'usual', roleInGroup: 'usual',
}, },
@ -518,7 +510,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
mutate({ mutate({
mutation: changeGroupMemberRoleMutation, mutation: changeGroupMemberRoleMutation,
variables: { variables: {
groupId: 'g0', groupId: 'g2',
userId: 'u5', userId: 'u5',
roleInGroup: 'usual', roleInGroup: 'usual',
}, },
@ -526,7 +518,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
mutate({ mutate({
mutation: changeGroupMemberRoleMutation, mutation: changeGroupMemberRoleMutation,
variables: { variables: {
groupId: 'g0', groupId: 'g2',
userId: 'u6', userId: 'u6',
roleInGroup: 'usual', roleInGroup: 'usual',
}, },

View File

@ -18,19 +18,25 @@ export default {
if (isMember === true) { if (isMember === true) {
groupCypher = ` groupCypher = `
MATCH (:User {id: $userId})-[membership:MEMBER_OF]->(group:Group${groupIdCypher}) MATCH (:User {id: $userId})-[membership:MEMBER_OF]->(group:Group${groupIdCypher})
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} RETURN group {.*, myRole: membership.role}
` `
} else { } else {
if (isMember === false) { if (isMember === false) {
groupCypher = ` groupCypher = `
MATCH (group:Group${groupIdCypher}) MATCH (group:Group${groupIdCypher})
WHERE NOT (:User {id: $userId})-[:MEMBER_OF]->(group) WHERE (NOT (:User {id: $userId})-[:MEMBER_OF]->(group))
WITH group
WHERE group.groupType IN ['public', 'closed']
RETURN group {.*, myRole: NULL} RETURN group {.*, myRole: NULL}
` `
} else { } else {
groupCypher = ` groupCypher = `
MATCH (group:Group${groupIdCypher}) MATCH (group:Group${groupIdCypher})
OPTIONAL MATCH (:User {id: $userId})-[membership:MEMBER_OF]->(group) 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'])
RETURN group {.*, myRole: membership.role} RETURN group {.*, myRole: membership.role}
` `
} }

View File

@ -267,6 +267,7 @@ describe('in mode', () => {
describe('authenticated', () => { describe('authenticated', () => {
let otherUser let otherUser
let ownerOfHiddenGroupUser
beforeAll(async () => { beforeAll(async () => {
otherUser = await Factory.build( otherUser = await Factory.build(
@ -276,7 +277,18 @@ describe('in mode', () => {
name: 'Other TestUser', name: 'Other TestUser',
}, },
{ {
email: 'test2@example.org', email: 'other-user@example.org',
password: '1234',
},
)
ownerOfHiddenGroupUser = await Factory.build(
'user',
{
id: 'owner-of-hidden-group',
name: 'Owner Of Hidden Group',
},
{
email: 'owner-of-hidden-group@example.org',
password: '1234', password: '1234',
}, },
) )
@ -293,6 +305,59 @@ describe('in mode', () => {
categoryIds, categoryIds,
}, },
}) })
authenticatedUser = await ownerOfHiddenGroupUser.toJson()
await mutate({
mutation: createGroupMutation,
variables: {
id: 'hidden-group',
name: 'Investigative Journalism Group',
about: 'We will change all.',
description: 'We research …' + descriptionAdditional100,
groupType: 'hidden',
actionRadius: 'global',
categoryIds,
},
})
await mutate({
mutation: createGroupMutation,
variables: {
id: 'second-hidden-group',
name: 'Second Investigative Journalism Group',
about: 'We will change all.',
description: 'We research …' + descriptionAdditional100,
groupType: 'hidden',
actionRadius: 'global',
categoryIds,
},
})
await mutate({
mutation: changeGroupMemberRoleMutation,
variables: {
groupId: 'second-hidden-group',
userId: 'current-user',
roleInGroup: 'pending',
},
})
await mutate({
mutation: createGroupMutation,
variables: {
id: 'third-hidden-group',
name: 'Third Investigative Journalism Group',
about: 'We will change all.',
description: 'We research …' + descriptionAdditional100,
groupType: 'hidden',
actionRadius: 'global',
categoryIds,
},
})
await mutate({
mutation: changeGroupMemberRoleMutation,
variables: {
groupId: 'third-hidden-group',
userId: 'current-user',
roleInGroup: 'usual',
},
})
authenticatedUser = await user.toJson() authenticatedUser = await user.toJson()
await mutate({ await mutate({
mutation: createGroupMutation, mutation: createGroupMutation,
@ -309,9 +374,11 @@ describe('in mode', () => {
}) })
describe('query groups', () => { describe('query groups', () => {
describe('in general finds only listed groups no hidden groups where user is none or pending member', () => {
describe('without any filters', () => { describe('without any filters', () => {
it('finds all groups', async () => { it('finds all listed groups', async () => {
await expect(query({ query: groupQuery, variables: {} })).resolves.toMatchObject({ const result = await query({ query: groupQuery, variables: {} })
expect(result).toMatchObject({
data: { data: {
Group: expect.arrayContaining([ Group: expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
@ -324,10 +391,16 @@ describe('in mode', () => {
slug: 'uninteresting-group', slug: 'uninteresting-group',
myRole: null, myRole: null,
}), }),
expect.objectContaining({
id: 'third-hidden-group',
slug: 'third-investigative-journalism-group',
myRole: 'usual',
}),
]), ]),
}, },
errors: undefined, errors: undefined,
}) })
expect(result.data.Group.length).toBe(3)
}) })
describe('categories', () => { describe('categories', () => {
@ -367,11 +440,11 @@ describe('in mode', () => {
}) })
}) })
describe('with given id', () => {
describe("id = 'my-group'", () => { describe("id = 'my-group'", () => {
it('finds only the group with this id', async () => { it('finds only the listed group with this id', async () => {
await expect( const result = await query({ query: groupQuery, variables: { id: 'my-group' } })
query({ query: groupQuery, variables: { id: 'my-group' } }), expect(result).toMatchObject({
).resolves.toMatchObject({
data: { data: {
Group: [ Group: [
expect.objectContaining({ expect.objectContaining({
@ -383,33 +456,81 @@ describe('in mode', () => {
}, },
errors: undefined, errors: undefined,
}) })
expect(result.data.Group.length).toBe(1)
})
})
describe("id = 'third-hidden-group'", () => {
it("finds only the hidden group where I'm 'usual' member", async () => {
const result = await query({
query: groupQuery,
variables: { id: 'third-hidden-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("id = 'second-hidden-group'", () => {
it("finds no hidden group where I'm 'pending' member", async () => {
const result = await query({
query: groupQuery,
variables: { id: 'second-hidden-group' },
})
expect(result.data.Group.length).toBe(0)
})
})
describe("id = 'hidden-group'", () => {
it("finds no hidden group where I'm not(!) a member at all", async () => {
const result = await query({
query: groupQuery,
variables: { id: 'hidden-group' },
})
expect(result.data.Group.length).toBe(0)
})
}) })
}) })
describe('isMember = true', () => { describe('isMember = true', () => {
it('finds only groups where user is member', async () => { it('finds only listed groups where user is member', async () => {
await expect( const result = await query({ query: groupQuery, variables: { isMember: true } })
query({ query: groupQuery, variables: { isMember: true } }), expect(result).toMatchObject({
).resolves.toMatchObject({
data: { data: {
Group: [ Group: expect.arrayContaining([
{ expect.objectContaining({
id: 'my-group', id: 'my-group',
slug: 'the-best-group', slug: 'the-best-group',
myRole: 'owner', myRole: 'owner',
}, }),
], expect.objectContaining({
id: 'third-hidden-group',
slug: 'third-investigative-journalism-group',
myRole: 'usual',
}),
]),
}, },
errors: undefined, errors: undefined,
}) })
expect(result.data.Group.length).toBe(2)
}) })
}) })
describe('isMember = false', () => { describe('isMember = false', () => {
it('finds only groups where user is not(!) member', async () => { it('finds only listed groups where user is not(!) member', async () => {
await expect( const result = await query({ query: groupQuery, variables: { isMember: false } })
query({ query: groupQuery, variables: { isMember: false } }), expect(result).toMatchObject({
).resolves.toMatchObject({
data: { data: {
Group: expect.arrayContaining([ Group: expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
@ -421,6 +542,8 @@ describe('in mode', () => {
}, },
errors: undefined, errors: undefined,
}) })
expect(result.data.Group.length).toBe(1)
})
}) })
}) })
}) })