mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
3159 lines
106 KiB
JavaScript
3159 lines
106 KiB
JavaScript
import { createTestClient } from 'apollo-server-testing'
|
||
import Factory, { cleanDatabase } from '../../db/factories'
|
||
import {
|
||
createGroupMutation,
|
||
updateGroupMutation,
|
||
joinGroupMutation,
|
||
leaveGroupMutation,
|
||
changeGroupMemberRoleMutation,
|
||
removeUserFromGroupMutation,
|
||
groupMembersQuery,
|
||
groupQuery,
|
||
} from '../../graphql/groups'
|
||
import { getNeode, getDriver } from '../../db/neo4j'
|
||
import createServer from '../../server'
|
||
import CONFIG from '../../config'
|
||
|
||
const driver = getDriver()
|
||
const neode = getNeode()
|
||
|
||
let authenticatedUser
|
||
let user
|
||
let noMemberUser
|
||
let pendingMemberUser
|
||
let usualMemberUser
|
||
let adminMemberUser
|
||
let ownerMemberUser
|
||
let secondOwnerMemberUser
|
||
|
||
const categoryIds = ['cat9', 'cat4', 'cat15']
|
||
const descriptionAdditional100 =
|
||
' 123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789'
|
||
let variables = {}
|
||
|
||
const { server } = createServer({
|
||
context: () => {
|
||
return {
|
||
driver,
|
||
neode,
|
||
user: authenticatedUser,
|
||
}
|
||
},
|
||
})
|
||
const { mutate, query } = createTestClient(server)
|
||
|
||
const seedBasicsAndClearAuthentication = async () => {
|
||
variables = {}
|
||
user = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'current-user',
|
||
name: 'TestUser',
|
||
},
|
||
{
|
||
email: 'test@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
await Promise.all([
|
||
neode.create('Category', {
|
||
id: 'cat4',
|
||
name: 'Environment & Nature',
|
||
slug: 'environment-nature',
|
||
icon: 'tree',
|
||
}),
|
||
neode.create('Category', {
|
||
id: 'cat9',
|
||
name: 'Democracy & Politics',
|
||
slug: 'democracy-politics',
|
||
icon: 'university',
|
||
}),
|
||
neode.create('Category', {
|
||
id: 'cat15',
|
||
name: 'Consumption & Sustainability',
|
||
slug: 'consumption-sustainability',
|
||
icon: 'shopping-cart',
|
||
}),
|
||
neode.create('Category', {
|
||
id: 'cat27',
|
||
name: 'Animal Protection',
|
||
slug: 'animal-protection',
|
||
icon: 'paw',
|
||
}),
|
||
])
|
||
authenticatedUser = null
|
||
}
|
||
|
||
const seedComplexScenarioAndClearAuthentication = async () => {
|
||
await seedBasicsAndClearAuthentication()
|
||
// create users
|
||
noMemberUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'none-member-user',
|
||
name: 'None Member TestUser',
|
||
},
|
||
{
|
||
email: 'none-member-user@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
pendingMemberUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'pending-member-user',
|
||
name: 'Pending Member TestUser',
|
||
},
|
||
{
|
||
email: 'pending-member-user@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
usualMemberUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'usual-member-user',
|
||
name: 'Usual Member TestUser',
|
||
},
|
||
{
|
||
email: 'usual-member-user@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
adminMemberUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'admin-member-user',
|
||
name: 'Admin Member TestUser',
|
||
},
|
||
{
|
||
email: 'admin-member-user@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
ownerMemberUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'owner-member-user',
|
||
name: 'Owner Member TestUser',
|
||
},
|
||
{
|
||
email: 'owner-member-user@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
secondOwnerMemberUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'second-owner-member-user',
|
||
name: 'Second Owner Member TestUser',
|
||
},
|
||
{
|
||
email: 'second-owner-member-user@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
// create groups
|
||
// public-group
|
||
authenticatedUser = await usualMemberUser.toJson()
|
||
await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
id: 'public-group',
|
||
name: 'The Best Group',
|
||
about: 'We will change the world!',
|
||
description: 'Some description' + descriptionAdditional100,
|
||
groupType: 'public',
|
||
actionRadius: 'regional',
|
||
categoryIds,
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'public-group',
|
||
userId: 'owner-of-closed-group',
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'public-group',
|
||
userId: 'owner-of-hidden-group',
|
||
},
|
||
})
|
||
// closed-group
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
id: 'closed-group',
|
||
name: 'Uninteresting Group',
|
||
about: 'We will change nothing!',
|
||
description: 'We love it like it is!?' + descriptionAdditional100,
|
||
groupType: 'closed',
|
||
actionRadius: 'national',
|
||
categoryIds,
|
||
},
|
||
})
|
||
// hidden-group
|
||
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,
|
||
},
|
||
})
|
||
// 'JoinGroup' mutation does not work in hidden groups so we join them by 'ChangeGroupMemberRole' through the owner
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'usual-member-user',
|
||
roleInGroup: 'usual',
|
||
},
|
||
})
|
||
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'admin-member-user',
|
||
roleInGroup: 'admin',
|
||
},
|
||
})
|
||
|
||
authenticatedUser = null
|
||
}
|
||
|
||
beforeAll(async () => {
|
||
await cleanDatabase()
|
||
})
|
||
|
||
afterAll(async () => {
|
||
await cleanDatabase()
|
||
driver.close()
|
||
})
|
||
|
||
describe('in mode', () => {
|
||
describe('clean db after each single test', () => {
|
||
beforeEach(async () => {
|
||
await seedBasicsAndClearAuthentication()
|
||
})
|
||
|
||
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
|
||
afterEach(async () => {
|
||
await cleanDatabase()
|
||
})
|
||
|
||
describe('CreateGroup', () => {
|
||
beforeEach(() => {
|
||
variables = {
|
||
...variables,
|
||
id: 'g589',
|
||
name: 'The Best Group',
|
||
slug: 'the-group',
|
||
about: 'We will change the world!',
|
||
description: 'Some description' + descriptionAdditional100,
|
||
groupType: 'public',
|
||
actionRadius: 'regional',
|
||
categoryIds,
|
||
locationName: 'Hamburg, Germany',
|
||
}
|
||
})
|
||
|
||
describe('unauthenticated', () => {
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({ mutation: createGroupMutation(), variables })
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('authenticated', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await user.toJson()
|
||
})
|
||
|
||
it('creates a group', async () => {
|
||
await expect(
|
||
mutate({ mutation: createGroupMutation(), variables }),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
CreateGroup: {
|
||
name: 'The Best Group',
|
||
slug: 'the-group',
|
||
about: 'We will change the world!',
|
||
description: 'Some description' + descriptionAdditional100,
|
||
descriptionExcerpt: 'Some description' + descriptionAdditional100,
|
||
groupType: 'public',
|
||
actionRadius: 'regional',
|
||
locationName: 'Hamburg, Germany',
|
||
location: expect.objectContaining({
|
||
name: 'Hamburg',
|
||
nameDE: 'Hamburg',
|
||
nameEN: 'Hamburg',
|
||
}),
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
|
||
it('assigns the authenticated user as owner', async () => {
|
||
await expect(
|
||
mutate({ mutation: createGroupMutation(), variables }),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
CreateGroup: {
|
||
name: 'The Best Group',
|
||
myRole: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
|
||
it('has "disabled" and "deleted" default to "false"', async () => {
|
||
await expect(
|
||
mutate({ mutation: createGroupMutation(), variables }),
|
||
).resolves.toMatchObject({
|
||
data: { CreateGroup: { disabled: false, deleted: false } },
|
||
})
|
||
})
|
||
|
||
describe('description', () => {
|
||
describe('length without HTML', () => {
|
||
describe('less then 100 chars', () => {
|
||
it('throws error: "Description too short!"', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
...variables,
|
||
description:
|
||
'0123456789' +
|
||
'<a href="https://domain.org/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789">0123456789</a>',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Description too short!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('categories', () => {
|
||
beforeEach(() => {
|
||
CONFIG.CATEGORIES_ACTIVE = true
|
||
})
|
||
|
||
describe('with matching amount of categories', () => {
|
||
it('has new categories', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
...variables,
|
||
categoryIds: ['cat4', 'cat27'],
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
CreateGroup: {
|
||
categories: expect.arrayContaining([
|
||
expect.objectContaining({ id: 'cat4' }),
|
||
expect.objectContaining({ id: 'cat27' }),
|
||
]),
|
||
myRole: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('not even one', () => {
|
||
describe('by "categoryIds: null"', () => {
|
||
it('throws error: "Too view categories!"', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: { ...variables, categoryIds: null },
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Too view categories!')
|
||
})
|
||
})
|
||
|
||
describe('by "categoryIds: []"', () => {
|
||
it('throws error: "Too view categories!"', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: { ...variables, categoryIds: [] },
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Too view categories!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('four', () => {
|
||
it('throws error: "Too many categories!"', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: { ...variables, categoryIds: ['cat9', 'cat4', 'cat15', 'cat27'] },
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Too many categories!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('building up – clean db after each resolver', () => {
|
||
describe('Group', () => {
|
||
beforeAll(async () => {
|
||
await seedBasicsAndClearAuthentication()
|
||
})
|
||
|
||
afterAll(async () => {
|
||
await cleanDatabase()
|
||
})
|
||
|
||
describe('unauthenticated', () => {
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await query({ query: groupQuery(), variables: {} })
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('authenticated', () => {
|
||
let otherUser
|
||
let ownerOfHiddenGroupUser
|
||
|
||
beforeAll(async () => {
|
||
otherUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'other-user',
|
||
name: 'Other TestUser',
|
||
},
|
||
{
|
||
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',
|
||
},
|
||
)
|
||
authenticatedUser = await otherUser.toJson()
|
||
await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
id: 'others-group',
|
||
name: 'Uninteresting Group',
|
||
about: 'We will change nothing!',
|
||
description: 'We love it like it is!?' + descriptionAdditional100,
|
||
groupType: 'closed',
|
||
actionRadius: 'global',
|
||
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()
|
||
await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
name: 'The Best Group',
|
||
about: 'We will change the world!',
|
||
description: 'Some description' + descriptionAdditional100,
|
||
groupType: 'public',
|
||
actionRadius: 'regional',
|
||
categoryIds,
|
||
locationName: 'Hamburg, Germany',
|
||
},
|
||
})
|
||
})
|
||
|
||
describe('query groups', () => {
|
||
describe('in general finds only listed groups – no hidden groups where user is none or pending member', () => {
|
||
describe('without any filters', () => {
|
||
it('finds all listed groups – including the set descriptionExcerpts and locations', async () => {
|
||
const result = await query({ query: groupQuery(), variables: {} })
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
Group: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'my-group',
|
||
slug: 'the-best-group',
|
||
descriptionExcerpt: 'Some description' + descriptionAdditional100,
|
||
locationName: 'Hamburg, Germany',
|
||
location: expect.objectContaining({
|
||
name: 'Hamburg',
|
||
nameDE: 'Hamburg',
|
||
nameEN: 'Hamburg',
|
||
}),
|
||
myRole: 'owner',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'others-group',
|
||
slug: 'uninteresting-group',
|
||
descriptionExcerpt: 'We love it like it is!?' + descriptionAdditional100,
|
||
locationName: null,
|
||
location: null,
|
||
myRole: null,
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'third-hidden-group',
|
||
slug: 'third-investigative-journalism-group',
|
||
descriptionExcerpt: 'We research …' + descriptionAdditional100,
|
||
myRole: 'usual',
|
||
locationName: null,
|
||
location: null,
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.Group.length).toBe(3)
|
||
})
|
||
|
||
describe('categories', () => {
|
||
beforeEach(() => {
|
||
CONFIG.CATEGORIES_ACTIVE = true
|
||
})
|
||
|
||
it('has set categories', async () => {
|
||
await expect(
|
||
query({ query: groupQuery(), variables: {} }),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
Group: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'my-group',
|
||
slug: 'the-best-group',
|
||
categories: expect.arrayContaining([
|
||
expect.objectContaining({ id: 'cat4' }),
|
||
expect.objectContaining({ id: 'cat9' }),
|
||
expect.objectContaining({ id: 'cat15' }),
|
||
]),
|
||
myRole: 'owner',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'others-group',
|
||
slug: 'uninteresting-group',
|
||
categories: expect.arrayContaining([
|
||
expect.objectContaining({ id: 'cat4' }),
|
||
expect.objectContaining({ id: 'cat9' }),
|
||
expect.objectContaining({ id: 'cat15' }),
|
||
]),
|
||
myRole: null,
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('with given id', () => {
|
||
describe("id = 'my-group'", () => {
|
||
it('finds only the listed group with this id', async () => {
|
||
const result = await query({ query: groupQuery(), variables: { id: 'my-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("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('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 } })
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
Group: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'my-group',
|
||
slug: 'the-best-group',
|
||
myRole: 'owner',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'third-hidden-group',
|
||
slug: 'third-investigative-journalism-group',
|
||
myRole: 'usual',
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.Group.length).toBe(2)
|
||
})
|
||
})
|
||
|
||
describe('isMember = false', () => {
|
||
it('finds only listed groups where user is not(!) member', async () => {
|
||
const result = await query({ query: groupQuery(), variables: { isMember: false } })
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
Group: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'others-group',
|
||
slug: 'uninteresting-group',
|
||
myRole: null,
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.Group.length).toBe(1)
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('JoinGroup', () => {
|
||
beforeAll(async () => {
|
||
await seedBasicsAndClearAuthentication()
|
||
})
|
||
|
||
afterAll(async () => {
|
||
await cleanDatabase()
|
||
})
|
||
|
||
describe('unauthenticated', () => {
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'not-existing-group',
|
||
userId: 'current-user',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('authenticated', () => {
|
||
let ownerOfClosedGroupUser
|
||
let ownerOfHiddenGroupUser
|
||
|
||
beforeAll(async () => {
|
||
// create users
|
||
ownerOfClosedGroupUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'owner-of-closed-group',
|
||
name: 'Owner Of Closed Group',
|
||
},
|
||
{
|
||
email: 'owner-of-closed-group@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',
|
||
},
|
||
)
|
||
// create groups
|
||
// public-group
|
||
authenticatedUser = await ownerOfClosedGroupUser.toJson()
|
||
await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
id: 'closed-group',
|
||
name: 'Uninteresting Group',
|
||
about: 'We will change nothing!',
|
||
description: 'We love it like it is!?' + descriptionAdditional100,
|
||
groupType: 'closed',
|
||
actionRadius: 'national',
|
||
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,
|
||
},
|
||
})
|
||
authenticatedUser = await user.toJson()
|
||
await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
id: 'public-group',
|
||
name: 'The Best Group',
|
||
about: 'We will change the world!',
|
||
description: 'Some description' + descriptionAdditional100,
|
||
groupType: 'public',
|
||
actionRadius: 'regional',
|
||
categoryIds,
|
||
},
|
||
})
|
||
})
|
||
|
||
describe('public group', () => {
|
||
describe('joined by "owner-of-closed-group"', () => {
|
||
it('has "usual" as membership role', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'public-group',
|
||
userId: 'owner-of-closed-group',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
JoinGroup: {
|
||
id: 'owner-of-closed-group',
|
||
myRoleInGroup: 'usual',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('joined by its owner', () => {
|
||
describe('does not create additional "MEMBER_OF" relation and therefore', () => {
|
||
it('has still "owner" as membership role', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'public-group',
|
||
userId: 'current-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
JoinGroup: {
|
||
id: 'current-user',
|
||
myRoleInGroup: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('closed group', () => {
|
||
describe('joined by "current-user"', () => {
|
||
it('has "pending" as membership role', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'closed-group',
|
||
userId: 'current-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
JoinGroup: {
|
||
id: 'current-user',
|
||
myRoleInGroup: 'pending',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('joined by its owner', () => {
|
||
describe('does not create additional "MEMBER_OF" relation and therefore', () => {
|
||
it('has still "owner" as membership role', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'closed-group',
|
||
userId: 'owner-of-closed-group',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
JoinGroup: {
|
||
id: 'owner-of-closed-group',
|
||
myRoleInGroup: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('hidden group', () => {
|
||
describe('joined by "owner-of-closed-group"', () => {
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await query({
|
||
query: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'owner-of-closed-group',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('joined by its owner', () => {
|
||
describe('does not create additional "MEMBER_OF" relation and therefore', () => {
|
||
it('has still "owner" as membership role', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'owner-of-hidden-group',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
JoinGroup: {
|
||
id: 'owner-of-hidden-group',
|
||
myRoleInGroup: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('GroupMembers', () => {
|
||
beforeAll(async () => {
|
||
await seedBasicsAndClearAuthentication()
|
||
})
|
||
|
||
afterAll(async () => {
|
||
await cleanDatabase()
|
||
})
|
||
|
||
describe('unauthenticated', () => {
|
||
it('throws authorization error', async () => {
|
||
variables = {
|
||
id: 'not-existing-group',
|
||
}
|
||
const { errors } = await query({ query: groupMembersQuery(), variables })
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('authenticated', () => {
|
||
let otherUser
|
||
let pendingUser
|
||
let ownerOfClosedGroupUser
|
||
let ownerOfHiddenGroupUser
|
||
|
||
beforeAll(async () => {
|
||
// create users
|
||
otherUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'other-user',
|
||
name: 'Other TestUser',
|
||
},
|
||
{
|
||
email: 'other-user@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
pendingUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'pending-user',
|
||
name: 'Pending TestUser',
|
||
},
|
||
{
|
||
email: 'pending@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
ownerOfClosedGroupUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'owner-of-closed-group',
|
||
name: 'Owner Of Closed Group',
|
||
},
|
||
{
|
||
email: 'owner-of-closed-group@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',
|
||
},
|
||
)
|
||
// create groups
|
||
// public-group
|
||
authenticatedUser = await user.toJson()
|
||
await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
id: 'public-group',
|
||
name: 'The Best Group',
|
||
about: 'We will change the world!',
|
||
description: 'Some description' + descriptionAdditional100,
|
||
groupType: 'public',
|
||
actionRadius: 'regional',
|
||
categoryIds,
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'public-group',
|
||
userId: 'owner-of-closed-group',
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'public-group',
|
||
userId: 'owner-of-hidden-group',
|
||
},
|
||
})
|
||
// closed-group
|
||
authenticatedUser = await ownerOfClosedGroupUser.toJson()
|
||
await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
id: 'closed-group',
|
||
name: 'Uninteresting Group',
|
||
about: 'We will change nothing!',
|
||
description: 'We love it like it is!?' + descriptionAdditional100,
|
||
groupType: 'closed',
|
||
actionRadius: 'national',
|
||
categoryIds,
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: joinGroupMutation(),
|
||
variables: {
|
||
groupId: 'closed-group',
|
||
userId: 'current-user',
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'closed-group',
|
||
userId: 'owner-of-hidden-group',
|
||
roleInGroup: 'usual',
|
||
},
|
||
})
|
||
// hidden-group
|
||
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,
|
||
},
|
||
})
|
||
// 'JoinGroup' mutation does not work in hidden groups so we join them by 'ChangeGroupMemberRole' through the owner
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'pending-user',
|
||
roleInGroup: 'pending',
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'current-user',
|
||
roleInGroup: 'usual',
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'owner-of-closed-group',
|
||
roleInGroup: 'admin',
|
||
},
|
||
})
|
||
|
||
authenticatedUser = null
|
||
})
|
||
|
||
describe('public group', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
id: 'public-group',
|
||
}
|
||
})
|
||
|
||
describe('query group members', () => {
|
||
describe('by owner "current-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await user.toJson()
|
||
})
|
||
|
||
it('finds all members', async () => {
|
||
const result = await query({
|
||
query: groupMembersQuery(),
|
||
variables,
|
||
})
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
GroupMembers: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'current-user',
|
||
myRoleInGroup: 'owner',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-closed-group',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-hidden-group',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.GroupMembers.length).toBe(3)
|
||
})
|
||
})
|
||
|
||
describe('by usual member "owner-of-closed-group"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerOfClosedGroupUser.toJson()
|
||
})
|
||
|
||
it('finds all members', async () => {
|
||
const result = await query({
|
||
query: groupMembersQuery(),
|
||
variables,
|
||
})
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
GroupMembers: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'current-user',
|
||
myRoleInGroup: 'owner',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-closed-group',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-hidden-group',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.GroupMembers.length).toBe(3)
|
||
})
|
||
})
|
||
|
||
describe('by none member "other-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await otherUser.toJson()
|
||
})
|
||
|
||
it('finds all members', async () => {
|
||
const result = await query({
|
||
query: groupMembersQuery(),
|
||
variables,
|
||
})
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
GroupMembers: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'current-user',
|
||
myRoleInGroup: 'owner',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-closed-group',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-hidden-group',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.GroupMembers.length).toBe(3)
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('closed group', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
id: 'closed-group',
|
||
}
|
||
})
|
||
|
||
describe('query group members', () => {
|
||
describe('by owner "owner-of-closed-group"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerOfClosedGroupUser.toJson()
|
||
})
|
||
|
||
it('finds all members', async () => {
|
||
const result = await query({
|
||
query: groupMembersQuery(),
|
||
variables,
|
||
})
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
GroupMembers: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'current-user',
|
||
myRoleInGroup: 'pending',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-closed-group',
|
||
myRoleInGroup: 'owner',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-hidden-group',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.GroupMembers.length).toBe(3)
|
||
})
|
||
})
|
||
|
||
describe('by usual member "owner-of-hidden-group"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerOfHiddenGroupUser.toJson()
|
||
})
|
||
|
||
it('finds all members', async () => {
|
||
const result = await query({
|
||
query: groupMembersQuery(),
|
||
variables,
|
||
})
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
GroupMembers: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'current-user',
|
||
myRoleInGroup: 'pending',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-closed-group',
|
||
myRoleInGroup: 'owner',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-hidden-group',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.GroupMembers.length).toBe(3)
|
||
})
|
||
})
|
||
|
||
describe('by pending member "current-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await user.toJson()
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await query({ query: groupMembersQuery(), variables })
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('by none member "other-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await otherUser.toJson()
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await query({ query: groupMembersQuery(), variables })
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('hidden group', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
id: 'hidden-group',
|
||
}
|
||
})
|
||
|
||
describe('query group members', () => {
|
||
describe('by owner "owner-of-hidden-group"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerOfHiddenGroupUser.toJson()
|
||
})
|
||
|
||
it('finds all members', async () => {
|
||
const result = await query({
|
||
query: groupMembersQuery(),
|
||
variables,
|
||
})
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
GroupMembers: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'pending-user',
|
||
myRoleInGroup: 'pending',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'current-user',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-closed-group',
|
||
myRoleInGroup: 'admin',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-hidden-group',
|
||
myRoleInGroup: 'owner',
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.GroupMembers.length).toBe(4)
|
||
})
|
||
})
|
||
|
||
describe('by usual member "current-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await user.toJson()
|
||
})
|
||
|
||
it('finds all members', async () => {
|
||
const result = await query({
|
||
query: groupMembersQuery(),
|
||
variables,
|
||
})
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
GroupMembers: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'pending-user',
|
||
myRoleInGroup: 'pending',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'current-user',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-closed-group',
|
||
myRoleInGroup: 'admin',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-hidden-group',
|
||
myRoleInGroup: 'owner',
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.GroupMembers.length).toBe(4)
|
||
})
|
||
})
|
||
|
||
describe('by admin member "owner-of-closed-group"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerOfClosedGroupUser.toJson()
|
||
})
|
||
|
||
it('finds all members', async () => {
|
||
const result = await query({
|
||
query: groupMembersQuery(),
|
||
variables,
|
||
})
|
||
expect(result).toMatchObject({
|
||
data: {
|
||
GroupMembers: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
id: 'pending-user',
|
||
myRoleInGroup: 'pending',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'current-user',
|
||
myRoleInGroup: 'usual',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-closed-group',
|
||
myRoleInGroup: 'admin',
|
||
}),
|
||
expect.objectContaining({
|
||
id: 'owner-of-hidden-group',
|
||
myRoleInGroup: 'owner',
|
||
}),
|
||
]),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
expect(result.data.GroupMembers.length).toBe(4)
|
||
})
|
||
})
|
||
|
||
describe('by pending member "pending-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await pendingUser.toJson()
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await query({ query: groupMembersQuery(), variables })
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('by none member "other-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await otherUser.toJson()
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await query({ query: groupMembersQuery(), variables })
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('ChangeGroupMemberRole', () => {
|
||
beforeAll(async () => {
|
||
await seedComplexScenarioAndClearAuthentication()
|
||
})
|
||
|
||
afterAll(async () => {
|
||
await cleanDatabase()
|
||
})
|
||
|
||
describe('unauthenticated', () => {
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'not-existing-group',
|
||
userId: 'current-user',
|
||
roleInGroup: 'pending',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('authenticated', () => {
|
||
describe('in all group types – here "closed-group" for example', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
groupId: 'closed-group',
|
||
}
|
||
})
|
||
|
||
describe('join the members and give them their prospective roles', () => {
|
||
describe('by owner "owner-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
})
|
||
|
||
describe('for "usual-member-user"', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
userId: 'usual-member-user',
|
||
}
|
||
})
|
||
|
||
describe('as usual', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'usual',
|
||
}
|
||
})
|
||
|
||
it('has role usual', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
ChangeGroupMemberRole: {
|
||
id: 'usual-member-user',
|
||
myRoleInGroup: 'usual',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
|
||
// the GQL mutation needs this fields in the result for testing
|
||
it.todo('has "updatedAt" newer as "createdAt"')
|
||
})
|
||
})
|
||
|
||
describe('for "admin-member-user"', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
userId: 'admin-member-user',
|
||
}
|
||
})
|
||
|
||
describe('as admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('has role admin', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
ChangeGroupMemberRole: {
|
||
id: 'admin-member-user',
|
||
myRoleInGroup: 'admin',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('for "second-owner-member-user"', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
userId: 'second-owner-member-user',
|
||
}
|
||
})
|
||
|
||
describe('as owner', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'owner',
|
||
}
|
||
})
|
||
|
||
it('has role owner', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
ChangeGroupMemberRole: {
|
||
id: 'second-owner-member-user',
|
||
myRoleInGroup: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('switch role', () => {
|
||
describe('of owner "owner-member-user"', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
userId: 'owner-member-user',
|
||
}
|
||
})
|
||
|
||
describe('by owner themself "owner-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
})
|
||
|
||
describe('to admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
|
||
// shall this be possible in the future?
|
||
// or shall only an owner who gave the second owner the owner role downgrade themself for savety?
|
||
// otherwise the first owner who downgrades the other one has the victory over the group!
|
||
describe('by second owner "second-owner-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await secondOwnerMemberUser.toJson()
|
||
})
|
||
|
||
describe('to admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('to same role owner', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'owner',
|
||
}
|
||
})
|
||
|
||
it('has role owner still', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
ChangeGroupMemberRole: {
|
||
id: 'owner-member-user',
|
||
myRoleInGroup: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by admin "admin-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await adminMemberUser.toJson()
|
||
})
|
||
|
||
describe('to admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by usual member "usual-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await usualMemberUser.toJson()
|
||
})
|
||
|
||
describe('to admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by still pending member "pending-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await pendingMemberUser.toJson()
|
||
})
|
||
|
||
describe('to admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('of admin "admin-member-user"', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
userId: 'admin-member-user',
|
||
}
|
||
})
|
||
|
||
describe('by owner "owner-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
})
|
||
|
||
describe('to owner', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'owner',
|
||
}
|
||
})
|
||
|
||
it('has role owner', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
ChangeGroupMemberRole: {
|
||
id: 'admin-member-user',
|
||
myRoleInGroup: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('back to admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by usual member "usual-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await usualMemberUser.toJson()
|
||
})
|
||
|
||
describe('upgrade to owner', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'owner',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('degrade to usual', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'usual',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by still pending member "pending-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await pendingMemberUser.toJson()
|
||
})
|
||
|
||
describe('upgrade to owner', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'owner',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('degrade to usual', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'usual',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by none member "current-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await user.toJson()
|
||
})
|
||
|
||
describe('upgrade to owner', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'owner',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('degrade to pending again', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'pending',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('of usual member "usual-member-user"', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
userId: 'usual-member-user',
|
||
}
|
||
})
|
||
|
||
describe('by owner "owner-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
})
|
||
|
||
describe('to admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('has role admin', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
ChangeGroupMemberRole: {
|
||
id: 'usual-member-user',
|
||
myRoleInGroup: 'admin',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('back to usual', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'usual',
|
||
}
|
||
})
|
||
|
||
it('has role usual again', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
ChangeGroupMemberRole: {
|
||
id: 'usual-member-user',
|
||
myRoleInGroup: 'usual',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by usual member "usual-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await usualMemberUser.toJson()
|
||
})
|
||
|
||
describe('upgrade to admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('degrade to pending', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'pending',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by still pending member "pending-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await pendingMemberUser.toJson()
|
||
})
|
||
|
||
describe('upgrade to admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('degrade to pending', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'pending',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by none member "current-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await user.toJson()
|
||
})
|
||
|
||
describe('upgrade to admin', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'admin',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('degrade to pending again', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'pending',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('of still pending member "pending-member-user"', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
userId: 'pending-member-user',
|
||
}
|
||
})
|
||
|
||
describe('by owner "owner-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
})
|
||
|
||
describe('to usual', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'usual',
|
||
}
|
||
})
|
||
|
||
it('has role usual', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
ChangeGroupMemberRole: {
|
||
id: 'pending-member-user',
|
||
myRoleInGroup: 'usual',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('back to pending', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'pending',
|
||
}
|
||
})
|
||
|
||
it('has role usual again', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
ChangeGroupMemberRole: {
|
||
id: 'pending-member-user',
|
||
myRoleInGroup: 'pending',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by usual member "usual-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await usualMemberUser.toJson()
|
||
})
|
||
|
||
describe('upgrade to usual', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'usual',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by still pending member "pending-member-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await pendingMemberUser.toJson()
|
||
})
|
||
|
||
describe('upgrade to usual', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'usual',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('by none member "current-user"', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await user.toJson()
|
||
})
|
||
|
||
describe('upgrade to usual', () => {
|
||
beforeEach(async () => {
|
||
variables = {
|
||
...variables,
|
||
roleInGroup: 'usual',
|
||
}
|
||
})
|
||
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables,
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('LeaveGroup', () => {
|
||
beforeAll(async () => {
|
||
await seedComplexScenarioAndClearAuthentication()
|
||
// closed-group
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'closed-group',
|
||
userId: 'pending-member-user',
|
||
roleInGroup: 'pending',
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'closed-group',
|
||
userId: 'usual-member-user',
|
||
roleInGroup: 'usual',
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'closed-group',
|
||
userId: 'admin-member-user',
|
||
roleInGroup: 'admin',
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'closed-group',
|
||
userId: 'second-owner-member-user',
|
||
roleInGroup: 'owner',
|
||
},
|
||
})
|
||
|
||
authenticatedUser = null
|
||
})
|
||
|
||
afterAll(async () => {
|
||
await cleanDatabase()
|
||
})
|
||
|
||
describe('unauthenticated', () => {
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: leaveGroupMutation(),
|
||
variables: {
|
||
groupId: 'not-existing-group',
|
||
userId: 'current-user',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('authenticated', () => {
|
||
describe('in all group types', () => {
|
||
describe('here "closed-group" for example', () => {
|
||
const memberInGroup = async (userId, groupId) => {
|
||
const result = await query({
|
||
query: groupMembersQuery(),
|
||
variables: {
|
||
id: groupId,
|
||
},
|
||
})
|
||
return result.data && result.data.GroupMembers
|
||
? !!result.data.GroupMembers.find((member) => member.id === userId)
|
||
: null
|
||
}
|
||
|
||
beforeEach(async () => {
|
||
authenticatedUser = null
|
||
variables = {
|
||
groupId: 'closed-group',
|
||
}
|
||
})
|
||
|
||
describe('left by "pending-member-user"', () => {
|
||
it('has "null" as membership role, was in the group, and left the group', async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
expect(await memberInGroup('pending-member-user', 'closed-group')).toBe(true)
|
||
authenticatedUser = await pendingMemberUser.toJson()
|
||
await expect(
|
||
mutate({
|
||
mutation: leaveGroupMutation(),
|
||
variables: {
|
||
...variables,
|
||
userId: 'pending-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
LeaveGroup: {
|
||
id: 'pending-member-user',
|
||
myRoleInGroup: null,
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
expect(await memberInGroup('pending-member-user', 'closed-group')).toBe(false)
|
||
})
|
||
})
|
||
|
||
describe('left by "usual-member-user"', () => {
|
||
it('has "null" as membership role, was in the group, and left the group', async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
expect(await memberInGroup('usual-member-user', 'closed-group')).toBe(true)
|
||
authenticatedUser = await usualMemberUser.toJson()
|
||
await expect(
|
||
mutate({
|
||
mutation: leaveGroupMutation(),
|
||
variables: {
|
||
...variables,
|
||
userId: 'usual-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
LeaveGroup: {
|
||
id: 'usual-member-user',
|
||
myRoleInGroup: null,
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
expect(await memberInGroup('usual-member-user', 'closed-group')).toBe(false)
|
||
})
|
||
})
|
||
|
||
describe('left by "admin-member-user"', () => {
|
||
it('has "null" as membership role, was in the group, and left the group', async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
expect(await memberInGroup('admin-member-user', 'closed-group')).toBe(true)
|
||
authenticatedUser = await adminMemberUser.toJson()
|
||
await expect(
|
||
mutate({
|
||
mutation: leaveGroupMutation(),
|
||
variables: {
|
||
...variables,
|
||
userId: 'admin-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
LeaveGroup: {
|
||
id: 'admin-member-user',
|
||
myRoleInGroup: null,
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
expect(await memberInGroup('admin-member-user', 'closed-group')).toBe(false)
|
||
})
|
||
})
|
||
|
||
describe('left by "owner-member-user"', () => {
|
||
it('throws authorization error', async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
const { errors } = await mutate({
|
||
mutation: leaveGroupMutation(),
|
||
variables: {
|
||
...variables,
|
||
userId: 'owner-member-user',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('left by "second-owner-member-user"', () => {
|
||
it('throws authorization error', async () => {
|
||
authenticatedUser = await secondOwnerMemberUser.toJson()
|
||
const { errors } = await mutate({
|
||
mutation: leaveGroupMutation(),
|
||
variables: {
|
||
...variables,
|
||
userId: 'second-owner-member-user',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('left by "none-member-user"', () => {
|
||
it('throws authorization error', async () => {
|
||
authenticatedUser = await noMemberUser.toJson()
|
||
const { errors } = await mutate({
|
||
mutation: leaveGroupMutation(),
|
||
variables: {
|
||
...variables,
|
||
userId: 'none-member-user',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('as "owner-member-user" try to leave member "usual-member-user"', () => {
|
||
it('throws authorization error', async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
const { errors } = await mutate({
|
||
mutation: leaveGroupMutation(),
|
||
variables: {
|
||
...variables,
|
||
userId: 'usual-member-user',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('as "usual-member-user" try to leave member "admin-member-user"', () => {
|
||
it('throws authorization error', async () => {
|
||
authenticatedUser = await usualMemberUser.toJson()
|
||
const { errors } = await mutate({
|
||
mutation: leaveGroupMutation(),
|
||
variables: {
|
||
...variables,
|
||
userId: 'admin-member-user',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('UpdateGroup', () => {
|
||
beforeAll(async () => {
|
||
await seedBasicsAndClearAuthentication()
|
||
})
|
||
|
||
afterAll(async () => {
|
||
await cleanDatabase()
|
||
})
|
||
|
||
describe('unauthenticated', () => {
|
||
it('throws authorization error', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
slug: 'my-best-group',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('authenticated', () => {
|
||
let noMemberUser
|
||
|
||
beforeAll(async () => {
|
||
noMemberUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'none-member-user',
|
||
name: 'None Member TestUser',
|
||
},
|
||
{
|
||
email: 'none-member-user@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
usualMemberUser = await Factory.build(
|
||
'user',
|
||
{
|
||
id: 'usual-member-user',
|
||
name: 'Usual Member TestUser',
|
||
},
|
||
{
|
||
email: 'usual-member-user@example.org',
|
||
password: '1234',
|
||
},
|
||
)
|
||
authenticatedUser = await noMemberUser.toJson()
|
||
await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
id: 'others-group',
|
||
name: 'Uninteresting Group',
|
||
about: 'We will change nothing!',
|
||
description: 'We love it like it is!?' + descriptionAdditional100,
|
||
groupType: 'closed',
|
||
actionRadius: 'global',
|
||
categoryIds,
|
||
},
|
||
})
|
||
authenticatedUser = await user.toJson()
|
||
await mutate({
|
||
mutation: createGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
name: 'The Best Group',
|
||
about: 'We will change the world!',
|
||
description: 'Some description' + descriptionAdditional100,
|
||
groupType: 'public',
|
||
actionRadius: 'regional',
|
||
categoryIds,
|
||
locationName: 'Berlin, Germany',
|
||
},
|
||
})
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'my-group',
|
||
userId: 'usual-member-user',
|
||
roleInGroup: 'usual',
|
||
},
|
||
})
|
||
})
|
||
|
||
describe('change group settings', () => {
|
||
describe('as owner', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await user.toJson()
|
||
})
|
||
|
||
describe('all standard settings – excluding location', () => {
|
||
it('has updated the settings', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
name: 'The New Group For Our Country',
|
||
about: 'We will change the land!',
|
||
description: 'Some country relevant description' + descriptionAdditional100,
|
||
actionRadius: 'national',
|
||
// avatar, // test this as result
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
UpdateGroup: {
|
||
id: 'my-group',
|
||
name: 'The New Group For Our Country',
|
||
slug: 'the-best-group', // changing the slug is tested in the slugifyMiddleware
|
||
about: 'We will change the land!',
|
||
description: 'Some country relevant description' + descriptionAdditional100,
|
||
descriptionExcerpt:
|
||
'Some country relevant description' + descriptionAdditional100,
|
||
actionRadius: 'national',
|
||
// avatar, // test this as result
|
||
myRole: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('location', () => {
|
||
describe('"locationName" is undefined – shall not change location', () => {
|
||
it('has left locaton unchanged as "Berlin"', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
UpdateGroup: {
|
||
id: 'my-group',
|
||
locationName: 'Berlin, Germany',
|
||
location: expect.objectContaining({
|
||
name: 'Berlin',
|
||
nameDE: 'Berlin',
|
||
nameEN: 'Berlin',
|
||
}),
|
||
myRole: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('"locationName" is null – shall change location "Berlin" to unset location', () => {
|
||
it('has updated the location to unset location', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
locationName: null,
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
UpdateGroup: {
|
||
id: 'my-group',
|
||
locationName: null,
|
||
location: null,
|
||
myRole: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('change unset location to "Paris"', () => {
|
||
it('has updated the location to "Paris"', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
locationName: 'Paris, France',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
UpdateGroup: {
|
||
id: 'my-group',
|
||
locationName: 'Paris, France',
|
||
location: expect.objectContaining({
|
||
name: 'Paris',
|
||
nameDE: 'Paris',
|
||
nameEN: 'Paris',
|
||
}),
|
||
myRole: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('change location "Paris" to "Hamburg"', () => {
|
||
it('has updated the location to "Hamburg"', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
locationName: 'Hamburg, Germany',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
UpdateGroup: {
|
||
id: 'my-group',
|
||
locationName: 'Hamburg, Germany',
|
||
location: expect.objectContaining({
|
||
name: 'Hamburg',
|
||
nameDE: 'Hamburg',
|
||
nameEN: 'Hamburg',
|
||
}),
|
||
myRole: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('"locationName" is empty string – shall change location "Hamburg" to unset location ', () => {
|
||
it('has updated the location to unset', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
locationName: '', // empty string '' sets it to null
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
UpdateGroup: {
|
||
id: 'my-group',
|
||
locationName: null,
|
||
location: null,
|
||
myRole: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('description', () => {
|
||
describe('length without HTML', () => {
|
||
describe('less then 100 chars', () => {
|
||
it('throws error: "Description too short!"', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
description:
|
||
'0123456789' +
|
||
'<a href="https://domain.org/0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789">0123456789</a>',
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Description too short!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('categories', () => {
|
||
beforeEach(async () => {
|
||
CONFIG.CATEGORIES_ACTIVE = true
|
||
})
|
||
|
||
describe('with matching amount of categories', () => {
|
||
it('has new categories', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
categoryIds: ['cat4', 'cat27'],
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
UpdateGroup: {
|
||
id: 'my-group',
|
||
categories: expect.arrayContaining([
|
||
expect.objectContaining({ id: 'cat4' }),
|
||
expect.objectContaining({ id: 'cat27' }),
|
||
]),
|
||
myRole: 'owner',
|
||
},
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('not even one', () => {
|
||
describe('by "categoryIds: []"', () => {
|
||
it('throws error: "Too view categories!"', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
categoryIds: [],
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Too view categories!')
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('four', () => {
|
||
it('throws error: "Too many categories!"', async () => {
|
||
const { errors } = await mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
categoryIds: ['cat9', 'cat4', 'cat15', 'cat27'],
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Too many categories!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('as "usual-member-user" member, no(!) owner', () => {
|
||
it('throws authorization error', async () => {
|
||
authenticatedUser = await usualMemberUser.toJson()
|
||
const { errors } = await mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
name: 'The New Group For Our Country',
|
||
about: 'We will change the land!',
|
||
description: 'Some country relevant description' + descriptionAdditional100,
|
||
actionRadius: 'national',
|
||
categoryIds: ['cat4', 'cat27'],
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
|
||
describe('as "none-member-user"', () => {
|
||
it('throws authorization error', async () => {
|
||
authenticatedUser = await noMemberUser.toJson()
|
||
const { errors } = await mutate({
|
||
mutation: updateGroupMutation(),
|
||
variables: {
|
||
id: 'my-group',
|
||
name: 'The New Group For Our Country',
|
||
about: 'We will change the land!',
|
||
description: 'Some country relevant description' + descriptionAdditional100,
|
||
actionRadius: 'national',
|
||
categoryIds: ['cat4', 'cat27'],
|
||
},
|
||
})
|
||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('RemoveUserFromGroup', () => {
|
||
beforeAll(async () => {
|
||
await seedComplexScenarioAndClearAuthentication()
|
||
})
|
||
|
||
afterAll(async () => {
|
||
await cleanDatabase()
|
||
})
|
||
|
||
describe('unauthenticated', () => {
|
||
it('throws an error', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: removeUserFromGroupMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'usual-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
errors: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
message: 'Not Authorized!',
|
||
}),
|
||
]),
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('authenticated', () => {
|
||
describe('as usual member', () => {
|
||
it('throws an error', async () => {
|
||
authenticatedUser = await usualMemberUser.toJson()
|
||
await expect(
|
||
mutate({
|
||
mutation: removeUserFromGroupMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'admin-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
errors: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
message: 'Not Authorized!',
|
||
}),
|
||
]),
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('as owner', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await ownerMemberUser.toJson()
|
||
})
|
||
|
||
it('removes the user from the group', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: removeUserFromGroupMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'usual-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
RemoveUserFromGroup: expect.objectContaining({
|
||
id: 'usual-member-user',
|
||
myRoleInGroup: null,
|
||
}),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
|
||
it('cannot remove self', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: removeUserFromGroupMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'owner-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
errors: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
message: 'Not Authorized!',
|
||
}),
|
||
]),
|
||
})
|
||
})
|
||
})
|
||
|
||
describe('as admin', () => {
|
||
beforeEach(async () => {
|
||
authenticatedUser = await adminMemberUser.toJson()
|
||
await mutate({
|
||
mutation: changeGroupMemberRoleMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'usual-member-user',
|
||
roleInGroup: 'usual',
|
||
},
|
||
})
|
||
})
|
||
|
||
it('throws an error', async () => {
|
||
authenticatedUser = await usualMemberUser.toJson()
|
||
await expect(
|
||
mutate({
|
||
mutation: removeUserFromGroupMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'admin-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
errors: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
message: 'Not Authorized!',
|
||
}),
|
||
]),
|
||
})
|
||
})
|
||
|
||
/*
|
||
it('removes the user from the group', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: removeUserFromGroupMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'usual-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
data: {
|
||
RemoveUserFromGroup: expect.objectContaining({
|
||
id: 'usual-member-user',
|
||
myRoleInGroup: null,
|
||
}),
|
||
},
|
||
errors: undefined,
|
||
})
|
||
})
|
||
|
||
it('cannot remove self', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: removeUserFromGroupMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'admin-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
errors: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
message: 'Not Authorized!',
|
||
}),
|
||
]),
|
||
})
|
||
})
|
||
|
||
it('cannot remove owner', async () => {
|
||
await expect(
|
||
mutate({
|
||
mutation: removeUserFromGroupMutation(),
|
||
variables: {
|
||
groupId: 'hidden-group',
|
||
userId: 'owner-member-user',
|
||
},
|
||
}),
|
||
).resolves.toMatchObject({
|
||
errors: expect.arrayContaining([
|
||
expect.objectContaining({
|
||
message: 'Not Authorized!',
|
||
}),
|
||
]),
|
||
})
|
||
})
|
||
*/
|
||
})
|
||
})
|
||
})
|
||
})
|