fix(backend): fix bug in notifications settings for currentUser (#9130)

This commit is contained in:
Ulf Gebhardt 2026-01-28 00:36:51 +01:00 committed by GitHub
parent 0ee476cfff
commit 8136ec1aba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 64 additions and 65 deletions

View File

@ -2,21 +2,20 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '@db/factories'
import { getDriver, getNeode } from '@db/neo4j'
import { followUser } from '@graphql/queries/followUser'
import { unfollowUser } from '@graphql/queries/unfollowUser'
import { User } from '@graphql/queries/User'
import createServer from '@src/server'
import { createApolloTestSetup } from '@root/test/helpers'
import type { ApolloTestSetup } from '@root/test/helpers'
import type { Context } from '@src/context'
const driver = getDriver()
const neode = getNeode()
let query
let mutate
let authenticatedUser
let authenticatedUser: Context['user']
const context = () => ({ authenticatedUser })
let mutate: ApolloTestSetup['mutate']
let query: ApolloTestSetup['query']
let database: ApolloTestSetup['database']
let server: ApolloTestSetup['server']
let user1
let user2
@ -24,26 +23,18 @@ let variables
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => ({
driver,
neode,
user: authenticatedUser,
cypherParams: {
currentUserId: authenticatedUser ? authenticatedUser.id : null,
},
}),
})
const testClient = createTestClient(server)
query = testClient.query
mutate = testClient.mutate
const apolloSetup = createApolloTestSetup({ context })
mutate = apolloSetup.mutate
query = apolloSetup.query
database = apolloSetup.database
server = apolloSetup.server
})
afterAll(async () => {
await cleanDatabase()
await driver.close()
void server.stop()
void database.driver.close()
database.neode.close()
})
beforeEach(async () => {
@ -118,7 +109,7 @@ describe('follow', () => {
mutation: followUser,
variables,
})
const relation = await neode.cypher(
const relation = await database.neode.cypher(
'MATCH (user:User {id: $id})-[relationship:FOLLOWS]->(followed:User) WHERE relationship.createdAt IS NOT NULL RETURN relationship',
{ id: 'u1' },
)

View File

@ -1,41 +1,34 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '@db/factories'
import { getNeode, getDriver } from '@db/neo4j'
import { UpdateUser } from '@graphql/queries/UpdateUser'
import { User } from '@graphql/queries/User'
import createServer from '@src/server'
import { createApolloTestSetup } from '@root/test/helpers'
import type { ApolloTestSetup } from '@root/test/helpers'
import type { Context } from '@src/context'
let query, mutate, authenticatedUser
const driver = getDriver()
const neode = getNeode()
let authenticatedUser: Context['user']
const context = () => ({ authenticatedUser })
let mutate: ApolloTestSetup['mutate']
let query: ApolloTestSetup['query']
let database: ApolloTestSetup['database']
let server: ApolloTestSetup['server']
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
driver,
neode,
user: authenticatedUser,
cypherParams: {
currentUserId: authenticatedUser ? authenticatedUser.id : null,
},
}
},
})
query = createTestClient(server).query
mutate = createTestClient(server).mutate
const apolloSetup = createApolloTestSetup({ context })
mutate = apolloSetup.mutate
query = apolloSetup.query
database = apolloSetup.database
server = apolloSetup.server
})
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

View File

@ -1,11 +1,9 @@
/* 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 */
import { AuthenticationError } from 'apollo-server'
import bcrypt from 'bcryptjs'
import { neo4jgraphql } from 'neo4j-graphql-js'
import { getNeode } from '@db/neo4j'
import { encode } from '@jwt/encode'
@ -17,8 +15,21 @@ const neode = getNeode()
export default {
Query: {
currentUser: async (object, params, context, resolveInfo) =>
await neo4jgraphql(object, { id: context.user.id }, context, resolveInfo),
currentUser: async (_object, _params, context: Context, _resolveInfo) => {
if (!context.user) {
throw new Error('You must be logged in')
}
const [user] = (
await context.database.query({
query: `
MATCH (user:User {id: $user.id})-[:PRIMARY_EMAIL]->(e:EmailAddress)
RETURN user {.*, email: e.email}
`,
variables: { user: context.user },
})
).records.map((record) => record.get('user'))
return user
},
},
Mutation: {
login: async (_, { email, password }, context: Context) => {

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-call */
@ -458,6 +457,18 @@ export default {
},
},
User: {
activeCategories: async (parent, _args, context: Context, _resolveInfo) => {
return (
await context.database.query({
query: `
MATCH (category:Category)
WHERE NOT ((:User{id: $user.id})-[:NOT_INTERESTED_IN]->(category))
RETURN collect(category.id) as categories
`,
variables: { user: parent },
})
).records.map((record) => record.get('categories'))[0]
},
inviteCodes: async (_parent, _args, context: Context, _resolveInfo) => {
return (
await context.database.query({
@ -471,7 +482,7 @@ export default {
})
).records.map((record) => record.get('inviteCodes'))
},
emailNotificationSettings: async (parent, _params, _context, _resolveInfo) => {
emailNotificationSettings: (parent, _params, _context, _resolveInfo) => {
return [
{
type: 'post',
@ -633,7 +644,6 @@ export default {
'allowEmbedIframes',
'showShoutsPublicly',
'locale',
'activeCategories',
],
boolean: {
followedByCurrentUser:

View File

@ -137,13 +137,7 @@ type User {
emotions: [EMOTED]
activeCategories: [String] @cypher(
statement: """
MATCH (category:Category)
WHERE NOT ((this)-[:NOT_INTERESTED_IN]->(category))
RETURN collect(category.id)
"""
)
activeCategories: [String] @neo4j_ignore
myRoleInGroup: GroupMemberRole
}