diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index 0f45304fd..29b2e64b9 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -57,7 +57,7 @@ const permissions = shield({ UpdateBadge: isAdmin, DeleteBadge: isAdmin, AddUserBadges: isAdmin, - addSocialMedia: isAuthenticated, + CreateSocialMedia: isAuthenticated, // AddBadgeRewarded: isAdmin, // RemoveBadgeRewarded: isAdmin, reward: isAdmin, diff --git a/backend/src/resolvers/socialMedia.js b/backend/src/resolvers/socialMedia.js new file mode 100644 index 000000000..40c540645 --- /dev/null +++ b/backend/src/resolvers/socialMedia.js @@ -0,0 +1,22 @@ +import { neo4jgraphql } from 'neo4j-graphql-js' + +export default { + Mutation: { + createSocialMedia: async (object, params, context, resolveInfo) => { + const result = await neo4jgraphql(object, params, context, resolveInfo, true) + + const session = context.driver.session() + await session.run( + 'MATCH (owner:User {id: $userId}), (socialMedia:SocialMedia {id: $socialMediaId}) ' + + 'MERGE (socialMedia)<-[:OWNED]-(owner) ' + + 'RETURN owner', { + userId: context.user.id, + socialMediaId: result.id + } + ) + session.close() + + return result + } + } +} diff --git a/backend/src/resolvers/user_management.js b/backend/src/resolvers/user_management.js index 14327ca36..c20baaf51 100644 --- a/backend/src/resolvers/user_management.js +++ b/backend/src/resolvers/user_management.js @@ -100,27 +100,6 @@ export default { return encode(currentUser) } - }, - addSocialMedia: async (_, { url }, { driver, user }) => { - const session = driver.session() - - const { id } = user - const result = await session.run( - `MATCH (user:User {id: $userId}) - SET user.socialMedia = user.socialMedia + $url - RETURN user {.socialMedia} - `, - { - userId: id, - url - } - ) - session.close() - const [currentUser] = result.records.map(record => { - return record.get('user') - }) - - return currentUser.socialMedia } } -} +} \ No newline at end of file diff --git a/backend/src/resolvers/user_management.spec.js b/backend/src/resolvers/user_management.spec.js index a6ef48ee5..ac3856c52 100644 --- a/backend/src/resolvers/user_management.spec.js +++ b/backend/src/resolvers/user_management.spec.js @@ -310,12 +310,14 @@ describe('change password', () => { }) }) -describe('addSocialMedia', () => { +describe('CreateSocialMedia', () => { let client let headers const mutation = ` - mutation($url: String!) { - addSocialMedia(url: $url) + mutation($input: SocialMediaInput) { + CreateSocialMedia(input: $input) { + url + } } ` @@ -326,12 +328,12 @@ describe('addSocialMedia', () => { }) it('rejects empty string', async () => { - const variables = { url: '' } + const variables = { input: { url: '' } } await expect(client.request(mutation, variables)).rejects.toThrow('Input is not a URL') }) it('validates URLs', async () => { - const variables = { url: 'not-a-url' } + const variables = { input: { url: 'not-a-url' } } await expect(client.request(mutation, variables)).rejects.toThrow('Input is not a URL') }) }) diff --git a/backend/src/schema.graphql b/backend/src/schema.graphql index c9a3d919d..80bb3530e 100644 --- a/backend/src/schema.graphql +++ b/backend/src/schema.graphql @@ -26,7 +26,7 @@ type Mutation { disable(id: ID!): ID enable(id: ID!): ID reward(fromBadgeId: ID!, toUserId: ID!): ID - addSocialMedia(url: urlInput): [String]! + createSocialMedia(input: SocialMediaInput): SocialMedia unreward(fromBadgeId: ID!, toUserId: ID!): ID "Shout the given Type and ID" shout(id: ID!, type: ShoutTypeEnum): Boolean! @cypher(statement: """ @@ -121,7 +121,7 @@ type User { location: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l") locationName: String about: String - socialMedia: [String] + socialMedia: [SocialMedia]! @relation(name: "OWNED", direction: "OUT") createdAt: String updatedAt: String @@ -313,9 +313,14 @@ type SharedInboxEndpoint { type SocialMedia { id: ID! - uri: String + url: String + ownedBy: [User]! @relation(name: "OWNED", direction: "IN") } -input urlInput { +input SocialMediaInput { url: String! @constraint(format: "uri") -} \ No newline at end of file +} + +directive @constraint( + format: String +) on INPUT_FIELD_DEFINITION diff --git a/backend/src/seed/factories/users.js b/backend/src/seed/factories/users.js index 6b2ac9439..f9479fdbb 100644 --- a/backend/src/seed/factories/users.js +++ b/backend/src/seed/factories/users.js @@ -1,7 +1,7 @@ import faker from 'faker' import uuid from 'uuid/v4' -export default function create (params) { +export default function create(params) { const { id = uuid(), name = faker.name.findName(), @@ -27,8 +27,7 @@ export default function create (params) { about: "${about}", role: ${role}, disabled: ${disabled}, - deleted: ${deleted}, - socialMedia: [] + deleted: ${deleted} ) { id name @@ -38,7 +37,6 @@ export default function create (params) { role deleted disabled - socialMedia } } `