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