Merge pull request #2978 from specklesystems/fabians/notifications-ioc-1

chore(server): notifications IoC 1 - getUserNotificationPreferencesFactory
This commit is contained in:
Alessandro Magionami
2024-09-13 10:28:33 +02:00
committed by GitHub
6 changed files with 64 additions and 28 deletions
@@ -0,0 +1,5 @@
import { NotificationPreferences } from '@/modules/notifications/helpers/types'
export type GetSavedUserNotificationPreferences = (
userId: string
) => Promise<NotificationPreferences>
@@ -1,10 +1,18 @@
import { db } from '@/db/knex'
import { Resolvers } from '@/modules/core/graph/generated/graphql'
import { getSavedUserNotificationPreferencesFactory } from '@/modules/notifications/repositories'
import {
updateNotificationPreferences,
getUserNotificationPreferences
getUserNotificationPreferencesFactory
} from '@/modules/notifications/services/notificationPreferences'
module.exports = {
const getUserNotificationPreferences = getUserNotificationPreferencesFactory({
getSavedUserNotificationPreferences: getSavedUserNotificationPreferencesFactory({
db
})
})
export = {
User: {
async notificationPreferences(parent) {
const preferences = await getUserNotificationPreferences(parent.id)
@@ -12,12 +20,8 @@ module.exports = {
}
},
Mutation: {
async userNotificationPreferencesUpdate(
_parent,
args,
context: { userId: string }
) {
await updateNotificationPreferences(context.userId, args.preferences)
async userNotificationPreferencesUpdate(_parent, args, context) {
await updateNotificationPreferences(context.userId!, args.preferences)
return true
}
}
@@ -1,19 +1,26 @@
import { UserNotificationPreferences } from '@/modules/core/dbSchema'
import { GetSavedUserNotificationPreferences } from '@/modules/notifications/domain/operations'
import {
NotificationPreferences,
UserNotificationPreferencesRecord
} from '@/modules/notifications/helpers/types'
import { Knex } from 'knex'
export async function getUserNotificationPreferences(
userId: string
): Promise<NotificationPreferences> {
const userPreferences =
await UserNotificationPreferences.knex<UserNotificationPreferencesRecord>()
const tables = {
userNotificationPreferences: (db: Knex) =>
db<UserNotificationPreferencesRecord>(UserNotificationPreferences.name)
}
export const getSavedUserNotificationPreferencesFactory =
(deps: { db: Knex }): GetSavedUserNotificationPreferences =>
async (userId: string): Promise<NotificationPreferences> => {
const userPreferences = await tables
.userNotificationPreferences(deps.db)
.where({ userId })
.first()
return userPreferences?.preferences ?? {}
}
return userPreferences?.preferences ?? {}
}
export async function saveUserNotificationPreferences(
userId: string,
@@ -10,7 +10,6 @@ import {
} from '@/modules/activitystream/helpers/types'
import { getServerInfo } from '@/modules/core/services/generic'
import { ServerInfo, UserRecord } from '@/modules/core/helpers/types'
import { getUserNotificationPreferences } from '@/modules/notifications/services/notificationPreferences'
import { sendEmail, SendEmailParams } from '@/modules/emails/services/sending'
import { groupBy } from 'lodash'
import { packageRoot } from '@/bootstrap'
@@ -26,6 +25,9 @@ import {
EmailInput,
renderEmail
} from '@/modules/emails/services/emailRendering'
import { getUserNotificationPreferencesFactory } from '@/modules/notifications/services/notificationPreferences'
import { getSavedUserNotificationPreferencesFactory } from '@/modules/notifications/repositories'
import { db } from '@/db/knex'
const handler: NotificationHandler<ActivityDigestMessage> = async (msg) => {
const {
@@ -44,6 +46,12 @@ const digestNotificationEmailHandler = async (
end: Date,
emailSender: (params: SendEmailParams) => Promise<boolean>
): Promise<boolean | null> => {
const getUserNotificationPreferences = getUserNotificationPreferencesFactory({
getSavedUserNotificationPreferences: getSavedUserNotificationPreferencesFactory({
db
})
})
const wantDigests =
(await (await getUserNotificationPreferences(userId)).activityDigest?.email) !==
false
@@ -5,15 +5,18 @@ import {
NotificationPreferences
} from '@/modules/notifications/helpers/types'
import { InvalidArgumentError } from '@/modules/shared/errors'
import { GetSavedUserNotificationPreferences } from '@/modules/notifications/domain/operations'
export async function getUserNotificationPreferences(
userId: string
): Promise<NotificationPreferences> {
const savedPreferences = await repo.getUserNotificationPreferences(userId)
return addDefaultPreferenceValues(savedPreferences)
}
export const getUserNotificationPreferencesFactory =
(deps: {
getSavedUserNotificationPreferences: GetSavedUserNotificationPreferences
}) =>
async (userId: string): Promise<NotificationPreferences> => {
const savedPreferences = await deps.getSavedUserNotificationPreferences(userId)
return addDefaultPreferenceValues(savedPreferences)
}
export function addDefaultPreferenceValues(
function addDefaultPreferenceValues(
preferences: NotificationPreferences
): NotificationPreferences {
const savedPreferences = { ...preferences }
@@ -1,7 +1,6 @@
import { truncateTables } from '@/test/hooks'
import { UserNotificationPreferences, Users } from '@/modules/core/dbSchema'
import { BasicTestUser, createTestUsers } from '@/test/authHelper'
import * as repo from '@/modules/notifications/repositories'
import * as services from '@/modules/notifications/services/notificationPreferences'
import { expect } from 'chai'
import {
@@ -9,6 +8,16 @@ import {
NotificationChannel
} from '@/modules/notifications/helpers/types'
import { BaseError } from '@/modules/shared/errors'
import { getUserNotificationPreferencesFactory } from '@/modules/notifications/services/notificationPreferences'
import { getSavedUserNotificationPreferencesFactory } from '@/modules/notifications/repositories'
import { db } from '@/db/knex'
const getSavedUserNotificationPreferences = getSavedUserNotificationPreferencesFactory({
db
})
const getUserNotificationPreferences = getUserNotificationPreferencesFactory({
getSavedUserNotificationPreferences
})
const cleanup = async () => {
await truncateTables([Users.name, UserNotificationPreferences.name])
@@ -28,10 +37,10 @@ describe('User notification preferences @notifications', () => {
describe('services', () => {
it('gets default preferences if none saved', async () => {
const savedPreferences = await repo.getUserNotificationPreferences(userA.id)
const savedPreferences = await getSavedUserNotificationPreferences(userA.id)
expect(savedPreferences).to.deep.equal({})
expect(savedPreferences).to.be.empty
const preferences = await services.getUserNotificationPreferences(userA.id)
const preferences = await getUserNotificationPreferences(userA.id)
expect(preferences).to.not.be.empty
for (const val of Object.values(preferences)) {
for (const setting of Object.values(val)) {
@@ -43,13 +52,13 @@ describe('User notification preferences @notifications', () => {
await services.updateNotificationPreferences(userA.id, {
activityDigest: { email: false }
})
let preferences = await services.getUserNotificationPreferences(userA.id)
let preferences = await getUserNotificationPreferences(userA.id)
expect(preferences).to.not.be.empty
expect(preferences.activityDigest?.email).to.be.false
await services.updateNotificationPreferences(userA.id, {
activityDigest: { email: true }
})
preferences = await services.getUserNotificationPreferences(userA.id)
preferences = await getUserNotificationPreferences(userA.id)
expect(preferences.activityDigest?.email).to.be.true
})
it("doesn't store invalid preference keys", async () => {