Merge pull request #1660 from Human-Connection/1583-remove-follow-type-enum

Remove follow type enum
This commit is contained in:
Robert Schäfer 2019-09-20 18:13:22 +02:00 committed by GitHub
commit a6ea4a2a3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 67 deletions

View File

@ -152,8 +152,8 @@ const permissions = shield(
// RemoveBadgeRewarded: isAdmin, // RemoveBadgeRewarded: isAdmin,
reward: isAdmin, reward: isAdmin,
unreward: isAdmin, unreward: isAdmin,
follow: isAuthenticated, followUser: isAuthenticated,
unfollow: isAuthenticated, unfollowUser: isAuthenticated,
shout: isAuthenticated, shout: isAuthenticated,
unshout: isAuthenticated, unshout: isAuthenticated,
changePassword: isAuthenticated, changePassword: isAuthenticated,

View File

@ -4,24 +4,24 @@ const neode = getNeode()
export default { export default {
Mutation: { Mutation: {
follow: async (_object, params, context, _resolveInfo) => { followUser: async (_object, params, context, _resolveInfo) => {
const { id: followedId, type } = params const { id: followedUserId } = params
const { user: currentUser } = context const { user: currentUser } = context
if (type === 'User' && currentUser.id === followedId) { if (currentUser.id === followedUserId) {
return null return null
} }
const [user, followedNode] = await Promise.all([ const [user, followedUser] = await Promise.all([
neode.find('User', currentUser.id), neode.find('User', currentUser.id),
neode.find(type, followedId), neode.find('User', followedUserId),
]) ])
await user.relateTo(followedNode, 'following') await user.relateTo(followedUser, 'following')
return followedNode.toJson() return followedUser.toJson()
}, },
unfollow: async (_object, params, context, _resolveInfo) => { unfollowUser: async (_object, params, context, _resolveInfo) => {
const { id: followedId, type } = params const { id: followedUserId } = params
const { user: currentUser } = context const { user: currentUser } = context
/* /*
@ -30,15 +30,14 @@ export default {
* However, pure cypher query looks cleaner IMO * However, pure cypher query looks cleaner IMO
*/ */
await neode.cypher( await neode.cypher(
`MATCH (user:User {id: $currentUser.id})-[relation:FOLLOWS]->(node {id: $followedId}) `MATCH (user:User {id: $currentUser.id})-[relation:FOLLOWS]->(followedUser:User {id: $followedUserId})
WHERE $type IN labels(node)
DELETE relation DELETE relation
RETURN COUNT(relation) > 0 as isFollowed`, RETURN COUNT(relation) > 0 as isFollowed`,
{ followedId, type, currentUser }, { followedUserId, currentUser },
) )
const followedNode = await neode.find(type, followedId) const followedUser = await neode.find('User', followedUserId)
return followedNode.toJson() return followedUser.toJson()
}, },
}, },
} }

View File

@ -1,11 +1,12 @@
import { createTestClient } from 'apollo-server-testing' import { createTestClient } from 'apollo-server-testing'
import Factory from '../../seed/factories' import Factory from '../../seed/factories'
import { getDriver } from '../../bootstrap/neo4j' import { getDriver, neode as getNeode } from '../../bootstrap/neo4j'
import createServer from '../../server' import createServer from '../../server'
import { gql } from '../../jest/helpers' import { gql } from '../../jest/helpers'
const factory = Factory() const factory = Factory()
const driver = getDriver() const driver = getDriver()
const neode = getNeode()
let query let query
let mutate let mutate
@ -16,8 +17,8 @@ let user2
let variables let variables
const mutationFollowUser = gql` const mutationFollowUser = gql`
mutation($id: ID!, $type: FollowTypeEnum) { mutation($id: ID!) {
follow(id: $id, type: $type) { followUser(id: $id) {
name name
followedBy { followedBy {
id id
@ -29,8 +30,8 @@ const mutationFollowUser = gql`
` `
const mutationUnfollowUser = gql` const mutationUnfollowUser = gql`
mutation($id: ID!, $type: FollowTypeEnum) { mutation($id: ID!) {
unfollow(id: $id, type: $type) { unfollowUser(id: $id) {
name name
followedBy { followedBy {
id id
@ -52,10 +53,12 @@ const userQuery = gql`
} }
` `
beforeAll(() => { beforeAll(async () => {
await factory.cleanDatabase()
const { server } = createServer({ const { server } = createServer({
context: () => ({ context: () => ({
driver, driver,
neode,
user: authenticatedUser, user: authenticatedUser,
cypherParams: { cypherParams: {
currentUserId: authenticatedUser ? authenticatedUser.id : null, currentUserId: authenticatedUser ? authenticatedUser.id : null,
@ -87,7 +90,7 @@ beforeEach(async () => {
.then(user => user.toJson()) .then(user => user.toJson())
authenticatedUser = user1 authenticatedUser = user1
variables = { id: user2.id, type: 'User' } variables = { id: user2.id }
}) })
afterEach(async () => { afterEach(async () => {
@ -99,71 +102,85 @@ describe('follow', () => {
describe('unauthenticated follow', () => { describe('unauthenticated follow', () => {
test('throws authorization error', async () => { test('throws authorization error', async () => {
authenticatedUser = null authenticatedUser = null
const { errors, data } = await mutate({ await expect(
mutation: mutationFollowUser, mutate({
variables, mutation: mutationFollowUser,
variables,
}),
).resolves.toMatchObject({
errors: [{ message: 'Not Authorised!' }],
data: { followUser: null },
}) })
expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
expect(data).toMatchObject({ follow: null })
}) })
}) })
test('I can follow another user', async () => { test('I can follow another user', async () => {
const { data: result } = await mutate({
mutation: mutationFollowUser,
variables,
})
const expectedUser = { const expectedUser = {
name: user2.name, name: user2.name,
followedBy: [{ id: user1.id, name: user1.name }], followedBy: [{ id: user1.id, name: user1.name }],
followedByCurrentUser: true, followedByCurrentUser: true,
} }
expect(result).toMatchObject({ follow: expectedUser }) await expect(
mutate({
mutation: mutationFollowUser,
variables,
}),
).resolves.toMatchObject({
data: { followUser: expectedUser },
errors: undefined,
})
}) })
test('I can`t follow myself', async () => { test('I can`t follow myself', async () => {
variables.id = user1.id variables.id = user1.id
const { data: result } = await mutate({ mutation: mutationFollowUser, variables }) await expect(mutate({ mutation: mutationFollowUser, variables })).resolves.toMatchObject({
const expectedResult = { follow: null } data: { followUser: null },
expect(result).toMatchObject(expectedResult) errors: undefined,
const { data } = await query({
query: userQuery,
variables: { id: user1.id },
}) })
const expectedUser = { const expectedUser = {
followedBy: [], followedBy: [],
followedByCurrentUser: false, followedByCurrentUser: false,
} }
expect(data).toMatchObject({ User: [expectedUser] }) await expect(
query({
query: userQuery,
variables: { id: user1.id },
}),
).resolves.toMatchObject({
data: {
User: [expectedUser],
},
errors: undefined,
})
}) })
}) })
describe('unfollow user', () => { describe('unfollow user', () => {
beforeEach(async () => { beforeEach(async () => {
variables = { variables = { id: user2.id }
id: user2.id,
type: 'User',
}
await mutate({ mutation: mutationFollowUser, variables }) await mutate({ mutation: mutationFollowUser, variables })
}) })
describe('unauthenticated follow', () => { describe('unauthenticated follow', () => {
test('throws authorization error', async () => { test('throws authorization error', async () => {
authenticatedUser = null authenticatedUser = null
const { errors, data } = await mutate({ mutation: mutationUnfollowUser, variables }) await expect(mutate({ mutation: mutationUnfollowUser, variables })).resolves.toMatchObject({
expect(errors[0]).toHaveProperty('message', 'Not Authorised!') data: { unfollowUser: null },
expect(data).toMatchObject({ unfollow: null }) errors: [{ message: 'Not Authorised!' }],
})
}) })
}) })
it('I can unfollow a user', async () => { test('I can unfollow a user', async () => {
const { data: result } = await mutate({ mutation: mutationUnfollowUser, variables })
const expectedUser = { const expectedUser = {
name: user2.name, name: user2.name,
followedBy: [], followedBy: [],
followedByCurrentUser: false, followedByCurrentUser: false,
} }
expect(result).toMatchObject({ unfollow: expectedUser }) await expect(mutate({ mutation: mutationUnfollowUser, variables })).resolves.toMatchObject({
data: { unfollowUser: expectedUser },
errors: undefined,
})
}) })
}) })
}) })

View File

@ -31,10 +31,8 @@ type Mutation {
shout(id: ID!, type: ShoutTypeEnum): Boolean! shout(id: ID!, type: ShoutTypeEnum): Boolean!
# Unshout the given Type and ID # Unshout the given Type and ID
unshout(id: ID!, type: ShoutTypeEnum): Boolean! unshout(id: ID!, type: ShoutTypeEnum): Boolean!
# Follow the given Type and ID followUser(id: ID!): User
follow(id: ID!, type: FollowTypeEnum): User unfollowUser(id: ID!): User
# Unfollow the given Type and ID
unfollow(id: ID!, type: FollowTypeEnum): User
} }
type Report { type Report {
@ -57,9 +55,6 @@ enum Deletable {
enum ShoutTypeEnum { enum ShoutTypeEnum {
Post Post
} }
enum FollowTypeEnum {
User
}
type Reward { type Reward {
id: ID! id: ID!

View File

@ -118,13 +118,12 @@ export default function Factory(options = {}) {
this.lastResponse = await this.graphQLClient.request(mutation) this.lastResponse = await this.graphQLClient.request(mutation)
return this return this
}, },
async follow(properties) { async followUser(properties) {
const { id, type } = properties const { id } = properties
const mutation = ` const mutation = `
mutation { mutation {
follow( followUser(
id: "${id}", id: "${id}"
type: ${type}
) )
} }
` `
@ -166,7 +165,7 @@ export default function Factory(options = {}) {
result.relate.bind(result) result.relate.bind(result)
result.mutate.bind(result) result.mutate.bind(result)
result.shout.bind(result) result.shout.bind(result)
result.follow.bind(result) result.followUser.bind(result)
result.invite.bind(result) result.invite.bind(result)
result.cleanDatabase.bind(result) result.cleanDatabase.bind(result)
return result return result

View File

@ -73,7 +73,7 @@ export default {
variables: { id: this.followId }, variables: { id: this.followId },
}) })
const followedUser = follow ? data.follow : data.unfollow const followedUser = follow ? data.followUser : data.unfollowUser
this.$emit('update', followedUser) this.$emit('update', followedUser)
} catch { } catch {
optimisticResult.followedByCurrentUser = !follow optimisticResult.followedByCurrentUser = !follow

View File

@ -106,7 +106,7 @@ export const followUserMutation = i18n => {
return gql` return gql`
${userFragment(lang)} ${userFragment(lang)}
mutation($id: ID!) { mutation($id: ID!) {
follow(id: $id, type: User) { followUser(id: $id) {
name name
followedByCount followedByCount
followedByCurrentUser followedByCurrentUser
@ -123,7 +123,7 @@ export const unfollowUserMutation = i18n => {
return gql` return gql`
${userFragment(lang)} ${userFragment(lang)}
mutation($id: ID!) { mutation($id: ID!) {
unfollow(id: $id, type: User) { unfollowUser(id: $id) {
name name
followedByCount followedByCount
followedByCurrentUser followedByCurrentUser