mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
refactor(backend): refactor context (#8434)
* type for neo4j and neode * fix build * remove flakyness * wait for neode to install schema * remove flakyness * explain why we wait for a non-promise * refactor context missing change missing change * adjust test setup proper cleanup after test * lint fixes * fix failing test to use new context
This commit is contained in:
parent
913cc2f06d
commit
c69cef47a1
3
backend/src/constants/subscriptions.ts
Normal file
3
backend/src/constants/subscriptions.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const NOTIFICATION_ADDED = 'NOTIFICATION_ADDED'
|
||||||
|
export const CHAT_MESSAGE_ADDED = 'CHAT_MESSAGE_ADDED'
|
||||||
|
export const ROOM_COUNT_UPDATED = 'ROOM_COUNT_UPDATED'
|
||||||
49
backend/src/context/database.ts
Normal file
49
backend/src/context/database.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { getDriver, getNeode } from '@db/neo4j'
|
||||||
|
|
||||||
|
import type { Driver } from 'neo4j-driver'
|
||||||
|
|
||||||
|
export const query =
|
||||||
|
(driver: Driver) =>
|
||||||
|
async ({ query, variables = {} }: { driver; query: string; variables: object }) => {
|
||||||
|
const session = driver.session()
|
||||||
|
|
||||||
|
const result = session.readTransaction(async (transaction) => {
|
||||||
|
const response = await transaction.run(query, variables)
|
||||||
|
return response
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await result
|
||||||
|
} finally {
|
||||||
|
await session.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mutate =
|
||||||
|
(driver: Driver) =>
|
||||||
|
async ({ query, variables = {} }: { driver; query: string; variables: object }) => {
|
||||||
|
const session = driver.session()
|
||||||
|
|
||||||
|
const result = session.writeTransaction(async (transaction) => {
|
||||||
|
const response = await transaction.run(query, variables)
|
||||||
|
return response
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await result
|
||||||
|
} finally {
|
||||||
|
await session.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const driver = getDriver()
|
||||||
|
const neode = getNeode()
|
||||||
|
|
||||||
|
return {
|
||||||
|
driver,
|
||||||
|
neode,
|
||||||
|
query: query(driver),
|
||||||
|
mutate: mutate(driver),
|
||||||
|
}
|
||||||
|
}
|
||||||
25
backend/src/context/pubsub.ts
Normal file
25
backend/src/context/pubsub.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
import { RedisPubSub } from 'graphql-redis-subscriptions'
|
||||||
|
import { PubSub } from 'graphql-subscriptions'
|
||||||
|
import Redis from 'ioredis'
|
||||||
|
|
||||||
|
import CONFIG from '@config/index'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
if (!CONFIG.REDIS_DOMAIN || CONFIG.REDIS_PORT || CONFIG.REDIS_PASSWORD) {
|
||||||
|
return new PubSub()
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
host: CONFIG.REDIS_DOMAIN,
|
||||||
|
port: CONFIG.REDIS_PORT,
|
||||||
|
password: CONFIG.REDIS_PASSWORD,
|
||||||
|
retryStrategy: (times) => {
|
||||||
|
return Math.min(times * 50, 2000)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return new RedisPubSub({
|
||||||
|
publisher: new Redis(options),
|
||||||
|
subscriber: new Redis(options),
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -2,40 +2,41 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
import databaseContext from '@context/database'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
import createServer, { getContext } from '@src/server'
|
||||||
import createServer from '@src/server'
|
|
||||||
|
|
||||||
const driver = getDriver()
|
const database = databaseContext()
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
let variables, mutate, authenticatedUser, commentAuthor, newlyCreatedComment
|
let variables, mutate, authenticatedUser, commentAuthor, newlyCreatedComment
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const { server } = createServer({
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/require-await
|
||||||
context: () => {
|
const contextUser = async (_req) => authenticatedUser
|
||||||
return {
|
const context = getContext({ user: contextUser, database })
|
||||||
driver,
|
|
||||||
user: authenticatedUser,
|
server = createServer({ context }).server
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
mutate = createTestClient(server).mutate
|
mutate = createTestClient(server).mutate
|
||||||
})
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
variables = {}
|
variables = {}
|
||||||
await neode.create('Category', {
|
await database.neode.create('Category', {
|
||||||
id: 'cat9',
|
id: 'cat9',
|
||||||
name: 'Democracy & Politics',
|
name: 'Democracy & Politics',
|
||||||
icon: 'university',
|
icon: 'university',
|
||||||
@ -103,7 +104,7 @@ describe('CreateComment', () => {
|
|||||||
|
|
||||||
describe('authenticated', () => {
|
describe('authenticated', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const user = await neode.create('User', { name: 'Author' })
|
const user = await database.neode.create('User', { name: 'Author' })
|
||||||
authenticatedUser = await user.toJson()
|
authenticatedUser = await user.toJson()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
import { getNeode } from '@db/neo4j'
|
import { getNeode } from '@db/neo4j'
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
|
|
||||||
import CONFIG from '@config/index'
|
import CONFIG from '@config/index'
|
||||||
|
import databaseContext from '@context/database'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
|
||||||
import { changeGroupMemberRoleMutation } from '@graphql/queries/changeGroupMemberRoleMutation'
|
import { changeGroupMemberRoleMutation } from '@graphql/queries/changeGroupMemberRoleMutation'
|
||||||
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
||||||
import { groupMembersQuery } from '@graphql/queries/groupMembersQuery'
|
import { groupMembersQuery } from '@graphql/queries/groupMembersQuery'
|
||||||
@ -16,10 +16,7 @@ import { joinGroupMutation } from '@graphql/queries/joinGroupMutation'
|
|||||||
import { leaveGroupMutation } from '@graphql/queries/leaveGroupMutation'
|
import { leaveGroupMutation } from '@graphql/queries/leaveGroupMutation'
|
||||||
import { removeUserFromGroupMutation } from '@graphql/queries/removeUserFromGroupMutation'
|
import { removeUserFromGroupMutation } from '@graphql/queries/removeUserFromGroupMutation'
|
||||||
import { updateGroupMutation } from '@graphql/queries/updateGroupMutation'
|
import { updateGroupMutation } from '@graphql/queries/updateGroupMutation'
|
||||||
import createServer from '@src/server'
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
let authenticatedUser
|
let authenticatedUser
|
||||||
let user
|
let user
|
||||||
@ -35,15 +32,12 @@ const descriptionAdditional100 =
|
|||||||
' 123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789'
|
' 123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789'
|
||||||
let variables = {}
|
let variables = {}
|
||||||
|
|
||||||
const { server } = createServer({
|
const database = databaseContext()
|
||||||
context: () => {
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
return {
|
const contextUser = async (_req) => authenticatedUser
|
||||||
driver,
|
const context = getContext({ user: contextUser, database })
|
||||||
neode,
|
|
||||||
user: authenticatedUser,
|
const { server } = createServer({ context })
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
const { mutate, query } = createTestClient(server)
|
const { mutate, query } = createTestClient(server)
|
||||||
|
|
||||||
const seedBasicsAndClearAuthentication = async () => {
|
const seedBasicsAndClearAuthentication = async () => {
|
||||||
@ -60,25 +54,25 @@ const seedBasicsAndClearAuthentication = async () => {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
neode.create('Category', {
|
database.neode.create('Category', {
|
||||||
id: 'cat4',
|
id: 'cat4',
|
||||||
name: 'Environment & Nature',
|
name: 'Environment & Nature',
|
||||||
slug: 'environment-nature',
|
slug: 'environment-nature',
|
||||||
icon: 'tree',
|
icon: 'tree',
|
||||||
}),
|
}),
|
||||||
neode.create('Category', {
|
database.neode.create('Category', {
|
||||||
id: 'cat9',
|
id: 'cat9',
|
||||||
name: 'Democracy & Politics',
|
name: 'Democracy & Politics',
|
||||||
slug: 'democracy-politics',
|
slug: 'democracy-politics',
|
||||||
icon: 'university',
|
icon: 'university',
|
||||||
}),
|
}),
|
||||||
neode.create('Category', {
|
database.neode.create('Category', {
|
||||||
id: 'cat15',
|
id: 'cat15',
|
||||||
name: 'Consumption & Sustainability',
|
name: 'Consumption & Sustainability',
|
||||||
slug: 'consumption-sustainability',
|
slug: 'consumption-sustainability',
|
||||||
icon: 'shopping-cart',
|
icon: 'shopping-cart',
|
||||||
}),
|
}),
|
||||||
neode.create('Category', {
|
database.neode.create('Category', {
|
||||||
id: 'cat27',
|
id: 'cat27',
|
||||||
name: 'Animal Protection',
|
name: 'Animal Protection',
|
||||||
slug: 'animal-protection',
|
slug: 'animal-protection',
|
||||||
@ -241,7 +235,9 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('in mode', () => {
|
describe('in mode', () => {
|
||||||
|
|||||||
@ -3,49 +3,47 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
|
|
||||||
|
import databaseContext from '@context/database'
|
||||||
|
import pubsubContext from '@context/pubsub'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
|
||||||
import { createMessageMutation } from '@graphql/queries/createMessageMutation'
|
import { createMessageMutation } from '@graphql/queries/createMessageMutation'
|
||||||
import { createRoomMutation } from '@graphql/queries/createRoomMutation'
|
import { createRoomMutation } from '@graphql/queries/createRoomMutation'
|
||||||
import { markMessagesAsSeen } from '@graphql/queries/markMessagesAsSeen'
|
import { markMessagesAsSeen } from '@graphql/queries/markMessagesAsSeen'
|
||||||
import { messageQuery } from '@graphql/queries/messageQuery'
|
import { messageQuery } from '@graphql/queries/messageQuery'
|
||||||
import { roomQuery } from '@graphql/queries/roomQuery'
|
import { roomQuery } from '@graphql/queries/roomQuery'
|
||||||
import createServer, { pubsub } from '@src/server'
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
let query
|
let query
|
||||||
let mutate
|
let mutate
|
||||||
let authenticatedUser
|
let authenticatedUser
|
||||||
let chattingUser, otherChattingUser, notChattingUser
|
let chattingUser, otherChattingUser, notChattingUser
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
const pubsub = pubsubContext()
|
||||||
const pubsubSpy = jest.spyOn(pubsub, 'publish')
|
const pubsubSpy = jest.spyOn(pubsub, 'publish')
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const { server } = createServer({
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/require-await
|
||||||
context: () => {
|
const contextUser = async (_req) => authenticatedUser
|
||||||
return {
|
const context = getContext({ user: contextUser, database, pubsub })
|
||||||
driver,
|
|
||||||
neode,
|
server = createServer({ context }).server
|
||||||
user: authenticatedUser,
|
|
||||||
cypherParams: {
|
|
||||||
currentUserId: authenticatedUser ? authenticatedUser.id : null,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
query = createTestClient(server).query
|
query = createTestClient(server).query
|
||||||
mutate = createTestClient(server).mutate
|
mutate = createTestClient(server).mutate
|
||||||
})
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Message', () => {
|
describe('Message', () => {
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
import { withFilter } from 'graphql-subscriptions'
|
import { withFilter } from 'graphql-subscriptions'
|
||||||
import { neo4jgraphql } from 'neo4j-graphql-js'
|
import { neo4jgraphql } from 'neo4j-graphql-js'
|
||||||
|
|
||||||
import { pubsub, CHAT_MESSAGE_ADDED } from '@src/server'
|
import { CHAT_MESSAGE_ADDED } from '@constants/subscriptions'
|
||||||
|
|
||||||
import Resolver from './helpers/Resolver'
|
import Resolver from './helpers/Resolver'
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ export default {
|
|||||||
Subscription: {
|
Subscription: {
|
||||||
chatMessageAdded: {
|
chatMessageAdded: {
|
||||||
subscribe: withFilter(
|
subscribe: withFilter(
|
||||||
() => pubsub.asyncIterator(CHAT_MESSAGE_ADDED),
|
(_, __, context) => context.pubsub.asyncIterator(CHAT_MESSAGE_ADDED),
|
||||||
(payload, variables, context) => {
|
(payload, variables, context) => {
|
||||||
return payload.userId === context.user?.id
|
return payload.userId === context.user?.id
|
||||||
},
|
},
|
||||||
|
|||||||
@ -6,13 +6,13 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
import { withFilter } from 'graphql-subscriptions'
|
import { withFilter } from 'graphql-subscriptions'
|
||||||
|
|
||||||
import { pubsub, NOTIFICATION_ADDED } from '@src/server'
|
import { NOTIFICATION_ADDED } from '@constants/subscriptions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Subscription: {
|
Subscription: {
|
||||||
notificationAdded: {
|
notificationAdded: {
|
||||||
subscribe: withFilter(
|
subscribe: withFilter(
|
||||||
() => pubsub.asyncIterator(NOTIFICATION_ADDED),
|
(_, __, context) => context.pubsub.asyncIterator(NOTIFICATION_ADDED),
|
||||||
(payload, variables, context) => {
|
(payload, variables, context) => {
|
||||||
return payload.notificationAdded.to.id === context.user?.id
|
return payload.notificationAdded.to.id === context.user?.id
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,20 +1,18 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
import CONFIG from '@config/index'
|
import CONFIG from '@config/index'
|
||||||
|
import databaseContext from '@context/database'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
|
||||||
import { createPostMutation } from '@graphql/queries/createPostMutation'
|
import { createPostMutation } from '@graphql/queries/createPostMutation'
|
||||||
import createServer from '@src/server'
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
CONFIG.CATEGORIES_ACTIVE = false
|
CONFIG.CATEGORIES_ACTIVE = false
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
let query
|
let query
|
||||||
let mutate
|
let mutate
|
||||||
let authenticatedUser
|
let authenticatedUser
|
||||||
@ -40,28 +38,27 @@ const postQuery = gql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const { server } = createServer({
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/require-await
|
||||||
context: () => {
|
const contextUser = async (_req) => authenticatedUser
|
||||||
return {
|
const context = getContext({ user: contextUser, database })
|
||||||
driver,
|
|
||||||
neode,
|
server = createServer({ context }).server
|
||||||
user: authenticatedUser,
|
|
||||||
cypherParams: {
|
|
||||||
currentUserId: authenticatedUser ? authenticatedUser.id : null,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
query = createTestClient(server).query
|
query = createTestClient(server).query
|
||||||
mutate = createTestClient(server).mutate
|
mutate = createTestClient(server).mutate
|
||||||
})
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('observing posts', () => {
|
describe('observing posts', () => {
|
||||||
|
|||||||
@ -2,11 +2,12 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
|
|
||||||
import CONFIG from '@config/index'
|
import CONFIG from '@config/index'
|
||||||
|
import databaseContext from '@context/database'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
|
||||||
import { changeGroupMemberRoleMutation } from '@graphql/queries/changeGroupMemberRoleMutation'
|
import { changeGroupMemberRoleMutation } from '@graphql/queries/changeGroupMemberRoleMutation'
|
||||||
import { createCommentMutation } from '@graphql/queries/createCommentMutation'
|
import { createCommentMutation } from '@graphql/queries/createCommentMutation'
|
||||||
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
||||||
@ -17,7 +18,7 @@ import { postQuery } from '@graphql/queries/postQuery'
|
|||||||
import { profilePagePosts } from '@graphql/queries/profilePagePosts'
|
import { profilePagePosts } from '@graphql/queries/profilePagePosts'
|
||||||
import { searchPosts } from '@graphql/queries/searchPosts'
|
import { searchPosts } from '@graphql/queries/searchPosts'
|
||||||
import { signupVerificationMutation } from '@graphql/queries/signupVerificationMutation'
|
import { signupVerificationMutation } from '@graphql/queries/signupVerificationMutation'
|
||||||
import createServer from '@src/server'
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
CONFIG.CATEGORIES_ACTIVE = false
|
CONFIG.CATEGORIES_ACTIVE = false
|
||||||
|
|
||||||
@ -28,9 +29,6 @@ jest.mock('@constants/groups', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
let query
|
let query
|
||||||
let mutate
|
let mutate
|
||||||
let anyUser
|
let anyUser
|
||||||
@ -42,28 +40,26 @@ let hiddenUser
|
|||||||
let authenticatedUser
|
let authenticatedUser
|
||||||
let newUser
|
let newUser
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const { server } = createServer({
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
context: () => {
|
const contextUser = async (_req) => authenticatedUser
|
||||||
return {
|
const context = getContext({ user: contextUser, database })
|
||||||
driver,
|
|
||||||
neode,
|
server = createServer({ context }).server
|
||||||
user: authenticatedUser,
|
|
||||||
cypherParams: {
|
|
||||||
currentUserId: authenticatedUser ? authenticatedUser.id : null,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
query = createTestClient(server).query
|
query = createTestClient(server).query
|
||||||
mutate = createTestClient(server).mutate
|
mutate = createTestClient(server).mutate
|
||||||
})
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Posts in Groups', () => {
|
describe('Posts in Groups', () => {
|
||||||
|
|||||||
@ -7,8 +7,7 @@
|
|||||||
import { withFilter } from 'graphql-subscriptions'
|
import { withFilter } from 'graphql-subscriptions'
|
||||||
import { neo4jgraphql } from 'neo4j-graphql-js'
|
import { neo4jgraphql } from 'neo4j-graphql-js'
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-cycle
|
import { ROOM_COUNT_UPDATED } from '@constants/subscriptions'
|
||||||
import { pubsub, ROOM_COUNT_UPDATED } from '@src/server'
|
|
||||||
|
|
||||||
import Resolver from './helpers/Resolver'
|
import Resolver from './helpers/Resolver'
|
||||||
|
|
||||||
@ -30,7 +29,7 @@ export default {
|
|||||||
Subscription: {
|
Subscription: {
|
||||||
roomCountUpdated: {
|
roomCountUpdated: {
|
||||||
subscribe: withFilter(
|
subscribe: withFilter(
|
||||||
() => pubsub.asyncIterator(ROOM_COUNT_UPDATED),
|
(_, __, context) => context.pubsub.asyncIterator(ROOM_COUNT_UPDATED),
|
||||||
(payload, variables, context) => {
|
(payload, variables, context) => {
|
||||||
return payload.userId === context.user?.id
|
return payload.userId === context.user?.id
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
import { getNeode } from '@db/neo4j'
|
import { getNeode } from '@db/neo4j'
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
|||||||
@ -3,14 +3,16 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
import { categories } from '@constants/categories'
|
import { categories } from '@constants/categories'
|
||||||
|
import databaseContext from '@context/database'
|
||||||
|
import pubsubContext from '@context/pubsub'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import User from '@db/models/User'
|
import User from '@db/models/User'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
import createServer, { getContext } from '@src/server'
|
||||||
import createServer from '@src/server'
|
|
||||||
|
|
||||||
const categoryIds = ['cat9']
|
const categoryIds = ['cat9']
|
||||||
let user
|
let user
|
||||||
@ -21,8 +23,7 @@ let query
|
|||||||
let mutate
|
let mutate
|
||||||
let variables
|
let variables
|
||||||
|
|
||||||
const driver = getDriver()
|
const pubsub = pubsubContext()
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
const deleteUserMutation = gql`
|
const deleteUserMutation = gql`
|
||||||
mutation ($id: ID!, $resource: [Deletable]) {
|
mutation ($id: ID!, $resource: [Deletable]) {
|
||||||
@ -108,25 +109,28 @@ const resetTrophyBadgesSelected = gql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const { server } = createServer({
|
const contextUser = async (_req) => authenticatedUser
|
||||||
context: () => {
|
const context = getContext({ user: contextUser, database, pubsub })
|
||||||
return {
|
|
||||||
driver,
|
server = createServer({ context }).server
|
||||||
neode,
|
|
||||||
user: authenticatedUser,
|
const createTestClientResult = createTestClient(server)
|
||||||
}
|
query = createTestClientResult.query
|
||||||
},
|
mutate = createTestClientResult.mutate
|
||||||
})
|
|
||||||
query = createTestClient(server).query
|
|
||||||
mutate = createTestClient(server).mutate
|
|
||||||
})
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 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
|
// 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
|
||||||
@ -540,10 +544,10 @@ describe('Delete a User as admin', () => {
|
|||||||
|
|
||||||
describe('connected `EmailAddress` nodes', () => {
|
describe('connected `EmailAddress` nodes', () => {
|
||||||
it('will be removed completely', async () => {
|
it('will be removed completely', async () => {
|
||||||
await expect(neode.all('EmailAddress')).resolves.toHaveLength(2)
|
await expect(database.neode.all('EmailAddress')).resolves.toHaveLength(2)
|
||||||
await mutate({ mutation: deleteUserMutation, variables })
|
await mutate({ mutation: deleteUserMutation, variables })
|
||||||
|
|
||||||
await expect(neode.all('EmailAddress')).resolves.toHaveLength(1)
|
await expect(database.neode.all('EmailAddress')).resolves.toHaveLength(1)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -554,9 +558,9 @@ describe('Delete a User as admin', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('will be removed completely', async () => {
|
it('will be removed completely', async () => {
|
||||||
await expect(neode.all('SocialMedia')).resolves.toHaveLength(1)
|
await expect(database.neode.all('SocialMedia')).resolves.toHaveLength(1)
|
||||||
await mutate({ mutation: deleteUserMutation, variables })
|
await mutate({ mutation: deleteUserMutation, variables })
|
||||||
await expect(neode.all('SocialMedia')).resolves.toHaveLength(0)
|
await expect(database.neode.all('SocialMedia')).resolves.toHaveLength(0)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -1041,8 +1045,8 @@ describe('updateOnlineStatus', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const cypher = 'MATCH (u:User {id: $id}) RETURN u'
|
const cypher = 'MATCH (u:User {id: $id}) RETURN u'
|
||||||
const result = await neode.cypher(cypher, { id: authenticatedUser.id })
|
const result = await database.neode.cypher(cypher, { id: authenticatedUser.id })
|
||||||
const dbUser = neode.hydrateFirst(result, 'u', neode.model('User'))
|
const dbUser = database.neode.hydrateFirst(result, 'u', database.neode.model('User'))
|
||||||
await expect(dbUser.toJson()).resolves.toMatchObject({
|
await expect(dbUser.toJson()).resolves.toMatchObject({
|
||||||
lastOnlineStatus: 'online',
|
lastOnlineStatus: 'online',
|
||||||
})
|
})
|
||||||
@ -1067,8 +1071,8 @@ describe('updateOnlineStatus', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const cypher = 'MATCH (u:User {id: $id}) RETURN u'
|
const cypher = 'MATCH (u:User {id: $id}) RETURN u'
|
||||||
const result = await neode.cypher(cypher, { id: authenticatedUser.id })
|
const result = await database.neode.cypher(cypher, { id: authenticatedUser.id })
|
||||||
const dbUser = neode.hydrateFirst(result, 'u', neode.model('User'))
|
const dbUser = database.neode.hydrateFirst(result, 'u', database.neode.model('User'))
|
||||||
await expect(dbUser.toJson()).resolves.toMatchObject({
|
await expect(dbUser.toJson()).resolves.toMatchObject({
|
||||||
lastOnlineStatus: 'away',
|
lastOnlineStatus: 'away',
|
||||||
awaySince: expect.any(String),
|
awaySince: expect.any(String),
|
||||||
@ -1083,8 +1087,12 @@ describe('updateOnlineStatus', () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const cypher = 'MATCH (u:User {id: $id}) RETURN u'
|
const cypher = 'MATCH (u:User {id: $id}) RETURN u'
|
||||||
const result = await neode.cypher(cypher, { id: authenticatedUser.id })
|
const result = await database.neode.cypher(cypher, { id: authenticatedUser.id })
|
||||||
const dbUser = neode.hydrateFirst<typeof User>(result, 'u', neode.model('User'))
|
const dbUser = database.neode.hydrateFirst<typeof User>(
|
||||||
|
result,
|
||||||
|
'u',
|
||||||
|
database.neode.model('User'),
|
||||||
|
)
|
||||||
await expect(dbUser.toJson()).resolves.toMatchObject({
|
await expect(dbUser.toJson()).resolves.toMatchObject({
|
||||||
lastOnlineStatus: 'away',
|
lastOnlineStatus: 'away',
|
||||||
awaySince: expect.any(String),
|
awaySince: expect.any(String),
|
||||||
@ -1098,8 +1106,8 @@ describe('updateOnlineStatus', () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
const result2 = await neode.cypher(cypher, { id: authenticatedUser.id })
|
const result2 = await database.neode.cypher(cypher, { id: authenticatedUser.id })
|
||||||
const dbUser2 = neode.hydrateFirst(result2, 'u', neode.model('User'))
|
const dbUser2 = database.neode.hydrateFirst(result2, 'u', database.neode.model('User'))
|
||||||
await expect(dbUser2.toJson()).resolves.toMatchObject({
|
await expect(dbUser2.toJson()).resolves.toMatchObject({
|
||||||
lastOnlineStatus: 'away',
|
lastOnlineStatus: 'away',
|
||||||
awaySince,
|
awaySince,
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
import nodemailer from 'nodemailer'
|
import { createTransport } from 'nodemailer'
|
||||||
import { htmlToText } from 'nodemailer-html-to-text'
|
import { htmlToText } from 'nodemailer-html-to-text'
|
||||||
|
|
||||||
import CONFIG from '@config/index'
|
import CONFIG from '@config/index'
|
||||||
@ -15,7 +15,7 @@ const hasAuthData = CONFIG.SMTP_USERNAME && CONFIG.SMTP_PASSWORD
|
|||||||
const hasDKIMData =
|
const hasDKIMData =
|
||||||
CONFIG.SMTP_DKIM_DOMAINNAME && CONFIG.SMTP_DKIM_KEYSELECTOR && CONFIG.SMTP_DKIM_PRIVATKEY
|
CONFIG.SMTP_DKIM_DOMAINNAME && CONFIG.SMTP_DKIM_KEYSELECTOR && CONFIG.SMTP_DKIM_PRIVATKEY
|
||||||
|
|
||||||
const transporter = nodemailer.createTransport({
|
const transporter = createTransport({
|
||||||
host: CONFIG.SMTP_HOST,
|
host: CONFIG.SMTP_HOST,
|
||||||
port: CONFIG.SMTP_PORT,
|
port: CONFIG.SMTP_PORT,
|
||||||
ignoreTLS: CONFIG.SMTP_IGNORE_TLS,
|
ignoreTLS: CONFIG.SMTP_IGNORE_TLS,
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import hashtags from './hashtags/hashtagsMiddleware'
|
|||||||
import includedFields from './includedFieldsMiddleware'
|
import includedFields from './includedFieldsMiddleware'
|
||||||
import languages from './languages/languages'
|
import languages from './languages/languages'
|
||||||
import login from './login/loginMiddleware'
|
import login from './login/loginMiddleware'
|
||||||
// eslint-disable-next-line import/no-cycle
|
|
||||||
import notifications from './notifications/notificationsMiddleware'
|
import notifications from './notifications/notificationsMiddleware'
|
||||||
import orderBy from './orderByMiddleware'
|
import orderBy from './orderByMiddleware'
|
||||||
import permissions from './permissionsMiddleware'
|
import permissions from './permissionsMiddleware'
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
import databaseContext from '@context/database'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
|
||||||
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
||||||
import { joinGroupMutation } from '@graphql/queries/joinGroupMutation'
|
import { joinGroupMutation } from '@graphql/queries/joinGroupMutation'
|
||||||
import CONFIG from '@src/config'
|
import CONFIG from '@src/config'
|
||||||
import createServer from '@src/server'
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
CONFIG.CATEGORIES_ACTIVE = false
|
CONFIG.CATEGORIES_ACTIVE = false
|
||||||
|
|
||||||
@ -21,13 +21,10 @@ jest.mock('@middleware/helpers/email/sendMail', () => ({
|
|||||||
sendMail: (notification) => sendMailMock(notification),
|
sendMail: (notification) => sendMailMock(notification),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
let server, query, mutate, authenticatedUser, emaillessMember
|
let query, mutate, authenticatedUser, emaillessMember
|
||||||
|
|
||||||
let postAuthor, groupMember
|
let postAuthor, groupMember
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
const mentionString = `
|
const mentionString = `
|
||||||
<a class="mention" data-mention-id="group-member" href="/profile/group-member/group-member">@group-member</a>
|
<a class="mention" data-mention-id="group-member" href="/profile/group-member/group-member">@group-member</a>
|
||||||
<a class="mention" data-mention-id="email-less-member" href="/profile/email-less-member/email-less-member">@email-less-member</a>`
|
<a class="mention" data-mention-id="email-less-member" href="/profile/email-less-member/email-less-member">@email-less-member</a>`
|
||||||
@ -97,22 +94,18 @@ const markAllAsRead = async () =>
|
|||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const createServerResult = createServer({
|
const contextUser = async (_req) => authenticatedUser
|
||||||
context: () => {
|
const context = getContext({ user: contextUser, database })
|
||||||
return {
|
|
||||||
user: authenticatedUser,
|
server = createServer({ context }).server
|
||||||
neode,
|
|
||||||
driver,
|
|
||||||
cypherParams: {
|
|
||||||
currentUserId: authenticatedUser ? authenticatedUser.id : null,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
server = createServerResult.server
|
|
||||||
const createTestClientResult = createTestClient(server)
|
const createTestClientResult = createTestClient(server)
|
||||||
query = createTestClientResult.query
|
query = createTestClientResult.query
|
||||||
mutate = createTestClientResult.mutate
|
mutate = createTestClientResult.mutate
|
||||||
@ -120,7 +113,9 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('emails sent for notifications', () => {
|
describe('emails sent for notifications', () => {
|
||||||
@ -149,7 +144,7 @@ describe('emails sent for notifications', () => {
|
|||||||
password: '1234',
|
password: '1234',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
emaillessMember = await neode.create('User', {
|
emaillessMember = await database.neode.create('User', {
|
||||||
id: 'email-less-member',
|
id: 'email-less-member',
|
||||||
name: 'Email-less Member',
|
name: 'Email-less Member',
|
||||||
slug: 'email-less-member',
|
slug: 'email-less-member',
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
import databaseContext from '@context/database'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
|
||||||
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
||||||
import CONFIG from '@src/config'
|
import CONFIG from '@src/config'
|
||||||
import createServer from '@src/server'
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
CONFIG.CATEGORIES_ACTIVE = false
|
CONFIG.CATEGORIES_ACTIVE = false
|
||||||
|
|
||||||
@ -19,13 +19,10 @@ jest.mock('@middleware/helpers/email/sendMail', () => ({
|
|||||||
sendMail: (notification) => sendMailMock(notification),
|
sendMail: (notification) => sendMailMock(notification),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
let server, query, mutate, authenticatedUser
|
let query, mutate, authenticatedUser
|
||||||
|
|
||||||
let postAuthor, firstFollower, secondFollower, thirdFollower, emaillessFollower
|
let postAuthor, firstFollower, secondFollower, thirdFollower, emaillessFollower
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
const createPostMutation = gql`
|
const createPostMutation = gql`
|
||||||
mutation ($id: ID, $title: String!, $content: String!, $groupId: ID) {
|
mutation ($id: ID, $title: String!, $content: String!, $groupId: ID) {
|
||||||
CreatePost(id: $id, title: $title, content: $content, groupId: $groupId) {
|
CreatePost(id: $id, title: $title, content: $content, groupId: $groupId) {
|
||||||
@ -71,22 +68,19 @@ const followUserMutation = gql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const createServerResult = createServer({
|
// eslint-disable-next-line @typescript-eslint/require-await
|
||||||
context: () => {
|
const contextUser = async (_req) => authenticatedUser
|
||||||
return {
|
const context = getContext({ user: contextUser, database })
|
||||||
user: authenticatedUser,
|
|
||||||
neode,
|
server = createServer({ context }).server
|
||||||
driver,
|
|
||||||
cypherParams: {
|
|
||||||
currentUserId: authenticatedUser ? authenticatedUser.id : null,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
server = createServerResult.server
|
|
||||||
const createTestClientResult = createTestClient(server)
|
const createTestClientResult = createTestClient(server)
|
||||||
query = createTestClientResult.query
|
query = createTestClientResult.query
|
||||||
mutate = createTestClientResult.mutate
|
mutate = createTestClientResult.mutate
|
||||||
@ -94,7 +88,9 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('following users notifications', () => {
|
describe('following users notifications', () => {
|
||||||
@ -147,7 +143,7 @@ describe('following users notifications', () => {
|
|||||||
password: '1234',
|
password: '1234',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
emaillessFollower = await neode.create('User', {
|
emaillessFollower = await database.neode.create('User', {
|
||||||
id: 'email-less-follower',
|
id: 'email-less-follower',
|
||||||
name: 'Email-less Follower',
|
name: 'Email-less Follower',
|
||||||
slug: 'email-less-follower',
|
slug: 'email-less-follower',
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
import databaseContext from '@context/database'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
|
||||||
import { changeGroupMemberRoleMutation } from '@graphql/queries/changeGroupMemberRoleMutation'
|
import { changeGroupMemberRoleMutation } from '@graphql/queries/changeGroupMemberRoleMutation'
|
||||||
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
||||||
import { joinGroupMutation } from '@graphql/queries/joinGroupMutation'
|
import { joinGroupMutation } from '@graphql/queries/joinGroupMutation'
|
||||||
import CONFIG from '@src/config'
|
import CONFIG from '@src/config'
|
||||||
import createServer from '@src/server'
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
CONFIG.CATEGORIES_ACTIVE = false
|
CONFIG.CATEGORIES_ACTIVE = false
|
||||||
|
|
||||||
@ -22,13 +22,10 @@ jest.mock('@middleware/helpers/email/sendMail', () => ({
|
|||||||
sendMail: (notification) => sendMailMock(notification),
|
sendMail: (notification) => sendMailMock(notification),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
let server, query, mutate, authenticatedUser
|
let query, mutate, authenticatedUser
|
||||||
|
|
||||||
let postAuthor, groupMember, pendingMember, noMember, emaillessMember
|
let postAuthor, groupMember, pendingMember, noMember, emaillessMember
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
const mentionString = `
|
const mentionString = `
|
||||||
<a class="mention" data-mention-id="no-member" href="/profile/no-member/no-member">@no-member</a>
|
<a class="mention" data-mention-id="no-member" href="/profile/no-member/no-member">@no-member</a>
|
||||||
<a class="mention" data-mention-id="pending-member" href="/profile/pending-member/pending-member">@pending-member</a>
|
<a class="mention" data-mention-id="pending-member" href="/profile/pending-member/pending-member">@pending-member</a>
|
||||||
@ -93,22 +90,18 @@ const markAllAsRead = async () =>
|
|||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const createServerResult = createServer({
|
const contextUser = async (_req) => authenticatedUser
|
||||||
context: () => {
|
const context = getContext({ user: contextUser, database })
|
||||||
return {
|
|
||||||
user: authenticatedUser,
|
server = createServer({ context }).server
|
||||||
neode,
|
|
||||||
driver,
|
|
||||||
cypherParams: {
|
|
||||||
currentUserId: authenticatedUser ? authenticatedUser.id : null,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
server = createServerResult.server
|
|
||||||
const createTestClientResult = createTestClient(server)
|
const createTestClientResult = createTestClient(server)
|
||||||
query = createTestClientResult.query
|
query = createTestClientResult.query
|
||||||
mutate = createTestClientResult.mutate
|
mutate = createTestClientResult.mutate
|
||||||
@ -116,7 +109,9 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('mentions in groups', () => {
|
describe('mentions in groups', () => {
|
||||||
@ -169,7 +164,7 @@ describe('mentions in groups', () => {
|
|||||||
password: '1234',
|
password: '1234',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
emaillessMember = await neode.create('User', {
|
emaillessMember = await database.neode.create('User', {
|
||||||
id: 'email-less-member',
|
id: 'email-less-member',
|
||||||
name: 'Email-less Member',
|
name: 'Email-less Member',
|
||||||
slug: 'email-less-member',
|
slug: 'email-less-member',
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
import CONFIG from '@config/index'
|
import CONFIG from '@config/index'
|
||||||
|
import databaseContext from '@context/database'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
import createServer, { getContext } from '@src/server'
|
||||||
import createServer from '@src/server'
|
|
||||||
|
|
||||||
CONFIG.CATEGORIES_ACTIVE = false
|
CONFIG.CATEGORIES_ACTIVE = false
|
||||||
|
|
||||||
@ -17,13 +19,10 @@ jest.mock('@middleware/helpers/email/sendMail', () => ({
|
|||||||
sendMail: (notification) => sendMailMock(notification),
|
sendMail: (notification) => sendMailMock(notification),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
let server, query, mutate, authenticatedUser
|
let query, mutate, authenticatedUser
|
||||||
|
|
||||||
let postAuthor, firstCommenter, secondCommenter, emaillessObserver
|
let postAuthor, firstCommenter, secondCommenter, emaillessObserver
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
const createPostMutation = gql`
|
const createPostMutation = gql`
|
||||||
mutation ($id: ID, $title: String!, $content: String!) {
|
mutation ($id: ID, $title: String!, $content: String!) {
|
||||||
CreatePost(id: $id, title: $title, content: $content) {
|
CreatePost(id: $id, title: $title, content: $content) {
|
||||||
@ -78,23 +77,18 @@ const toggleObservePostMutation = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
const database = databaseContext()
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const createServerResult = createServer({
|
const contextUser = async (_req) => authenticatedUser
|
||||||
context: () => {
|
const context = getContext({ user: contextUser, database })
|
||||||
return {
|
|
||||||
user: authenticatedUser,
|
server = createServer({ context }).server
|
||||||
neode,
|
|
||||||
driver,
|
|
||||||
cypherParams: {
|
|
||||||
currentUserId: authenticatedUser ? authenticatedUser.id : null,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
server = createServerResult.server
|
|
||||||
const createTestClientResult = createTestClient(server)
|
const createTestClientResult = createTestClient(server)
|
||||||
query = createTestClientResult.query
|
query = createTestClientResult.query
|
||||||
mutate = createTestClientResult.mutate
|
mutate = createTestClientResult.mutate
|
||||||
@ -102,7 +96,9 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('notifications for users that observe a post', () => {
|
describe('notifications for users that observe a post', () => {
|
||||||
@ -143,7 +139,7 @@ describe('notifications for users that observe a post', () => {
|
|||||||
password: '1234',
|
password: '1234',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
emaillessObserver = await neode.create('User', {
|
emaillessObserver = await database.neode.create('User', {
|
||||||
id: 'email-less-observer',
|
id: 'email-less-observer',
|
||||||
name: 'Email-less Observer',
|
name: 'Email-less Observer',
|
||||||
slug: 'email-less-observer',
|
slug: 'email-less-observer',
|
||||||
|
|||||||
@ -1,15 +1,14 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
import databaseContext from '@context/database'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
|
||||||
import CONFIG from '@src/config'
|
import CONFIG from '@src/config'
|
||||||
import createServer from '@src/server'
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
CONFIG.CATEGORIES_ACTIVE = false
|
CONFIG.CATEGORIES_ACTIVE = false
|
||||||
|
|
||||||
@ -23,13 +22,10 @@ jest.mock('../helpers/isUserOnline', () => ({
|
|||||||
isUserOnline: () => isUserOnlineMock(),
|
isUserOnline: () => isUserOnlineMock(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
let server, mutate, authenticatedUser
|
let mutate, authenticatedUser
|
||||||
|
|
||||||
let postAuthor
|
let postAuthor
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
const createPostMutation = gql`
|
const createPostMutation = gql`
|
||||||
mutation ($id: ID, $title: String!, $content: String!, $groupId: ID) {
|
mutation ($id: ID, $title: String!, $content: String!, $groupId: ID) {
|
||||||
CreatePost(id: $id, title: $title, content: $content, groupId: $groupId) {
|
CreatePost(id: $id, title: $title, content: $content, groupId: $groupId) {
|
||||||
@ -40,29 +36,24 @@ const createPostMutation = gql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const createServerResult = createServer({
|
// eslint-disable-next-line @typescript-eslint/require-await
|
||||||
context: () => {
|
const contextUser = async (_req) => authenticatedUser
|
||||||
return {
|
const context = getContext({ user: contextUser, database })
|
||||||
user: authenticatedUser,
|
|
||||||
neode,
|
const { server } = createServer({ context })
|
||||||
driver,
|
|
||||||
cypherParams: {
|
|
||||||
currentUserId: authenticatedUser ? authenticatedUser.id : null,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
server = createServerResult.server
|
|
||||||
const createTestClientResult = createTestClient(server)
|
const createTestClientResult = createTestClient(server)
|
||||||
mutate = createTestClientResult.mutate
|
mutate = createTestClientResult.mutate
|
||||||
})
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
await database.driver.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
import databaseContext from '@context/database'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
|
||||||
import { changeGroupMemberRoleMutation } from '@graphql/queries/changeGroupMemberRoleMutation'
|
import { changeGroupMemberRoleMutation } from '@graphql/queries/changeGroupMemberRoleMutation'
|
||||||
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
||||||
import { joinGroupMutation } from '@graphql/queries/joinGroupMutation'
|
import { joinGroupMutation } from '@graphql/queries/joinGroupMutation'
|
||||||
import CONFIG from '@src/config'
|
import CONFIG from '@src/config'
|
||||||
import createServer from '@src/server'
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
CONFIG.CATEGORIES_ACTIVE = false
|
CONFIG.CATEGORIES_ACTIVE = false
|
||||||
|
|
||||||
@ -22,13 +22,10 @@ jest.mock('@middleware/helpers/email/sendMail', () => ({
|
|||||||
sendMail: (notification) => sendMailMock(notification),
|
sendMail: (notification) => sendMailMock(notification),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
let server, query, mutate, authenticatedUser
|
let query, mutate, authenticatedUser
|
||||||
|
|
||||||
let postAuthor, groupMember, pendingMember, emaillessMember
|
let postAuthor, groupMember, pendingMember, emaillessMember
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
const createPostMutation = gql`
|
const createPostMutation = gql`
|
||||||
mutation ($id: ID, $title: String!, $content: String!, $groupId: ID) {
|
mutation ($id: ID, $title: String!, $content: String!, $groupId: ID) {
|
||||||
CreatePost(id: $id, title: $title, content: $content, groupId: $groupId) {
|
CreatePost(id: $id, title: $title, content: $content, groupId: $groupId) {
|
||||||
@ -95,22 +92,17 @@ const markAllAsRead = async () =>
|
|||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const createServerResult = createServer({
|
const contextUser = async (_req) => authenticatedUser
|
||||||
context: () => {
|
const context = getContext({ user: contextUser, database })
|
||||||
return {
|
|
||||||
user: authenticatedUser,
|
server = createServer({ context }).server
|
||||||
neode,
|
|
||||||
driver,
|
|
||||||
cypherParams: {
|
|
||||||
currentUserId: authenticatedUser ? authenticatedUser.id : null,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
server = createServerResult.server
|
|
||||||
const createTestClientResult = createTestClient(server)
|
const createTestClientResult = createTestClient(server)
|
||||||
query = createTestClientResult.query
|
query = createTestClientResult.query
|
||||||
mutate = createTestClientResult.mutate
|
mutate = createTestClientResult.mutate
|
||||||
@ -118,7 +110,9 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('notify group members of new posts in group', () => {
|
describe('notify group members of new posts in group', () => {
|
||||||
@ -159,7 +153,7 @@ describe('notify group members of new posts in group', () => {
|
|||||||
password: '1234',
|
password: '1234',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
emaillessMember = await neode.create('User', {
|
emaillessMember = await database.neode.create('User', {
|
||||||
id: 'email-less-member',
|
id: 'email-less-member',
|
||||||
name: 'Email-less Member',
|
name: 'Email-less Member',
|
||||||
slug: 'email-less-member',
|
slug: 'email-less-member',
|
||||||
|
|||||||
@ -4,11 +4,13 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import { createTestClient } from 'apollo-server-testing'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
import databaseContext from '@context/database'
|
||||||
|
import pubsubContext from '@context/pubsub'
|
||||||
import Factory, { cleanDatabase } from '@db/factories'
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
import { getNeode, getDriver } from '@db/neo4j'
|
|
||||||
import { changeGroupMemberRoleMutation } from '@graphql/queries/changeGroupMemberRoleMutation'
|
import { changeGroupMemberRoleMutation } from '@graphql/queries/changeGroupMemberRoleMutation'
|
||||||
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
import { createGroupMutation } from '@graphql/queries/createGroupMutation'
|
||||||
import { createMessageMutation } from '@graphql/queries/createMessageMutation'
|
import { createMessageMutation } from '@graphql/queries/createMessageMutation'
|
||||||
@ -16,7 +18,7 @@ import { createRoomMutation } from '@graphql/queries/createRoomMutation'
|
|||||||
import { joinGroupMutation } from '@graphql/queries/joinGroupMutation'
|
import { joinGroupMutation } from '@graphql/queries/joinGroupMutation'
|
||||||
import { leaveGroupMutation } from '@graphql/queries/leaveGroupMutation'
|
import { leaveGroupMutation } from '@graphql/queries/leaveGroupMutation'
|
||||||
import { removeUserFromGroupMutation } from '@graphql/queries/removeUserFromGroupMutation'
|
import { removeUserFromGroupMutation } from '@graphql/queries/removeUserFromGroupMutation'
|
||||||
import createServer, { pubsub } from '@src/server'
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
const sendMailMock: (notification) => void = jest.fn()
|
const sendMailMock: (notification) => void = jest.fn()
|
||||||
jest.mock('@middleware/helpers/email/sendMail', () => ({
|
jest.mock('@middleware/helpers/email/sendMail', () => ({
|
||||||
@ -35,12 +37,12 @@ jest.mock('../helpers/isUserOnline', () => ({
|
|||||||
isUserOnline: () => isUserOnlineMock(),
|
isUserOnline: () => isUserOnlineMock(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
const pubsub = pubsubContext()
|
||||||
const pubsubSpy = jest.spyOn(pubsub, 'publish')
|
const pubsubSpy = jest.spyOn(pubsub, 'publish')
|
||||||
|
|
||||||
let server, query, mutate, notifiedUser, authenticatedUser
|
let query, mutate, notifiedUser, authenticatedUser
|
||||||
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
const categoryIds = ['cat9']
|
const categoryIds = ['cat9']
|
||||||
const createPostMutation = gql`
|
const createPostMutation = gql`
|
||||||
mutation ($id: ID, $title: String!, $postContent: String!, $categoryIds: [ID]!) {
|
mutation ($id: ID, $title: String!, $postContent: String!, $categoryIds: [ID]!) {
|
||||||
@ -68,19 +70,16 @@ const createCommentMutation = gql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
|
|
||||||
const createServerResult = createServer({
|
const contextUser = async (_req) => authenticatedUser
|
||||||
context: () => {
|
const context = getContext({ user: contextUser, database, pubsub })
|
||||||
return {
|
|
||||||
user: authenticatedUser,
|
server = createServer({ context }).server
|
||||||
neode,
|
|
||||||
driver,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
server = createServerResult.server
|
|
||||||
const createTestClientResult = createTestClient(server)
|
const createTestClientResult = createTestClient(server)
|
||||||
query = createTestClientResult.query
|
query = createTestClientResult.query
|
||||||
mutate = createTestClientResult.mutate
|
mutate = createTestClientResult.mutate
|
||||||
@ -88,7 +87,9 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await cleanDatabase()
|
await cleanDatabase()
|
||||||
await driver.close()
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@ -104,7 +105,7 @@ beforeEach(async () => {
|
|||||||
password: '1234',
|
password: '1234',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
await neode.create('Category', {
|
await database.neode.create('Category', {
|
||||||
id: 'cat9',
|
id: 'cat9',
|
||||||
name: 'Democracy & Politics',
|
name: 'Democracy & Politics',
|
||||||
icon: 'university',
|
icon: 'university',
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
/* eslint-disable import/no-cycle */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
/* eslint-disable security/detect-object-injection */
|
/* eslint-disable security/detect-object-injection */
|
||||||
|
import {
|
||||||
|
NOTIFICATION_ADDED,
|
||||||
|
ROOM_COUNT_UPDATED,
|
||||||
|
CHAT_MESSAGE_ADDED,
|
||||||
|
} from '@constants/subscriptions'
|
||||||
import { getUnreadRoomsCount } from '@graphql/resolvers/rooms'
|
import { getUnreadRoomsCount } from '@graphql/resolvers/rooms'
|
||||||
import { sendMail } from '@middleware/helpers/email/sendMail'
|
import { sendMail } from '@middleware/helpers/email/sendMail'
|
||||||
import {
|
import {
|
||||||
@ -13,7 +17,6 @@ import {
|
|||||||
} from '@middleware/helpers/email/templateBuilder'
|
} from '@middleware/helpers/email/templateBuilder'
|
||||||
import { isUserOnline } from '@middleware/helpers/isUserOnline'
|
import { isUserOnline } from '@middleware/helpers/isUserOnline'
|
||||||
import { validateNotifyUsers } from '@middleware/validation/validationMiddleware'
|
import { validateNotifyUsers } from '@middleware/validation/validationMiddleware'
|
||||||
import { pubsub, NOTIFICATION_ADDED, ROOM_COUNT_UPDATED, CHAT_MESSAGE_ADDED } from '@src/server'
|
|
||||||
|
|
||||||
import extractMentionedUsers from './mentions/extractMentionedUsers'
|
import extractMentionedUsers from './mentions/extractMentionedUsers'
|
||||||
|
|
||||||
@ -25,7 +28,7 @@ const publishNotifications = async (
|
|||||||
): Promise<string[]> => {
|
): Promise<string[]> => {
|
||||||
const notifications = await notificationsPromise
|
const notifications = await notificationsPromise
|
||||||
notifications.forEach((notificationAdded) => {
|
notifications.forEach((notificationAdded) => {
|
||||||
pubsub.publish(NOTIFICATION_ADDED, { notificationAdded })
|
context.pubsub.publish(NOTIFICATION_ADDED, { notificationAdded })
|
||||||
if (
|
if (
|
||||||
notificationAdded.email && // no primary email was found
|
notificationAdded.email && // no primary email was found
|
||||||
(notificationAdded.to[emailNotificationSetting] ?? true) &&
|
(notificationAdded.to[emailNotificationSetting] ?? true) &&
|
||||||
@ -482,11 +485,11 @@ const handleCreateMessage = async (resolve, root, args, context, resolveInfo) =>
|
|||||||
// send subscriptions
|
// send subscriptions
|
||||||
const roomCountUpdated = await getUnreadRoomsCount(recipientUser.id, session)
|
const roomCountUpdated = await getUnreadRoomsCount(recipientUser.id, session)
|
||||||
|
|
||||||
void pubsub.publish(ROOM_COUNT_UPDATED, {
|
void context.pubsub.publish(ROOM_COUNT_UPDATED, {
|
||||||
roomCountUpdated,
|
roomCountUpdated,
|
||||||
userId: recipientUser.id,
|
userId: recipientUser.id,
|
||||||
})
|
})
|
||||||
void pubsub.publish(CHAT_MESSAGE_ADDED, {
|
void context.pubsub.publish(CHAT_MESSAGE_ADDED, {
|
||||||
chatMessageAdded: message,
|
chatMessageAdded: message,
|
||||||
userId: recipientUser.id,
|
userId: recipientUser.id,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -10,62 +10,55 @@ import http from 'node:http'
|
|||||||
import { ApolloServer } from 'apollo-server-express'
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
import bodyParser from 'body-parser'
|
import bodyParser from 'body-parser'
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import { RedisPubSub } from 'graphql-redis-subscriptions'
|
|
||||||
import { PubSub } from 'graphql-subscriptions'
|
|
||||||
import { graphqlUploadExpress } from 'graphql-upload'
|
import { graphqlUploadExpress } from 'graphql-upload'
|
||||||
import helmet from 'helmet'
|
import helmet from 'helmet'
|
||||||
import Redis from 'ioredis'
|
|
||||||
|
import databaseContext from '@context/database'
|
||||||
|
import pubsubContext from '@context/pubsub'
|
||||||
|
|
||||||
import CONFIG from './config'
|
import CONFIG from './config'
|
||||||
import { getNeode, getDriver } from './db/neo4j'
|
|
||||||
import schema from './graphql/schema'
|
import schema from './graphql/schema'
|
||||||
import decode from './jwt/decode'
|
import decode from './jwt/decode'
|
||||||
// eslint-disable-next-line import/no-cycle
|
|
||||||
import middleware from './middleware'
|
import middleware from './middleware'
|
||||||
|
|
||||||
export const NOTIFICATION_ADDED = 'NOTIFICATION_ADDED'
|
const serverDatabase = databaseContext()
|
||||||
export const CHAT_MESSAGE_ADDED = 'CHAT_MESSAGE_ADDED'
|
const serverPubsub = pubsubContext()
|
||||||
export const ROOM_COUNT_UPDATED = 'ROOM_COUNT_UPDATED'
|
|
||||||
const { REDIS_DOMAIN, REDIS_PORT, REDIS_PASSWORD } = CONFIG
|
|
||||||
let prodPubsub, devPubsub
|
|
||||||
const options = {
|
|
||||||
host: REDIS_DOMAIN,
|
|
||||||
port: REDIS_PORT,
|
|
||||||
password: REDIS_PASSWORD,
|
|
||||||
retryStrategy: (times) => {
|
|
||||||
return Math.min(times * 50, 2000)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if (options.host && options.port && options.password) {
|
|
||||||
prodPubsub = new RedisPubSub({
|
|
||||||
publisher: new Redis(options),
|
|
||||||
subscriber: new Redis(options),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
devPubsub = new PubSub()
|
|
||||||
}
|
|
||||||
export const pubsub = prodPubsub || devPubsub
|
|
||||||
const driver = getDriver()
|
|
||||||
const neode = getNeode()
|
|
||||||
|
|
||||||
const getContext = async (req) => {
|
const databaseUser = async (req) => decode(serverDatabase.driver, req.headers.authorization)
|
||||||
const user = await decode(driver, req.headers.authorization)
|
|
||||||
|
export const getContext =
|
||||||
|
(
|
||||||
|
{
|
||||||
|
database = serverDatabase,
|
||||||
|
pubsub = serverPubsub,
|
||||||
|
user = databaseUser,
|
||||||
|
}: {
|
||||||
|
database?: ReturnType<typeof databaseContext>
|
||||||
|
pubsub?: ReturnType<typeof pubsubContext>
|
||||||
|
user?: (any) => Promise<any>
|
||||||
|
} = { database: serverDatabase, pubsub: serverPubsub, user: databaseUser },
|
||||||
|
) =>
|
||||||
|
async (req) => {
|
||||||
|
const u = await user(req)
|
||||||
return {
|
return {
|
||||||
driver,
|
database,
|
||||||
neode,
|
driver: database.driver,
|
||||||
user,
|
neode: database.neode,
|
||||||
|
pubsub,
|
||||||
|
user: u,
|
||||||
req,
|
req,
|
||||||
cypherParams: {
|
cypherParams: {
|
||||||
currentUserId: user ? user.id : null,
|
currentUserId: u ? u.id : null,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const context = async (options) => {
|
export const context = async (options) => {
|
||||||
const { connection, req } = options
|
const { connection, req } = options
|
||||||
if (connection) {
|
if (connection) {
|
||||||
return connection.context
|
return connection.context
|
||||||
} else {
|
} else {
|
||||||
return getContext(req)
|
return getContext()(req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,9 +67,7 @@ const createServer = (options?) => {
|
|||||||
context,
|
context,
|
||||||
schema: middleware(schema),
|
schema: middleware(schema),
|
||||||
subscriptions: {
|
subscriptions: {
|
||||||
onConnect: (connectionParams, _webSocket) => {
|
onConnect: (connectionParams) => getContext()(connectionParams),
|
||||||
return getContext(connectionParams)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
debug: !!CONFIG.DEBUG,
|
debug: !!CONFIG.DEBUG,
|
||||||
uploads: false,
|
uploads: false,
|
||||||
@ -88,11 +79,10 @@ const createServer = (options?) => {
|
|||||||
return error
|
return error
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const server = new ApolloServer(Object.assign({}, defaults, options))
|
const server = new ApolloServer(Object.assign(defaults, options))
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
|
|
||||||
app.set('driver', driver)
|
|
||||||
// TODO: this exception is required for the graphql playground, since the playground loads external resources
|
// TODO: this exception is required for the graphql playground, since the playground loads external resources
|
||||||
// See: https://github.com/graphql/graphql-playground/issues/1283
|
// See: https://github.com/graphql/graphql-playground/issues/1283
|
||||||
app.use(
|
app.use(
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
"paths": { /* Specify a set of entries that re-map imports to additional lookup locations. */
|
"paths": { /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||||
"@config/*": ["./src/config/*"],
|
"@config/*": ["./src/config/*"],
|
||||||
"@constants/*": ["./src/constants/*"],
|
"@constants/*": ["./src/constants/*"],
|
||||||
|
"@context/*": ["./src/context/*"],
|
||||||
"@db/*": ["./src/db/*"],
|
"@db/*": ["./src/db/*"],
|
||||||
"@graphql/*": ["./src/graphql/*"],
|
"@graphql/*": ["./src/graphql/*"],
|
||||||
"@helpers/*": ["./src/helpers/*"],
|
"@helpers/*": ["./src/helpers/*"],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user