diff --git a/backend/src/db/graphql/groups.js b/backend/src/db/graphql/groups.js index 4562fa4b4..773a27cbe 100644 --- a/backend/src/db/graphql/groups.js +++ b/backend/src/db/graphql/groups.js @@ -55,57 +55,59 @@ export const createGroupMutation = () => { ` } -export const updateGroupMutation = gql` - mutation ( - $id: ID! - $name: String - $slug: String - $about: String - $description: String - $actionRadius: GroupActionRadius - $categoryIds: [ID] - $avatar: ImageInput - $locationName: String # empty string '' sets it to null - ) { - UpdateGroup( - id: $id - name: $name - slug: $slug - about: $about - description: $description - actionRadius: $actionRadius - categoryIds: $categoryIds - avatar: $avatar - locationName: $locationName +export const updateGroupMutation = () => { + return gql` + mutation ( + $id: ID! + $name: String + $slug: String + $about: String + $description: String + $actionRadius: GroupActionRadius + $categoryIds: [ID] + $avatar: ImageInput + $locationName: String # empty string '' sets it to null ) { - id - name - slug - createdAt - updatedAt - disabled - deleted - about - description - groupType - actionRadius - categories { + UpdateGroup( + id: $id + name: $name + slug: $slug + about: $about + description: $description + actionRadius: $actionRadius + categoryIds: $categoryIds + avatar: $avatar + locationName: $locationName + ) { id + name slug - name - icon + createdAt + updatedAt + disabled + deleted + about + description + groupType + actionRadius + categories { + id + slug + name + icon + } + # avatar # test this as result + locationName + location { + name + nameDE + nameEN + } + myRole } - # avatar # test this as result - locationName - location { - name - nameDE - nameEN - } - myRole } - } -` + ` +} export const joinGroupMutation = gql` mutation ($groupId: ID!, $userId: ID!) { diff --git a/backend/src/middleware/slugifyMiddleware.spec.js b/backend/src/middleware/slugifyMiddleware.spec.js index 8e4460103..c600d0e52 100644 --- a/backend/src/middleware/slugifyMiddleware.spec.js +++ b/backend/src/middleware/slugifyMiddleware.spec.js @@ -51,6 +51,7 @@ beforeEach(async () => { await Factory.build('category', { id: 'cat9', name: 'Democracy & Politics', + slug: 'democracy-politics', icon: 'university', }) authenticatedUser = await admin.toJson() @@ -93,6 +94,7 @@ describe('slugifyMiddleware', () => { actionRadius: 'national', }, }, + errors: undefined, }) }) @@ -111,6 +113,7 @@ describe('slugifyMiddleware', () => { slug: 'the-group', }, }, + errors: undefined, }) }) }) @@ -144,6 +147,7 @@ describe('slugifyMiddleware', () => { slug: 'pre-existing-group-1', }, }, + errors: undefined, }) }) @@ -213,7 +217,7 @@ describe('slugifyMiddleware', () => { it('has the new slug', async () => { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: createGroupResult.data.CreateGroup.id, name: 'My Best Group', @@ -231,6 +235,7 @@ describe('slugifyMiddleware', () => { myRole: 'owner', }, }, + errors: undefined, }) }) }) @@ -239,7 +244,7 @@ describe('slugifyMiddleware', () => { it('has the new slug', async () => { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: createGroupResult.data.CreateGroup.id, slug: 'my-best-group', @@ -257,6 +262,7 @@ describe('slugifyMiddleware', () => { myRole: 'owner', }, }, + errors: undefined, }) }) }) @@ -282,7 +288,7 @@ describe('slugifyMiddleware', () => { it('has unique slug "*-1"', async () => { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: createGroupResult.data.CreateGroup.id, name: 'Pre-Existing Group', @@ -300,6 +306,7 @@ describe('slugifyMiddleware', () => { myRole: 'owner', }, }, + errors: undefined, }) }) }) @@ -309,7 +316,7 @@ describe('slugifyMiddleware', () => { try { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: createGroupResult.data.CreateGroup.id, slug: 'pre-existing-group', @@ -368,6 +375,7 @@ describe('slugifyMiddleware', () => { slug: 'i-am-a-brand-new-post', }, }, + errors: undefined, }) }) @@ -386,6 +394,7 @@ describe('slugifyMiddleware', () => { slug: 'the-post', }, }, + errors: undefined, }) }) }) @@ -422,6 +431,7 @@ describe('slugifyMiddleware', () => { slug: 'pre-existing-post-1', }, }, + errors: undefined, }) }) @@ -504,6 +514,7 @@ describe('slugifyMiddleware', () => { slug: 'i-am-a-user', }, }, + errors: undefined, }) }) @@ -522,6 +533,7 @@ describe('slugifyMiddleware', () => { slug: 'the-user', }, }, + errors: undefined, }) }) }) @@ -546,6 +558,7 @@ describe('slugifyMiddleware', () => { slug: 'i-am-a-user-1', }, }, + errors: undefined, }) }) diff --git a/backend/src/schema/resolvers/groups.js b/backend/src/schema/resolvers/groups.js index 4b3d645eb..2617bd43e 100644 --- a/backend/src/schema/resolvers/groups.js +++ b/backend/src/schema/resolvers/groups.js @@ -86,6 +86,7 @@ export default { CreateGroup: async (_parent, params, context, _resolveInfo) => { const { categoryIds } = params delete params.categoryIds + params.locationName = params.locationName === '' ? null : params.locationName if (CONFIG.CATEGORIES_ACTIVE && (!categoryIds || categoryIds.length < CATEGORIES_MIN)) { throw new UserInputError('Too view categories!') } @@ -137,6 +138,7 @@ export default { }) try { const group = await writeTxResultPromise + // TODO: put in a middleware, see "UpdateGroup", "UpdateUser" await createOrUpdateLocations('Group', params.id, params.locationName, session) return group } catch (error) { @@ -212,10 +214,8 @@ export default { }) try { const group = await writeTxResultPromise - // TODO: put in a middleware, see "UpdateUser" - if (params.locationName !== undefined) { - await createOrUpdateLocations('Group', params.id, params.locationName, session) - } + // TODO: put in a middleware, see "CreateGroup", "UpdateUser" + await createOrUpdateLocations('Group', params.id, params.locationName, session) return group } catch (error) { if (error.code === 'Neo.ClientError.Schema.ConstraintValidationFailed') diff --git a/backend/src/schema/resolvers/groups.spec.js b/backend/src/schema/resolvers/groups.spec.js index 816bfcbc9..a8ab4f3fc 100644 --- a/backend/src/schema/resolvers/groups.spec.js +++ b/backend/src/schema/resolvers/groups.spec.js @@ -2610,7 +2610,7 @@ describe('in mode', () => { describe('unauthenticated', () => { it('throws authorization error', async () => { const { errors } = await mutate({ - query: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', slug: 'my-best-group', @@ -2693,7 +2693,7 @@ describe('in mode', () => { it('has updated the settings', async () => { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', name: 'The New Group For Our Country', @@ -2726,7 +2726,7 @@ describe('in mode', () => { it('has left locaton unchanged as "Berlin"', async () => { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', }, @@ -2753,7 +2753,7 @@ describe('in mode', () => { it('has updated the location to unset location', async () => { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', locationName: null, @@ -2777,7 +2777,7 @@ describe('in mode', () => { it('has updated the location to "Paris"', async () => { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', locationName: 'Paris, France', @@ -2805,7 +2805,7 @@ describe('in mode', () => { it('has updated the location to "Hamburg"', async () => { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', locationName: 'Hamburg, Germany', @@ -2833,7 +2833,7 @@ describe('in mode', () => { it('has updated the location to unset', async () => { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', locationName: '', // empty string '' sets it to null @@ -2859,7 +2859,7 @@ describe('in mode', () => { describe('less then 100 chars', () => { it('throws error: "Description too short!"', async () => { const { errors } = await mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', description: @@ -2882,7 +2882,7 @@ describe('in mode', () => { it('has new categories', async () => { await expect( mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', categoryIds: ['cat4', 'cat27'], @@ -2908,7 +2908,7 @@ describe('in mode', () => { describe('by "categoryIds: []"', () => { it('throws error: "Too view categories!"', async () => { const { errors } = await mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', categoryIds: [], @@ -2922,7 +2922,7 @@ describe('in mode', () => { describe('four', () => { it('throws error: "Too many categories!"', async () => { const { errors } = await mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', categoryIds: ['cat9', 'cat4', 'cat15', 'cat27'], @@ -2938,7 +2938,7 @@ describe('in mode', () => { it('throws authorization error', async () => { authenticatedUser = await usualMemberUser.toJson() const { errors } = await mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', name: 'The New Group For Our Country', @@ -2956,7 +2956,7 @@ describe('in mode', () => { it('throws authorization error', async () => { authenticatedUser = await noMemberUser.toJson() const { errors } = await mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables: { id: 'my-group', name: 'The New Group For Our Country', diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index f03f0a7ca..1ce3b986f 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -170,10 +170,8 @@ export default { }) try { const user = await writeTxResultPromise - // TODO: put in a middleware, see "CreateGroup, UpdateGroup" - if (params.locationName !== undefined) { - await createOrUpdateLocations('User', params.id, params.locationName, session) - } + // TODO: put in a middleware, see "CreateGroup", "UpdateGroup" + await createOrUpdateLocations('User', params.id, params.locationName, session) return user } catch (error) { throw new UserInputError(error.message) diff --git a/backend/src/schema/resolvers/users.spec.js b/backend/src/schema/resolvers/users.spec.js index b31477664..87226ec4d 100644 --- a/backend/src/schema/resolvers/users.spec.js +++ b/backend/src/schema/resolvers/users.spec.js @@ -174,6 +174,11 @@ describe('UpdateUser', () => { termsAndConditionsAgreedVersion termsAndConditionsAgreedAt locationName + location { + name + nameDE + nameEN + } } } ` @@ -289,11 +294,39 @@ describe('UpdateUser', () => { expect(errors[0]).toHaveProperty('message', 'Invalid version format!') }) - it('supports updating location', async () => { - variables = { ...variables, locationName: 'Hamburg, New Jersey, United States' } - await expect(mutate({ mutation: updateUserMutation, variables })).resolves.toMatchObject({ - data: { UpdateUser: { locationName: 'Hamburg, New Jersey, United States' } }, - errors: undefined, + describe('supports updating location', () => { + describe('change location to "Hamburg, New Jersey, United States"', () => { + it('has updated location to "Hamburg, New Jersey, United States"', async () => { + variables = { ...variables, locationName: 'Hamburg, New Jersey, United States' } + await expect(mutate({ mutation: updateUserMutation, variables })).resolves.toMatchObject({ + data: { + UpdateUser: { + locationName: 'Hamburg, New Jersey, United States', + location: expect.objectContaining({ + name: 'Hamburg', + nameDE: 'Hamburg', + nameEN: 'Hamburg', + }), + }, + }, + errors: undefined, + }) + }) + }) + + describe('change location to unset location', () => { + it('has updated location to unset location', async () => { + variables = { ...variables, locationName: '' } + await expect(mutate({ mutation: updateUserMutation, variables })).resolves.toMatchObject({ + data: { + UpdateUser: { + locationName: null, + location: null, + }, + }, + errors: undefined, + }) + }) }) }) }) diff --git a/backend/src/schema/resolvers/users/location.js b/backend/src/schema/resolvers/users/location.js index 25b813f53..9d8a11f89 100644 --- a/backend/src/schema/resolvers/users/location.js +++ b/backend/src/schema/resolvers/users/location.js @@ -62,6 +62,8 @@ const createLocation = async (session, mapboxData) => { } export const createOrUpdateLocations = async (nodeLabel, nodeId, locationName, session) => { + if (locationName === undefined) return + let locationId if (locationName !== null) { diff --git a/webapp/components/Uploader/AvatarUploader.vue b/webapp/components/Uploader/AvatarUploader.vue index be8744ac2..39cb9136b 100644 --- a/webapp/components/Uploader/AvatarUploader.vue +++ b/webapp/components/Uploader/AvatarUploader.vue @@ -29,7 +29,7 @@ export default { }, props: { profile: { type: Object, required: true }, - updateMutation: { type: Object, required: true }, + updateMutation: { type: Function, required: true }, }, data() { return { @@ -69,7 +69,7 @@ export default { const avatarUpload = file[0] this.$apollo .mutate({ - mutation: this.updateMutation, + mutation: this.updateMutation(), variables: { avatar: { upload: avatarUpload, diff --git a/webapp/graphql/groups.js b/webapp/graphql/groups.js index 157a6d7dc..ae7dd93a7 100644 --- a/webapp/graphql/groups.js +++ b/webapp/graphql/groups.js @@ -50,53 +50,55 @@ export const createGroupMutation = () => { ` } -export const updateGroupMutation = gql` - mutation ( - $id: ID! - $name: String - $slug: String - $about: String - $description: String - $actionRadius: GroupActionRadius - $categoryIds: [ID] - $avatar: ImageInput - $locationName: String # empty string '' sets it to null - ) { - UpdateGroup( - id: $id - name: $name - slug: $slug - about: $about - description: $description - actionRadius: $actionRadius - categoryIds: $categoryIds - avatar: $avatar - locationName: $locationName +export const updateGroupMutation = () => { + return gql` + mutation ( + $id: ID! + $name: String + $slug: String + $about: String + $description: String + $actionRadius: GroupActionRadius + $categoryIds: [ID] + $avatar: ImageInput + $locationName: String # empty string '' sets it to null ) { - id - name - slug - createdAt - updatedAt - disabled - deleted - about - description - descriptionExcerpt - groupType - actionRadius - categories { + UpdateGroup( + id: $id + name: $name + slug: $slug + about: $about + description: $description + actionRadius: $actionRadius + categoryIds: $categoryIds + avatar: $avatar + locationName: $locationName + ) { id - slug name - icon + slug + createdAt + updatedAt + disabled + deleted + about + description + descriptionExcerpt + groupType + actionRadius + categories { + id + slug + name + icon + } + # avatar # test this as result + locationName # test this as result + myRole } - # avatar # test this as result - locationName # test this as result - myRole } - } -` + ` +} export const joinGroupMutation = gql` mutation ($groupId: ID!, $userId: ID!) { diff --git a/webapp/pages/group/edit/_id/index.vue b/webapp/pages/group/edit/_id/index.vue index 7930f92fc..8dcbfd445 100644 --- a/webapp/pages/group/edit/_id/index.vue +++ b/webapp/pages/group/edit/_id/index.vue @@ -27,7 +27,7 @@ export default { const variables = { id, name, about, description, groupType, actionRadius, categoryIds } try { await this.$apollo.mutate({ - mutation: updateGroupMutation, + mutation: updateGroupMutation(), variables, }) this.$toast.success(this.$t('group.group-updated')) diff --git a/webapp/pages/profile/_id/_slug.vue b/webapp/pages/profile/_id/_slug.vue index 1bbc31eca..668c271d6 100644 --- a/webapp/pages/profile/_id/_slug.vue +++ b/webapp/pages/profile/_id/_slug.vue @@ -237,7 +237,7 @@ export default { followedByCountStartValue: 0, followedByCount: followListVisibleCount, followingCount: followListVisibleCount, - updateUserMutation: updateUserMutation(), + updateUserMutation, } }, computed: {