From a8f4fe86dbccde56264b639bb35f6aed09334374 Mon Sep 17 00:00:00 2001 From: Mohammad Ranjbar Z Date: Mon, 20 Feb 2023 16:37:47 +0330 Subject: [PATCH 1/5] 2.0.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a54325e..3c91678 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "notification-venter", - "version": "1.0.0", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "notification-venter", - "version": "1.0.0", + "version": "2.0.0", "license": "ISC", "dependencies": { "@adminjs/express": "4.1.0", diff --git a/package.json b/package.json index 667a858..62fddca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "notification-venter", - "version": "1.0.0", + "version": "2.0.0", "description": "", "main": "index.js", "scripts": { From c4d9e3045a222ee1730219428004e54f326a9ff7 Mon Sep 17 00:00:00 2001 From: Mohammad Ranjbar Z Date: Tue, 21 Feb 2023 11:49:48 +0330 Subject: [PATCH 2/5] Fix notification setting default values related to #46 --- .../notificationSettingRepository.test.ts | 337 +++++++------- .../notificationSettingRepository.ts | 305 +++++++------ .../notificationTypeRepository.ts | 33 +- .../v1/notificationSettingsRouter.test.ts | 431 +++++++++--------- 4 files changed, 555 insertions(+), 551 deletions(-) diff --git a/src/repositories/notificationSettingRepository.test.ts b/src/repositories/notificationSettingRepository.test.ts index 97aa7eb..4f1e2f1 100644 --- a/src/repositories/notificationSettingRepository.test.ts +++ b/src/repositories/notificationSettingRepository.test.ts @@ -1,195 +1,196 @@ -import { assert } from 'chai'; -import { generateRandomEthereumAddress } from '../../test/testUtils'; -import { NotificationSetting } from '../entities/notificationSetting'; +import {assert} from 'chai'; +import {generateRandomEthereumAddress} from '../../test/testUtils'; +import {NotificationSetting} from '../entities/notificationSetting'; import { - findNotificationSettingByNotificationTypeAndUserAddress, - getUserNotificationSettings, - updateUserNotificationSetting, + findNotificationSettingByNotificationTypeAndUserAddress, + getUserNotificationSettings, + updateUserNotificationSetting, } from './notificationSettingRepository'; -import { createNewUserAddressIfNotExists } from './userAddressRepository'; -import { getNotificationTypeByEventName } from './notificationTypeRepository'; -import { SegmentEvents } from '../services/segment/segmentAnalyticsSingleton'; +import {createNewUserAddressIfNotExists} from './userAddressRepository'; +import {getNotificationTypeByEventName} from './notificationTypeRepository'; +import {SegmentEvents} from '../services/segment/segmentAnalyticsSingleton'; // createNotificationSettingsForNewUser tested in userRepository describe( - 'getUserNotificationSettings() test cases', - getUserNotificationSettingsTestCases, + 'getUserNotificationSettings() test cases', + getUserNotificationSettingsTestCases, ); describe( - 'updateUserNotificationSetting() test cases', - updateUserNotificationSettingTestCases, + 'updateUserNotificationSetting() test cases', + updateUserNotificationSettingTestCases, ); describe( - 'findNotificationSettingByNotificationTypeAndUserAddress() test cases', - findNotificationSettingByNotificationTypeAndUserAddressTestCases, + 'findNotificationSettingByNotificationTypeAndUserAddress() test cases', + findNotificationSettingByNotificationTypeAndUserAddressTestCases, ); const walletAddress = generateRandomEthereumAddress(); function getUserNotificationSettingsTestCases() { - it('return notification settings by user and take and skip', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const take = 50; - const skip = 0; - - const [notificationSettings] = await getUserNotificationSettings( - take, - skip, - userAddress.id, - ); - - assert.isOk(notificationSettings); - notificationSettings.forEach(setting => { - assert.isTrue(setting!.userAddressId === userAddress.id); - assert.isTrue(setting?.notificationType?.showOnSettingPage); + it('return notification settings by user and take and skip', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const take = 50; + const skip = 0; + + const [notificationSettings] = await getUserNotificationSettings( + take, + skip, + userAddress.id, + ); + + assert.isOk(notificationSettings); + notificationSettings.forEach(setting => { + assert.isTrue(setting!.userAddressId === userAddress.id); + assert.isTrue(setting?.notificationType?.showOnSettingPage); + }); }); - }); - it('return notification settings order by notificationTypeId', async () => { - const userAddress = await createNewUserAddressIfNotExists( - generateRandomEthereumAddress(), - ); - - const [notificationSettings] = await getUserNotificationSettings( - 100, - 0, - userAddress.id, - ); - - assert.isOk(notificationSettings); - notificationSettings.forEach(setting => { - assert.isTrue(setting!.userAddressId === userAddress.id); - assert.isTrue(setting?.notificationType?.showOnSettingPage); + it('return notification settings order by notificationTypeId', async () => { + const userAddress = await createNewUserAddressIfNotExists( + generateRandomEthereumAddress(), + ); + + const [notificationSettings] = await getUserNotificationSettings( + 100, + 0, + userAddress.id, + ); + + assert.isOk(notificationSettings); + notificationSettings.forEach(setting => { + assert.isTrue(setting!.userAddressId === userAddress.id); + assert.isTrue(setting?.notificationType?.showOnSettingPage); + }); + + for (let i = 1; i < notificationSettings.length; i++) { + assert.isTrue( + notificationSettings[i]?.notificationTypeId > + notificationSettings[i - 1]?.notificationTypeId, + ); + } }); - - for (let i = 1; i < notificationSettings.length; i++) { - assert.isTrue( - notificationSettings[i]?.notificationTypeId > - notificationSettings[i - 1]?.notificationTypeId, - ); - } - }); } function findNotificationSettingByNotificationTypeAndUserAddressTestCases() { - it('return notification settings for userAddress and notificationType', async () => { - const address = generateRandomEthereumAddress(); - const userAddress = await createNewUserAddressIfNotExists(address); - const notificationType = await getNotificationTypeByEventName( - SegmentEvents.PROJECT_LISTED, - ); - const notificationSettings = - await findNotificationSettingByNotificationTypeAndUserAddress({ - userAddressId: userAddress.id, - notificationTypeId: notificationType?.id as number, - }); - - assert.isOk(notificationSettings); - assert.equal( - notificationSettings?.notificationTypeId, - notificationType?.id, - ); - assert.equal(notificationSettings?.userAddressId, userAddress?.id); - }); - it('return null for invalid notificationType', async () => { - const address = generateRandomEthereumAddress(); - const userAddress = await createNewUserAddressIfNotExists(address); - const notificationSettings = - await findNotificationSettingByNotificationTypeAndUserAddress({ - userAddressId: userAddress.id, - notificationTypeId: 999999, - }); - - assert.isNull(notificationSettings); - }); - - it('return null for invalid notificationAddress', async () => { - const notificationType = await getNotificationTypeByEventName( - SegmentEvents.PROJECT_LISTED, - ); - const notificationSettings = - await findNotificationSettingByNotificationTypeAndUserAddress({ - userAddressId: 99999, - notificationTypeId: notificationType?.id as number, - }); - assert.isNull(notificationSettings); - }); + it('return notification settings for userAddress and notificationType', async () => { + const address = generateRandomEthereumAddress(); + const userAddress = await createNewUserAddressIfNotExists(address); + const notificationType = await getNotificationTypeByEventName( + SegmentEvents.PROJECT_LISTED, + ); + const notificationSettings = + await findNotificationSettingByNotificationTypeAndUserAddress({ + userAddressId: userAddress.id, + notificationTypeId: notificationType?.id as number, + }); + + assert.isOk(notificationSettings); + assert.equal( + notificationSettings?.notificationTypeId, + notificationType?.id, + ); + assert.equal(notificationSettings?.userAddressId, userAddress?.id); + }); + it('return null for invalid notificationType', async () => { + const address = generateRandomEthereumAddress(); + const userAddress = await createNewUserAddressIfNotExists(address); + const notificationSettings = + await findNotificationSettingByNotificationTypeAndUserAddress({ + userAddressId: userAddress.id, + notificationTypeId: 999999, + }); + + assert.isNull(notificationSettings); + }); + + it('return null for invalid notificationAddress', async () => { + const notificationType = await getNotificationTypeByEventName( + SegmentEvents.PROJECT_LISTED, + ); + const notificationSettings = + await findNotificationSettingByNotificationTypeAndUserAddress({ + userAddressId: 99999, + notificationTypeId: notificationType?.id as number, + }); + assert.isNull(notificationSettings); + }); } function updateUserNotificationSettingTestCases() { - it('update user notification settings', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - - const userNotificationSetting = - await NotificationSetting.createQueryBuilder('setting') - .leftJoinAndSelect('setting.notificationType', 'notificationType') - .where('setting."userAddressId" = :userAddressId', { - userAddressId: userAddress.id, - }) - .andWhere('notificationType.isGroupParent = false') - .andWhere('notificationType.isEmailEditable = true') - .andWhere('notificationType.isWebEditable = true') - .getOne(); - - assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); - - const updatedSetting = await updateUserNotificationSetting({ - notificationSettingId: userNotificationSetting!.id, - userAddressId: userAddress.id, - allowEmailNotification: false, - allowDappPushNotification: false, + it('update user notification settings', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + + const userNotificationSetting = + await NotificationSetting.createQueryBuilder('setting') + .leftJoinAndSelect('setting.notificationType', 'notificationType') + .where('setting."userAddressId" = :userAddressId', { + userAddressId: userAddress.id, + }) + .andWhere('notificationType.isGroupParent = false') + .andWhere('notificationType.isEmailEditable = true') + .andWhere('notificationType.isWebEditable = true') + .getOne(); + + assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); + + const updatedSetting = await updateUserNotificationSetting({ + notificationSettingId: userNotificationSetting!.id, + userAddressId: userAddress.id, + allowEmailNotification: false, + allowDappPushNotification: false, + }); + assert.isOk(updatedSetting); + assert.isFalse(updatedSetting?.allowEmailNotification); + assert.isFalse(updatedSetting?.allowDappPushNotification); }); - assert.isOk(updatedSetting); - assert.isFalse(updatedSetting?.allowEmailNotification); - assert.isFalse(updatedSetting?.allowDappPushNotification); - }); - it('update user notification settings, cant change when isEmailEditable is false', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - - const userNotificationSetting = - await NotificationSetting.createQueryBuilder('setting') - .leftJoinAndSelect('setting.notificationType', 'notificationType') - .where('setting."userAddressId" = :userAddressId', { - userAddressId: userAddress.id, - }) - .andWhere('notificationType.isGroupParent = false') - .andWhere('notificationType.isEmailEditable = false') - .andWhere('notificationType.isWebEditable = true') - .getOne(); - - assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); - - const updatedSetting = await updateUserNotificationSetting({ - notificationSettingId: userNotificationSetting!.id, - userAddressId: userAddress.id, - allowEmailNotification: false, - allowDappPushNotification: false, + it('update user notification settings, cant change when isEmailEditable is false', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + + const userNotificationSetting = + await NotificationSetting.createQueryBuilder('setting') + .leftJoinAndSelect('setting.notificationType', 'notificationType') + .where('setting."userAddressId" = :userAddressId', { + userAddressId: userAddress.id, + }) + .andWhere('notificationType.isGroupParent = true') + .andWhere('notificationType.isEmailEditable = false') + .andWhere('setting.allowEmailNotification = false') + .andWhere('notificationType.isWebEditable = true') + .getOne(); + + assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); + + const updatedSetting = await updateUserNotificationSetting({ + notificationSettingId: userNotificationSetting!.id, + userAddressId: userAddress.id, + allowEmailNotification: true, + allowDappPushNotification: false, + }); + assert.isOk(updatedSetting); + assert.isFalse(updatedSetting?.allowEmailNotification); + assert.isFalse(updatedSetting?.allowDappPushNotification); }); - assert.isOk(updatedSetting); - assert.isTrue(updatedSetting?.allowEmailNotification); - assert.isFalse(updatedSetting?.allowDappPushNotification); - }); - it('update user notification settings, cant change when isWebEditable is false', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - - const userNotificationSetting = - await NotificationSetting.createQueryBuilder('setting') - .leftJoinAndSelect('setting.notificationType', 'notificationType') - .where('setting."userAddressId" = :userAddressId', { - userAddressId: userAddress.id, - }) - .andWhere('notificationType.isWebEditable = false') - .getOne(); - - assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); - - const updatedSetting = await updateUserNotificationSetting({ - notificationSettingId: userNotificationSetting!.id, - userAddressId: userAddress.id, - allowEmailNotification: false, - allowDappPushNotification: false, + it('update user notification settings, cant change when isWebEditable is false', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + + const userNotificationSetting = + await NotificationSetting.createQueryBuilder('setting') + .leftJoinAndSelect('setting.notificationType', 'notificationType') + .where('setting."userAddressId" = :userAddressId', { + userAddressId: userAddress.id, + }) + .andWhere('notificationType.isWebEditable = false') + .getOne(); + + assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); + + const updatedSetting = await updateUserNotificationSetting({ + notificationSettingId: userNotificationSetting!.id, + userAddressId: userAddress.id, + allowEmailNotification: false, + allowDappPushNotification: false, + }); + assert.isOk(updatedSetting); + assert.isTrue(updatedSetting?.allowDappPushNotification); }); - assert.isOk(updatedSetting); - assert.isTrue(updatedSetting?.allowDappPushNotification); - }); } diff --git a/src/repositories/notificationSettingRepository.ts b/src/repositories/notificationSettingRepository.ts index f333e49..53d5e18 100644 --- a/src/repositories/notificationSettingRepository.ts +++ b/src/repositories/notificationSettingRepository.ts @@ -1,183 +1,188 @@ -import { UserAddress } from '../entities/userAddress'; -import { NotificationType } from '../entities/notificationType'; -import { NotificationSetting } from '../entities/notificationSetting'; -import { errorMessages } from '../utils/errorMessages'; -import { createQueryBuilder } from 'typeorm'; -import { logger } from '../utils/logger'; -import { StandardError } from '../types/StandardError'; +import {UserAddress} from '../entities/userAddress'; +import {NotificationType} from '../entities/notificationType'; +import {NotificationSetting} from '../entities/notificationSetting'; +import {errorMessages} from '../utils/errorMessages'; +import {createQueryBuilder} from 'typeorm'; +import {logger} from '../utils/logger'; +import {StandardError} from '../types/StandardError'; +import {findNotificationTypeParent} from "./notificationTypeRepository"; export const createNotificationSettingsForNewUser = async ( - user: UserAddress, + user: UserAddress, ) => { - const notificationTypes = await NotificationType.find(); - // rest of values are set by default - const typeSettings = notificationTypes.map(notificationType => { - const payload: Partial = { - notificationType: notificationType, - userAddress: user, - // allowEmailNotification: - // notificationType.emailDefaultValue !== undefined - // ? notificationType.emailDefaultValue - // : true, - }; - - return payload; - }); + const notificationTypes = await NotificationType.find(); + // rest of values are set by default + const notificationTypeSettings = [] + for (const notificationType of notificationTypes) { + const notificationParent = notificationType?.isGroupParent ? + notificationType : + await findNotificationTypeParent(notificationType.categoryGroup as string) + const payload: Partial = { + notificationType: notificationType, + userAddress: user, + allowEmailNotification: notificationParent?.emailDefaultValue !== undefined ? notificationParent?.emailDefaultValue : true, + allowDappPushNotification: + notificationParent?.webDefaultValue !== undefined + ? notificationParent?.webDefaultValue + : true, + }; + + notificationTypeSettings.push(payload); + } - const userSettings = NotificationSetting.create(typeSettings); + const userSettings = NotificationSetting.create(notificationTypeSettings); - return await NotificationSetting.save(userSettings); + return await NotificationSetting.save(userSettings); }; export const getUserNotificationSettings = async ( - take: number, - skip: number, - userAddressId: number, - category?: string, + take: number, + skip: number, + userAddressId: number, + category?: string, ) => { - let query = NotificationSetting.createQueryBuilder('notificationSetting') - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :userAddressId', { - userAddressId: userAddressId, - }) - .andWhere('notificationType.showOnSettingPage = true'); + let query = NotificationSetting.createQueryBuilder('notificationSetting') + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :userAddressId', { + userAddressId: userAddressId, + }) + .andWhere('notificationType.showOnSettingPage = true'); - if (category) { - query = query.andWhere('notificationType.category = :category', { - category: category, - }); - } - query.orderBy('notificationType.id', 'ASC'); - return query.take(take).skip(skip).getManyAndCount(); + if (category) { + query = query.andWhere('notificationType.category = :category', { + category: category, + }); + } + query.orderBy('notificationType.id', 'ASC'); + return query.take(take).skip(skip).getManyAndCount(); }; export const findNotificationSettingByNotificationTypeAndUserAddress = - async (params: { - notificationTypeId: number; - userAddressId: number; - }): Promise => { - const { notificationTypeId, userAddressId } = params; - try { - return await NotificationSetting.createQueryBuilder('notificationSetting') - .where('notificationSetting.userAddressId = :userAddressId', { - userAddressId, - }) - .andWhere( - 'notificationSetting.notificationTypeId = :notificationTypeId', - { - notificationTypeId, - }, - ) - .getOne(); - } catch (e) { - logger.error( - 'findNotificationSettingByNotificationTypeAndUserAddress() error', - e, - ); - throw e; - } - }; + async (params: { + notificationTypeId: number; + userAddressId: number; + }): Promise => { + const {notificationTypeId, userAddressId} = params; + try { + return await NotificationSetting.createQueryBuilder('notificationSetting') + .where('notificationSetting.userAddressId = :userAddressId', { + userAddressId, + }) + .andWhere( + 'notificationSetting.notificationTypeId = :notificationTypeId', + { + notificationTypeId, + }, + ) + .getOne(); + } catch (e) { + logger.error( + 'findNotificationSettingByNotificationTypeAndUserAddress() error', + e, + ); + throw e; + } + }; export const findNotificationSettingById = async ( - id: number, + id: number, ): Promise => { - try { - return await NotificationSetting.createQueryBuilder('notificationSetting') - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.id = :id', { - id, - }) - .getOne(); - } catch (e) { - logger.error( - 'findNotificationSettingByNotificationTypeAndUserAddress() error', - e, - ); - throw e; - } + try { + return await NotificationSetting.createQueryBuilder('notificationSetting') + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.id = :id', { + id, + }) + .getOne(); + } catch (e) { + logger.error( + 'findNotificationSettingByNotificationTypeAndUserAddress() error', + e, + ); + throw e; + } }; export const updateUserNotificationSetting = async (params: { - notificationSettingId: number; - userAddressId: number; - allowEmailNotification: boolean; - allowDappPushNotification: boolean; + notificationSettingId: number; + userAddressId: number; + allowEmailNotification: boolean; + allowDappPushNotification: boolean; }): Promise => { - const notificationSetting = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', + const notificationSetting = await NotificationSetting.createQueryBuilder( + 'notificationSetting', ) - .where( - 'notificationSetting.id = :id AND notificationSetting.userAddressId = :userAddressId', - { - id: params.notificationSettingId, - userAddressId: params.userAddressId, - }, - ) - .getOne(); - - if (!notificationSetting) { - throw new StandardError({ - message: errorMessages.NOTIFICATION_SETTING_NOT_FOUND, - httpStatusCode: 400, - }); - } - if (notificationSetting.notificationType?.isEmailEditable) { - notificationSetting.allowEmailNotification = params.allowEmailNotification; - } - if (notificationSetting.notificationType?.isWebEditable) { - notificationSetting.allowDappPushNotification = - params.allowDappPushNotification; - } + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where( + 'notificationSetting.id = :id AND notificationSetting.userAddressId = :userAddressId', + { + id: params.notificationSettingId, + userAddressId: params.userAddressId, + }, + ) + .getOne(); - if ( - notificationSetting?.notificationType?.isGroupParent && - notificationSetting?.notificationType?.categoryGroup - ) { - await updateChildNotificationSettings({ - categoryGroup: notificationSetting?.notificationType?.categoryGroup, - userAddressId: params.userAddressId, - allowEmailNotification: notificationSetting.allowEmailNotification, - allowDappPushNotification: notificationSetting.allowDappPushNotification, - }); - } + if (!notificationSetting) { + throw new StandardError({ + message: errorMessages.NOTIFICATION_SETTING_NOT_FOUND, + httpStatusCode: 400, + }); + } + if (notificationSetting.notificationType?.isEmailEditable) { + notificationSetting.allowEmailNotification = params.allowEmailNotification; + } + if (notificationSetting.notificationType?.isWebEditable) { + notificationSetting.allowDappPushNotification = + params.allowDappPushNotification; + } - return notificationSetting.save(); + if ( + notificationSetting?.notificationType?.isGroupParent && + notificationSetting?.notificationType?.categoryGroup + ) { + await updateChildNotificationSettings({ + categoryGroup: notificationSetting?.notificationType?.categoryGroup, + userAddressId: params.userAddressId, + allowEmailNotification: notificationSetting.allowEmailNotification, + allowDappPushNotification: notificationSetting.allowDappPushNotification, + }); + } + return notificationSetting.save(); }; export const updateChildNotificationSettings = async (params: { - categoryGroup: string; - userAddressId: number; - allowEmailNotification: boolean; - allowDappPushNotification: boolean; + categoryGroup: string; + userAddressId: number; + allowEmailNotification: boolean; + allowDappPushNotification: boolean; }) => { - // Grab type ids - const notificationTypes = await NotificationType.createQueryBuilder( - 'notificationType', - ) - .select('notificationType.id') - .where('notificationType.categoryGroup = :categoryGroup', { - categoryGroup: params.categoryGroup, - }) - .andWhere('notificationType.isGroupParent = false') - .getMany(); + // Grab type ids + const notificationTypes = await NotificationType.createQueryBuilder( + 'notificationType', + ) + .select('notificationType.id') + .where('notificationType.categoryGroup = :categoryGroup', { + categoryGroup: params.categoryGroup, + }) + .andWhere('notificationType.isGroupParent = false') + .getMany(); - const notificationTypeIds = notificationTypes.map(notificationType => { - return notificationType.id; - }); + const notificationTypeIds = notificationTypes.map(notificationType => { + return notificationType.id; + }); - if (notificationTypeIds.length === 0) return; + if (notificationTypeIds.length === 0) return; - await NotificationSetting.query(` + await NotificationSetting.query(` UPDATE notification_setting SET "allowEmailNotification" = ${ params.allowEmailNotification diff --git a/src/repositories/notificationTypeRepository.ts b/src/repositories/notificationTypeRepository.ts index 7dc0531..d55697d 100644 --- a/src/repositories/notificationTypeRepository.ts +++ b/src/repositories/notificationTypeRepository.ts @@ -1,19 +1,28 @@ -import { NotificationType } from '../entities/notificationType'; +import {NotificationType} from '../entities/notificationType'; export const getNotificationTypeByEventName = async (eventName: string) => { - return NotificationType.createQueryBuilder() - .where('name = :name', { name: eventName }) - .getOne(); + return NotificationType.createQueryBuilder() + .where('name = :name', {name: eventName}) + .getOne(); +}; + +export const findNotificationTypeParent = async (categoryGroup: string) => { + return NotificationType.createQueryBuilder() + .where('category = :category', { + category: categoryGroup, + }) + .andWhere('"isGroupParent" = true') + .getOne(); }; export const getNotificationTypeByEventNameAndMicroservice = async (params: { - eventName: string; - microService: string; + eventName: string; + microService: string; }) => { - return NotificationType.createQueryBuilder() - .where('name = :name', { name: params.eventName }) - .andWhere('"microService" = :microService', { - microService: params.microService, - }) - .getOne(); + return NotificationType.createQueryBuilder() + .where('name = :name', {name: params.eventName}) + .andWhere('"microService" = :microService', { + microService: params.microService, + }) + .getOne(); }; diff --git a/src/routes/v1/notificationSettingsRouter.test.ts b/src/routes/v1/notificationSettingsRouter.test.ts index b57d799..c22e45b 100644 --- a/src/routes/v1/notificationSettingsRouter.test.ts +++ b/src/routes/v1/notificationSettingsRouter.test.ts @@ -1,251 +1,240 @@ -import { assert } from 'chai'; +import {assert} from 'chai'; import { - generateRandomEthereumAddress, - serverUrl, + generateRandomEthereumAddress, + serverUrl, } from '../../../test/testUtils'; -import { createNewUserAddressIfNotExists } from '../../repositories/userAddressRepository'; +import {createNewUserAddressIfNotExists} from '../../repositories/userAddressRepository'; import Axios from 'axios'; import jwt from 'jsonwebtoken'; import { - NotificationSetting, - NOTIFICATION_CATEGORY_GROUPS, + NotificationSetting, + NOTIFICATION_CATEGORY_GROUPS, } from '../../entities/notificationSetting'; -import { NOTIFICATION_CATEGORY } from '../../types/general'; -import { not } from 'joi'; +import {NOTIFICATION_CATEGORY} from '../../types/general'; +import {not} from 'joi'; const apiBaseUrl = serverUrl; describe( - '/notification_settings GET test cases', - getNotificationSettingsTestCases, + '/notification_settings GET test cases', + getNotificationSettingsTestCases, ); describe( - '/notification_settings/:id PUT test cases', - updateNotificationsTestCases, + '/notification_settings/:id PUT test cases', + updateNotificationsTestCases, ); describe( - '/notification_settings PUT test cases', - updateMultipleNotificationsTestCases, + '/notification_settings PUT test cases', + updateMultipleNotificationsTestCases, ); const walletAddress = generateRandomEthereumAddress().toLowerCase(); const walletAddress2 = generateRandomEthereumAddress().toLowerCase(); function getNotificationSettingsTestCases() { - it('should return success response', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const jwtToken = jwt.sign({ publicAddress: walletAddress }, 'xxxx'); - const result = await Axios.get(`${apiBaseUrl}/v1/notification_settings`, { - headers: { Authorization: `Bearer ${jwtToken}` }, + it('should return success response', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const jwtToken = jwt.sign({publicAddress: walletAddress}, 'xxxx'); + const result = await Axios.get(`${apiBaseUrl}/v1/notification_settings`, { + headers: {Authorization: `Bearer ${jwtToken}`}, + }); + const notifications = result.data.notificationSettings; + assert.isOk(notifications); + assert.isTrue(notifications[0].userAddressId === userAddress.id); + }); + it('should return addresses filtered by category', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const jwtToken = jwt.sign({publicAddress: walletAddress}, 'xxxx'); + const category = NOTIFICATION_CATEGORY.PROJECT_RELATED; + const result = await Axios.get( + `${apiBaseUrl}/v1/notification_settings?limit=10&category=${category}`, + { + headers: {Authorization: `Bearer ${jwtToken}`}, + }, + ); + const notifications = result.data.notificationSettings; + assert.isOk(notifications); + assert.isTrue(notifications[0]?.userAddressId === userAddress.id); + assert.isTrue(notifications[0]?.notificationType?.category === category); + assert.isTrue(notifications[0]?.notificationType?.showOnSettingPage); }); - const notifications = result.data.notificationSettings; - assert.isOk(notifications); - assert.isTrue(notifications[0].userAddressId === userAddress.id); - }); - it('should return addresses filtered by category', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const jwtToken = jwt.sign({ publicAddress: walletAddress }, 'xxxx'); - const category = NOTIFICATION_CATEGORY.PROJECT_RELATED; - const result = await Axios.get( - `${apiBaseUrl}/v1/notification_settings?limit=10&category=${category}`, - { - headers: { Authorization: `Bearer ${jwtToken}` }, - }, - ); - const notifications = result.data.notificationSettings; - assert.isOk(notifications); - assert.isTrue(notifications[0]?.userAddressId === userAddress.id); - assert.isTrue(notifications[0]?.notificationType?.category === category); - assert.isTrue(notifications[0]?.notificationType?.showOnSettingPage); - }); } function updateNotificationsTestCases() { - it('should update notification setting', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const notificationSetting = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :id', { id: userAddress.id }) - .andWhere('notificationType.isEmailEditable = true') - .andWhere('notificationType.isWebEditable = true') - .getOne(); - const jwtToken = jwt.sign({ publicAddress: walletAddress }, 'xxxx'); - const result = await Axios.put( - `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, - { - id: notificationSetting!.id, - allowEmailNotification: false, - allowDappPushNotification: false, - }, - { headers: { Authorization: `Bearer ${jwtToken}` } }, - ); - - const updatedNotification = result.data; - assert.isOk(result); - - assert.isFalse(updatedNotification.allowEmailNotification); - assert.isFalse(updatedNotification.allowDappPushNotification); - //validate child notifications of the group are updated - const updatedChildSettings = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :id', { id: userAddress.id }) - .andWhere( - 'notificationType.isGroupParent = false AND notificationType.categoryGroup = :categoryGroup', - { categoryGroup: NOTIFICATION_CATEGORY_GROUPS.GIVPOWER_ALLOCATIONS }, - ) - .getMany(); - - updatedChildSettings.forEach(setting => { - assert.isTrue(setting.allowNotifications); - assert.isTrue(setting.allowEmailNotification); - assert.isTrue(setting.allowDappPushNotification); + it('should update notification setting', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const notificationSetting = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :id', {id: userAddress.id}) + .andWhere('notificationType.isEmailEditable = true') + .andWhere('notificationType.isWebEditable = true') + .andWhere('notificationType.isGroupParent = true') + .getOne(); + const jwtToken = jwt.sign({publicAddress: walletAddress}, 'xxxx'); + const result = await Axios.put( + `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, + { + id: notificationSetting!.id, + allowEmailNotification: false, + allowDappPushNotification: false, + }, + {headers: {Authorization: `Bearer ${jwtToken}`}}, + ); + + const updatedNotification = result.data; + assert.isOk(result); + + assert.isFalse(updatedNotification.allowEmailNotification); + assert.isFalse(updatedNotification.allowDappPushNotification); + //validate child notifications of the group are updated + const updatedChildSettings = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :id', {id: userAddress.id}) + .andWhere( + 'notificationType.isGroupParent = false AND notificationType.categoryGroup = :categoryGroup', + {categoryGroup: notificationSetting?.notificationType?.categoryGroup}, + ) + .getMany(); + + updatedChildSettings.forEach(setting => { + assert.isTrue(setting.allowNotifications); + assert.isFalse(setting.allowEmailNotification); + assert.isFalse(setting.allowDappPushNotification); + }); + }); + it('should update notification setting, when isEmailEditable is false should not change email setting', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const notificationSetting = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :id', {id: userAddress.id}) + .andWhere('notificationType.isEmailEditable = false') + .andWhere('notificationSetting.allowEmailNotification = false') + .getOne(); + const jwtToken = jwt.sign({publicAddress: walletAddress}, 'xxxx'); + const result = await Axios.put( + `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, + { + id: notificationSetting!.id, + allowEmailNotification: true, + allowDappPushNotification: false, + }, + {headers: {Authorization: `Bearer ${jwtToken}`}}, + ); + + const updatedNotification = result.data; + assert.isOk(result); + assert.isFalse(updatedNotification.allowEmailNotification); + }); + it('should update notification setting, when isWebEditable is false should not change dapp push notification setting', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const notificationSetting = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :id', {id: userAddress.id}) + .andWhere('notificationType.isWebEditable = false') + .andWhere('notificationSetting.allowDappPushNotification = true') + .getOne(); + const jwtToken = jwt.sign({publicAddress: walletAddress}, 'xxxx'); + const result = await Axios.put( + `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, + { + id: notificationSetting!.id, + allowEmailNotification: false, + allowDappPushNotification: false, + }, + {headers: {Authorization: `Bearer ${jwtToken}`}}, + ); + + const updatedNotification = result.data; + assert.isOk(result); + + assert.isTrue(updatedNotification.allowDappPushNotification); }); - }); - it('should update notification setting, when isEmailEditable is false should not change email setting', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const notificationSetting = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :id', { id: userAddress.id }) - .andWhere('notificationType.isEmailEditable = false') - .andWhere('notificationSetting.allowDappPushNotification = true') - .getOne(); - const jwtToken = jwt.sign({ publicAddress: walletAddress }, 'xxxx'); - const result = await Axios.put( - `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, - { - id: notificationSetting!.id, - allowEmailNotification: false, - allowDappPushNotification: false, - }, - { headers: { Authorization: `Bearer ${jwtToken}` } }, - ); - - const updatedNotification = result.data; - assert.isOk(result); - - assert.isTrue(updatedNotification.allowEmailNotification); - }); - it('should update notification setting, when isWebEditable is false should not change dapp push notification setting', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const notificationSetting = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :id', { id: userAddress.id }) - .andWhere('notificationType.isWebEditable = false') - .andWhere('notificationSetting.allowDappPushNotification = true') - .getOne(); - const jwtToken = jwt.sign({ publicAddress: walletAddress }, 'xxxx'); - const result = await Axios.put( - `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, - { - id: notificationSetting!.id, - allowEmailNotification: false, - allowDappPushNotification: false, - }, - { headers: { Authorization: `Bearer ${jwtToken}` } }, - ); - - const updatedNotification = result.data; - assert.isOk(result); - - assert.isTrue(updatedNotification.allowDappPushNotification); - }); } function updateMultipleNotificationsTestCases() { - it('should update notification settings', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress2); - const notificationSettings = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :id', { id: userAddress.id }) - .andWhere('notificationType.isEmailEditable = true') - .andWhere('notificationType.isWebEditable = true') - .take(2) - .getMany(); - - const jwtToken = jwt.sign({ publicAddress: walletAddress2 }, 'xxxx'); - const result = await Axios.put( - `${apiBaseUrl}/v1/notification_settings`, - { - settings: notificationSettings.map(setting => { - return { - id: setting!.id, - allowEmailNotification: false, - allowDappPushNotification: false, - }; - }), - }, - { headers: { Authorization: `Bearer ${jwtToken}` } }, - ); - - const updatedNotifications: any[] = Object.values(result.data); - assert.isOk(result); - // didnt update this value so it remains true - assert.isTrue(updatedNotifications[0].allowNotifications); - assert.isTrue(updatedNotifications[1].allowNotifications); - - const updatedNotification1 = updatedNotifications.find((setting: any) => { - return setting.id === notificationSettings[0].id; + it('should update notification settings', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress2); + const notificationSettings = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :id', {id: userAddress.id}) + .andWhere('notificationType.isGroupParent = true') + .andWhere('notificationType.isEmailEditable = true') + .andWhere('notificationType.isWebEditable = true') + // .andWhere('notificationSetting.allowEmailNotification = true') + // .andWhere('notificationSetting.allowDappPushNotification = true') + .take(2) + .getMany(); + assert.equal(notificationSettings.length, 2) + + const jwtToken = jwt.sign({publicAddress: walletAddress2}, 'xxxx'); + const result = await Axios.put( + `${apiBaseUrl}/v1/notification_settings`, + { + settings: notificationSettings.map(setting => { + return { + id: setting!.id, + allowEmailNotification: !setting.allowEmailNotification, + allowDappPushNotification: !setting.allowDappPushNotification, + }; + }), + }, + {headers: {Authorization: `Bearer ${jwtToken}`}}, + ); + + const updatedNotifications: any[] = Object.values(result.data); + assert.isOk(result); + + const updatedNotification1 = updatedNotifications.find((setting: any) => { + return setting.id === notificationSettings[0].id; + }); + + const updatedNotification2 = updatedNotifications.find((setting: any) => { + return setting.id === notificationSettings[1].id; + }); + + // notification 1 + assert.isTrue( + updatedNotification1.allowEmailNotification !== + notificationSettings[0]?.allowEmailNotification, + ); + assert.isTrue( + updatedNotification1.allowDappPushNotification !== + notificationSettings[0]?.allowDappPushNotification, + ); + + // notification 2 + assert.isTrue( + updatedNotification2.allowEmailNotification !== + notificationSettings[1]?.allowEmailNotification, + ); + assert.isTrue( + updatedNotification2.allowDappPushNotification !== + notificationSettings[1]?.allowDappPushNotification, + ); }); - - const updatedNotification2 = updatedNotifications.find((setting: any) => { - return setting.id === notificationSettings[1].id; - }); - - // notification 1 - assert.isTrue( - updatedNotification1.allowNotifications === - notificationSettings[0]?.allowNotifications, - ); - assert.isFalse(updatedNotification1.allowEmailNotification); - assert.isTrue( - updatedNotification1.allowEmailNotification !== - notificationSettings[0]?.allowEmailNotification, - ); - assert.isFalse(updatedNotification1.allowDappPushNotification); - assert.isTrue( - updatedNotification1.allowDappPushNotification !== - notificationSettings[0]?.allowDappPushNotification, - ); - - // notification 2 - assert.isTrue( - updatedNotification2.allowNotifications === - notificationSettings[1]?.allowNotifications, - ); - assert.isFalse(updatedNotification2.allowEmailNotification); - assert.isTrue( - updatedNotification2.allowEmailNotification !== - notificationSettings[1]?.allowEmailNotification, - ); - assert.isFalse(updatedNotification2.allowDappPushNotification); - assert.isTrue( - updatedNotification2.allowDappPushNotification !== - notificationSettings[1]?.allowDappPushNotification, - ); - }); } From 6931596d4aad0a9201785c7b362d6dbe416de4f8 Mon Sep 17 00:00:00 2001 From: Mohammad Ranjbar Z Date: Tue, 21 Feb 2023 11:49:56 +0330 Subject: [PATCH 3/5] 2.0.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3c91678..3f91a1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "notification-venter", - "version": "2.0.0", + "version": "2.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "notification-venter", - "version": "2.0.0", + "version": "2.0.1", "license": "ISC", "dependencies": { "@adminjs/express": "4.1.0", diff --git a/package.json b/package.json index 62fddca..297135f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "notification-venter", - "version": "2.0.0", + "version": "2.0.1", "description": "", "main": "index.js", "scripts": { From 161d20143de50187603f702846dc40c0099a4436 Mon Sep 17 00:00:00 2001 From: Mohammad Ranjbar Z Date: Sun, 26 Feb 2023 09:53:23 +0330 Subject: [PATCH 4/5] Run prettier --- .../notificationSettingRepository.test.ts | 338 +++++++------- .../notificationSettingRepository.ts | 313 ++++++------- .../notificationTypeRepository.ts | 36 +- .../v1/notificationSettingsRouter.test.ts | 420 +++++++++--------- 4 files changed, 556 insertions(+), 551 deletions(-) diff --git a/src/repositories/notificationSettingRepository.test.ts b/src/repositories/notificationSettingRepository.test.ts index 4f1e2f1..c8ad092 100644 --- a/src/repositories/notificationSettingRepository.test.ts +++ b/src/repositories/notificationSettingRepository.test.ts @@ -1,196 +1,196 @@ -import {assert} from 'chai'; -import {generateRandomEthereumAddress} from '../../test/testUtils'; -import {NotificationSetting} from '../entities/notificationSetting'; +import { assert } from 'chai'; +import { generateRandomEthereumAddress } from '../../test/testUtils'; +import { NotificationSetting } from '../entities/notificationSetting'; import { - findNotificationSettingByNotificationTypeAndUserAddress, - getUserNotificationSettings, - updateUserNotificationSetting, + findNotificationSettingByNotificationTypeAndUserAddress, + getUserNotificationSettings, + updateUserNotificationSetting, } from './notificationSettingRepository'; -import {createNewUserAddressIfNotExists} from './userAddressRepository'; -import {getNotificationTypeByEventName} from './notificationTypeRepository'; -import {SegmentEvents} from '../services/segment/segmentAnalyticsSingleton'; +import { createNewUserAddressIfNotExists } from './userAddressRepository'; +import { getNotificationTypeByEventName } from './notificationTypeRepository'; +import { SegmentEvents } from '../services/segment/segmentAnalyticsSingleton'; // createNotificationSettingsForNewUser tested in userRepository describe( - 'getUserNotificationSettings() test cases', - getUserNotificationSettingsTestCases, + 'getUserNotificationSettings() test cases', + getUserNotificationSettingsTestCases, ); describe( - 'updateUserNotificationSetting() test cases', - updateUserNotificationSettingTestCases, + 'updateUserNotificationSetting() test cases', + updateUserNotificationSettingTestCases, ); describe( - 'findNotificationSettingByNotificationTypeAndUserAddress() test cases', - findNotificationSettingByNotificationTypeAndUserAddressTestCases, + 'findNotificationSettingByNotificationTypeAndUserAddress() test cases', + findNotificationSettingByNotificationTypeAndUserAddressTestCases, ); const walletAddress = generateRandomEthereumAddress(); function getUserNotificationSettingsTestCases() { - it('return notification settings by user and take and skip', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const take = 50; - const skip = 0; - - const [notificationSettings] = await getUserNotificationSettings( - take, - skip, - userAddress.id, - ); - - assert.isOk(notificationSettings); - notificationSettings.forEach(setting => { - assert.isTrue(setting!.userAddressId === userAddress.id); - assert.isTrue(setting?.notificationType?.showOnSettingPage); - }); + it('return notification settings by user and take and skip', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const take = 50; + const skip = 0; + + const [notificationSettings] = await getUserNotificationSettings( + take, + skip, + userAddress.id, + ); + + assert.isOk(notificationSettings); + notificationSettings.forEach(setting => { + assert.isTrue(setting!.userAddressId === userAddress.id); + assert.isTrue(setting?.notificationType?.showOnSettingPage); }); - it('return notification settings order by notificationTypeId', async () => { - const userAddress = await createNewUserAddressIfNotExists( - generateRandomEthereumAddress(), - ); - - const [notificationSettings] = await getUserNotificationSettings( - 100, - 0, - userAddress.id, - ); - - assert.isOk(notificationSettings); - notificationSettings.forEach(setting => { - assert.isTrue(setting!.userAddressId === userAddress.id); - assert.isTrue(setting?.notificationType?.showOnSettingPage); - }); - - for (let i = 1; i < notificationSettings.length; i++) { - assert.isTrue( - notificationSettings[i]?.notificationTypeId > - notificationSettings[i - 1]?.notificationTypeId, - ); - } + }); + it('return notification settings order by notificationTypeId', async () => { + const userAddress = await createNewUserAddressIfNotExists( + generateRandomEthereumAddress(), + ); + + const [notificationSettings] = await getUserNotificationSettings( + 100, + 0, + userAddress.id, + ); + + assert.isOk(notificationSettings); + notificationSettings.forEach(setting => { + assert.isTrue(setting!.userAddressId === userAddress.id); + assert.isTrue(setting?.notificationType?.showOnSettingPage); }); + + for (let i = 1; i < notificationSettings.length; i++) { + assert.isTrue( + notificationSettings[i]?.notificationTypeId > + notificationSettings[i - 1]?.notificationTypeId, + ); + } + }); } function findNotificationSettingByNotificationTypeAndUserAddressTestCases() { - it('return notification settings for userAddress and notificationType', async () => { - const address = generateRandomEthereumAddress(); - const userAddress = await createNewUserAddressIfNotExists(address); - const notificationType = await getNotificationTypeByEventName( - SegmentEvents.PROJECT_LISTED, - ); - const notificationSettings = - await findNotificationSettingByNotificationTypeAndUserAddress({ - userAddressId: userAddress.id, - notificationTypeId: notificationType?.id as number, - }); - - assert.isOk(notificationSettings); - assert.equal( - notificationSettings?.notificationTypeId, - notificationType?.id, - ); - assert.equal(notificationSettings?.userAddressId, userAddress?.id); - }); - it('return null for invalid notificationType', async () => { - const address = generateRandomEthereumAddress(); - const userAddress = await createNewUserAddressIfNotExists(address); - const notificationSettings = - await findNotificationSettingByNotificationTypeAndUserAddress({ - userAddressId: userAddress.id, - notificationTypeId: 999999, - }); - - assert.isNull(notificationSettings); - }); - - it('return null for invalid notificationAddress', async () => { - const notificationType = await getNotificationTypeByEventName( - SegmentEvents.PROJECT_LISTED, - ); - const notificationSettings = - await findNotificationSettingByNotificationTypeAndUserAddress({ - userAddressId: 99999, - notificationTypeId: notificationType?.id as number, - }); - assert.isNull(notificationSettings); - }); + it('return notification settings for userAddress and notificationType', async () => { + const address = generateRandomEthereumAddress(); + const userAddress = await createNewUserAddressIfNotExists(address); + const notificationType = await getNotificationTypeByEventName( + SegmentEvents.PROJECT_LISTED, + ); + const notificationSettings = + await findNotificationSettingByNotificationTypeAndUserAddress({ + userAddressId: userAddress.id, + notificationTypeId: notificationType?.id as number, + }); + + assert.isOk(notificationSettings); + assert.equal( + notificationSettings?.notificationTypeId, + notificationType?.id, + ); + assert.equal(notificationSettings?.userAddressId, userAddress?.id); + }); + it('return null for invalid notificationType', async () => { + const address = generateRandomEthereumAddress(); + const userAddress = await createNewUserAddressIfNotExists(address); + const notificationSettings = + await findNotificationSettingByNotificationTypeAndUserAddress({ + userAddressId: userAddress.id, + notificationTypeId: 999999, + }); + + assert.isNull(notificationSettings); + }); + + it('return null for invalid notificationAddress', async () => { + const notificationType = await getNotificationTypeByEventName( + SegmentEvents.PROJECT_LISTED, + ); + const notificationSettings = + await findNotificationSettingByNotificationTypeAndUserAddress({ + userAddressId: 99999, + notificationTypeId: notificationType?.id as number, + }); + assert.isNull(notificationSettings); + }); } function updateUserNotificationSettingTestCases() { - it('update user notification settings', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - - const userNotificationSetting = - await NotificationSetting.createQueryBuilder('setting') - .leftJoinAndSelect('setting.notificationType', 'notificationType') - .where('setting."userAddressId" = :userAddressId', { - userAddressId: userAddress.id, - }) - .andWhere('notificationType.isGroupParent = false') - .andWhere('notificationType.isEmailEditable = true') - .andWhere('notificationType.isWebEditable = true') - .getOne(); - - assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); - - const updatedSetting = await updateUserNotificationSetting({ - notificationSettingId: userNotificationSetting!.id, - userAddressId: userAddress.id, - allowEmailNotification: false, - allowDappPushNotification: false, - }); - assert.isOk(updatedSetting); - assert.isFalse(updatedSetting?.allowEmailNotification); - assert.isFalse(updatedSetting?.allowDappPushNotification); + it('update user notification settings', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + + const userNotificationSetting = + await NotificationSetting.createQueryBuilder('setting') + .leftJoinAndSelect('setting.notificationType', 'notificationType') + .where('setting."userAddressId" = :userAddressId', { + userAddressId: userAddress.id, + }) + .andWhere('notificationType.isGroupParent = false') + .andWhere('notificationType.isEmailEditable = true') + .andWhere('notificationType.isWebEditable = true') + .getOne(); + + assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); + + const updatedSetting = await updateUserNotificationSetting({ + notificationSettingId: userNotificationSetting!.id, + userAddressId: userAddress.id, + allowEmailNotification: false, + allowDappPushNotification: false, }); - it('update user notification settings, cant change when isEmailEditable is false', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - - const userNotificationSetting = - await NotificationSetting.createQueryBuilder('setting') - .leftJoinAndSelect('setting.notificationType', 'notificationType') - .where('setting."userAddressId" = :userAddressId', { - userAddressId: userAddress.id, - }) - .andWhere('notificationType.isGroupParent = true') - .andWhere('notificationType.isEmailEditable = false') - .andWhere('setting.allowEmailNotification = false') - .andWhere('notificationType.isWebEditable = true') - .getOne(); - - assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); - - const updatedSetting = await updateUserNotificationSetting({ - notificationSettingId: userNotificationSetting!.id, - userAddressId: userAddress.id, - allowEmailNotification: true, - allowDappPushNotification: false, - }); - assert.isOk(updatedSetting); - assert.isFalse(updatedSetting?.allowEmailNotification); - assert.isFalse(updatedSetting?.allowDappPushNotification); + assert.isOk(updatedSetting); + assert.isFalse(updatedSetting?.allowEmailNotification); + assert.isFalse(updatedSetting?.allowDappPushNotification); + }); + it('update user notification settings, cant change when isEmailEditable is false', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + + const userNotificationSetting = + await NotificationSetting.createQueryBuilder('setting') + .leftJoinAndSelect('setting.notificationType', 'notificationType') + .where('setting."userAddressId" = :userAddressId', { + userAddressId: userAddress.id, + }) + .andWhere('notificationType.isGroupParent = true') + .andWhere('notificationType.isEmailEditable = false') + .andWhere('setting.allowEmailNotification = false') + .andWhere('notificationType.isWebEditable = true') + .getOne(); + + assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); + + const updatedSetting = await updateUserNotificationSetting({ + notificationSettingId: userNotificationSetting!.id, + userAddressId: userAddress.id, + allowEmailNotification: true, + allowDappPushNotification: false, }); - it('update user notification settings, cant change when isWebEditable is false', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - - const userNotificationSetting = - await NotificationSetting.createQueryBuilder('setting') - .leftJoinAndSelect('setting.notificationType', 'notificationType') - .where('setting."userAddressId" = :userAddressId', { - userAddressId: userAddress.id, - }) - .andWhere('notificationType.isWebEditable = false') - .getOne(); - - assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); - - const updatedSetting = await updateUserNotificationSetting({ - notificationSettingId: userNotificationSetting!.id, - userAddressId: userAddress.id, - allowEmailNotification: false, - allowDappPushNotification: false, - }); - assert.isOk(updatedSetting); - assert.isTrue(updatedSetting?.allowDappPushNotification); + assert.isOk(updatedSetting); + assert.isFalse(updatedSetting?.allowEmailNotification); + assert.isFalse(updatedSetting?.allowDappPushNotification); + }); + it('update user notification settings, cant change when isWebEditable is false', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + + const userNotificationSetting = + await NotificationSetting.createQueryBuilder('setting') + .leftJoinAndSelect('setting.notificationType', 'notificationType') + .where('setting."userAddressId" = :userAddressId', { + userAddressId: userAddress.id, + }) + .andWhere('notificationType.isWebEditable = false') + .getOne(); + + assert.isTrue(userNotificationSetting?.userAddressId === userAddress.id); + + const updatedSetting = await updateUserNotificationSetting({ + notificationSettingId: userNotificationSetting!.id, + userAddressId: userAddress.id, + allowEmailNotification: false, + allowDappPushNotification: false, }); + assert.isOk(updatedSetting); + assert.isTrue(updatedSetting?.allowDappPushNotification); + }); } diff --git a/src/repositories/notificationSettingRepository.ts b/src/repositories/notificationSettingRepository.ts index 53d5e18..20ce266 100644 --- a/src/repositories/notificationSettingRepository.ts +++ b/src/repositories/notificationSettingRepository.ts @@ -1,188 +1,193 @@ -import {UserAddress} from '../entities/userAddress'; -import {NotificationType} from '../entities/notificationType'; -import {NotificationSetting} from '../entities/notificationSetting'; -import {errorMessages} from '../utils/errorMessages'; -import {createQueryBuilder} from 'typeorm'; -import {logger} from '../utils/logger'; -import {StandardError} from '../types/StandardError'; -import {findNotificationTypeParent} from "./notificationTypeRepository"; +import { UserAddress } from '../entities/userAddress'; +import { NotificationType } from '../entities/notificationType'; +import { NotificationSetting } from '../entities/notificationSetting'; +import { errorMessages } from '../utils/errorMessages'; +import { createQueryBuilder } from 'typeorm'; +import { logger } from '../utils/logger'; +import { StandardError } from '../types/StandardError'; +import { findNotificationTypeParent } from './notificationTypeRepository'; export const createNotificationSettingsForNewUser = async ( - user: UserAddress, + user: UserAddress, ) => { - const notificationTypes = await NotificationType.find(); - // rest of values are set by default - const notificationTypeSettings = [] - for (const notificationType of notificationTypes) { - const notificationParent = notificationType?.isGroupParent ? - notificationType : - await findNotificationTypeParent(notificationType.categoryGroup as string) - const payload: Partial = { - notificationType: notificationType, - userAddress: user, - allowEmailNotification: notificationParent?.emailDefaultValue !== undefined ? notificationParent?.emailDefaultValue : true, - allowDappPushNotification: - notificationParent?.webDefaultValue !== undefined - ? notificationParent?.webDefaultValue - : true, - }; + const notificationTypes = await NotificationType.find(); + // rest of values are set by default + const notificationTypeSettings = []; + for (const notificationType of notificationTypes) { + const notificationParent = notificationType?.isGroupParent + ? notificationType + : await findNotificationTypeParent( + notificationType.categoryGroup as string, + ); + const payload: Partial = { + notificationType: notificationType, + userAddress: user, + allowEmailNotification: + notificationParent?.emailDefaultValue !== undefined + ? notificationParent?.emailDefaultValue + : true, + allowDappPushNotification: + notificationParent?.webDefaultValue !== undefined + ? notificationParent?.webDefaultValue + : true, + }; - notificationTypeSettings.push(payload); - } + notificationTypeSettings.push(payload); + } - const userSettings = NotificationSetting.create(notificationTypeSettings); + const userSettings = NotificationSetting.create(notificationTypeSettings); - return await NotificationSetting.save(userSettings); + return await NotificationSetting.save(userSettings); }; export const getUserNotificationSettings = async ( - take: number, - skip: number, - userAddressId: number, - category?: string, + take: number, + skip: number, + userAddressId: number, + category?: string, ) => { - let query = NotificationSetting.createQueryBuilder('notificationSetting') - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :userAddressId', { - userAddressId: userAddressId, - }) - .andWhere('notificationType.showOnSettingPage = true'); + let query = NotificationSetting.createQueryBuilder('notificationSetting') + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :userAddressId', { + userAddressId: userAddressId, + }) + .andWhere('notificationType.showOnSettingPage = true'); - if (category) { - query = query.andWhere('notificationType.category = :category', { - category: category, - }); - } - query.orderBy('notificationType.id', 'ASC'); - return query.take(take).skip(skip).getManyAndCount(); + if (category) { + query = query.andWhere('notificationType.category = :category', { + category: category, + }); + } + query.orderBy('notificationType.id', 'ASC'); + return query.take(take).skip(skip).getManyAndCount(); }; export const findNotificationSettingByNotificationTypeAndUserAddress = - async (params: { - notificationTypeId: number; - userAddressId: number; - }): Promise => { - const {notificationTypeId, userAddressId} = params; - try { - return await NotificationSetting.createQueryBuilder('notificationSetting') - .where('notificationSetting.userAddressId = :userAddressId', { - userAddressId, - }) - .andWhere( - 'notificationSetting.notificationTypeId = :notificationTypeId', - { - notificationTypeId, - }, - ) - .getOne(); - } catch (e) { - logger.error( - 'findNotificationSettingByNotificationTypeAndUserAddress() error', - e, - ); - throw e; - } - }; - -export const findNotificationSettingById = async ( - id: number, -): Promise => { + async (params: { + notificationTypeId: number; + userAddressId: number; + }): Promise => { + const { notificationTypeId, userAddressId } = params; try { - return await NotificationSetting.createQueryBuilder('notificationSetting') - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.id = :id', { - id, - }) - .getOne(); + return await NotificationSetting.createQueryBuilder('notificationSetting') + .where('notificationSetting.userAddressId = :userAddressId', { + userAddressId, + }) + .andWhere( + 'notificationSetting.notificationTypeId = :notificationTypeId', + { + notificationTypeId, + }, + ) + .getOne(); } catch (e) { - logger.error( - 'findNotificationSettingByNotificationTypeAndUserAddress() error', - e, - ); - throw e; + logger.error( + 'findNotificationSettingByNotificationTypeAndUserAddress() error', + e, + ); + throw e; } + }; + +export const findNotificationSettingById = async ( + id: number, +): Promise => { + try { + return await NotificationSetting.createQueryBuilder('notificationSetting') + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.id = :id', { + id, + }) + .getOne(); + } catch (e) { + logger.error( + 'findNotificationSettingByNotificationTypeAndUserAddress() error', + e, + ); + throw e; + } }; export const updateUserNotificationSetting = async (params: { - notificationSettingId: number; - userAddressId: number; - allowEmailNotification: boolean; - allowDappPushNotification: boolean; + notificationSettingId: number; + userAddressId: number; + allowEmailNotification: boolean; + allowDappPushNotification: boolean; }): Promise => { - const notificationSetting = await NotificationSetting.createQueryBuilder( - 'notificationSetting', + const notificationSetting = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where( - 'notificationSetting.id = :id AND notificationSetting.userAddressId = :userAddressId', - { - id: params.notificationSettingId, - userAddressId: params.userAddressId, - }, - ) - .getOne(); + .where( + 'notificationSetting.id = :id AND notificationSetting.userAddressId = :userAddressId', + { + id: params.notificationSettingId, + userAddressId: params.userAddressId, + }, + ) + .getOne(); - if (!notificationSetting) { - throw new StandardError({ - message: errorMessages.NOTIFICATION_SETTING_NOT_FOUND, - httpStatusCode: 400, - }); - } - if (notificationSetting.notificationType?.isEmailEditable) { - notificationSetting.allowEmailNotification = params.allowEmailNotification; - } - if (notificationSetting.notificationType?.isWebEditable) { - notificationSetting.allowDappPushNotification = - params.allowDappPushNotification; - } + if (!notificationSetting) { + throw new StandardError({ + message: errorMessages.NOTIFICATION_SETTING_NOT_FOUND, + httpStatusCode: 400, + }); + } + if (notificationSetting.notificationType?.isEmailEditable) { + notificationSetting.allowEmailNotification = params.allowEmailNotification; + } + if (notificationSetting.notificationType?.isWebEditable) { + notificationSetting.allowDappPushNotification = + params.allowDappPushNotification; + } - if ( - notificationSetting?.notificationType?.isGroupParent && - notificationSetting?.notificationType?.categoryGroup - ) { - await updateChildNotificationSettings({ - categoryGroup: notificationSetting?.notificationType?.categoryGroup, - userAddressId: params.userAddressId, - allowEmailNotification: notificationSetting.allowEmailNotification, - allowDappPushNotification: notificationSetting.allowDappPushNotification, - }); - } - return notificationSetting.save(); + if ( + notificationSetting?.notificationType?.isGroupParent && + notificationSetting?.notificationType?.categoryGroup + ) { + await updateChildNotificationSettings({ + categoryGroup: notificationSetting?.notificationType?.categoryGroup, + userAddressId: params.userAddressId, + allowEmailNotification: notificationSetting.allowEmailNotification, + allowDappPushNotification: notificationSetting.allowDappPushNotification, + }); + } + return notificationSetting.save(); }; export const updateChildNotificationSettings = async (params: { - categoryGroup: string; - userAddressId: number; - allowEmailNotification: boolean; - allowDappPushNotification: boolean; + categoryGroup: string; + userAddressId: number; + allowEmailNotification: boolean; + allowDappPushNotification: boolean; }) => { - // Grab type ids - const notificationTypes = await NotificationType.createQueryBuilder( - 'notificationType', - ) - .select('notificationType.id') - .where('notificationType.categoryGroup = :categoryGroup', { - categoryGroup: params.categoryGroup, - }) - .andWhere('notificationType.isGroupParent = false') - .getMany(); + // Grab type ids + const notificationTypes = await NotificationType.createQueryBuilder( + 'notificationType', + ) + .select('notificationType.id') + .where('notificationType.categoryGroup = :categoryGroup', { + categoryGroup: params.categoryGroup, + }) + .andWhere('notificationType.isGroupParent = false') + .getMany(); - const notificationTypeIds = notificationTypes.map(notificationType => { - return notificationType.id; - }); + const notificationTypeIds = notificationTypes.map(notificationType => { + return notificationType.id; + }); - if (notificationTypeIds.length === 0) return; + if (notificationTypeIds.length === 0) return; - await NotificationSetting.query(` + await NotificationSetting.query(` UPDATE notification_setting SET "allowEmailNotification" = ${ params.allowEmailNotification diff --git a/src/repositories/notificationTypeRepository.ts b/src/repositories/notificationTypeRepository.ts index d55697d..4ff50cf 100644 --- a/src/repositories/notificationTypeRepository.ts +++ b/src/repositories/notificationTypeRepository.ts @@ -1,28 +1,28 @@ -import {NotificationType} from '../entities/notificationType'; +import { NotificationType } from '../entities/notificationType'; export const getNotificationTypeByEventName = async (eventName: string) => { - return NotificationType.createQueryBuilder() - .where('name = :name', {name: eventName}) - .getOne(); + return NotificationType.createQueryBuilder() + .where('name = :name', { name: eventName }) + .getOne(); }; export const findNotificationTypeParent = async (categoryGroup: string) => { - return NotificationType.createQueryBuilder() - .where('category = :category', { - category: categoryGroup, - }) - .andWhere('"isGroupParent" = true') - .getOne(); + return NotificationType.createQueryBuilder() + .where('category = :category', { + category: categoryGroup, + }) + .andWhere('"isGroupParent" = true') + .getOne(); }; export const getNotificationTypeByEventNameAndMicroservice = async (params: { - eventName: string; - microService: string; + eventName: string; + microService: string; }) => { - return NotificationType.createQueryBuilder() - .where('name = :name', {name: params.eventName}) - .andWhere('"microService" = :microService', { - microService: params.microService, - }) - .getOne(); + return NotificationType.createQueryBuilder() + .where('name = :name', { name: params.eventName }) + .andWhere('"microService" = :microService', { + microService: params.microService, + }) + .getOne(); }; diff --git a/src/routes/v1/notificationSettingsRouter.test.ts b/src/routes/v1/notificationSettingsRouter.test.ts index c22e45b..7b7a55a 100644 --- a/src/routes/v1/notificationSettingsRouter.test.ts +++ b/src/routes/v1/notificationSettingsRouter.test.ts @@ -1,240 +1,240 @@ -import {assert} from 'chai'; +import { assert } from 'chai'; import { - generateRandomEthereumAddress, - serverUrl, + generateRandomEthereumAddress, + serverUrl, } from '../../../test/testUtils'; -import {createNewUserAddressIfNotExists} from '../../repositories/userAddressRepository'; +import { createNewUserAddressIfNotExists } from '../../repositories/userAddressRepository'; import Axios from 'axios'; import jwt from 'jsonwebtoken'; import { - NotificationSetting, - NOTIFICATION_CATEGORY_GROUPS, + NotificationSetting, + NOTIFICATION_CATEGORY_GROUPS, } from '../../entities/notificationSetting'; -import {NOTIFICATION_CATEGORY} from '../../types/general'; -import {not} from 'joi'; +import { NOTIFICATION_CATEGORY } from '../../types/general'; +import { not } from 'joi'; const apiBaseUrl = serverUrl; describe( - '/notification_settings GET test cases', - getNotificationSettingsTestCases, + '/notification_settings GET test cases', + getNotificationSettingsTestCases, ); describe( - '/notification_settings/:id PUT test cases', - updateNotificationsTestCases, + '/notification_settings/:id PUT test cases', + updateNotificationsTestCases, ); describe( - '/notification_settings PUT test cases', - updateMultipleNotificationsTestCases, + '/notification_settings PUT test cases', + updateMultipleNotificationsTestCases, ); const walletAddress = generateRandomEthereumAddress().toLowerCase(); const walletAddress2 = generateRandomEthereumAddress().toLowerCase(); function getNotificationSettingsTestCases() { - it('should return success response', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const jwtToken = jwt.sign({publicAddress: walletAddress}, 'xxxx'); - const result = await Axios.get(`${apiBaseUrl}/v1/notification_settings`, { - headers: {Authorization: `Bearer ${jwtToken}`}, - }); - const notifications = result.data.notificationSettings; - assert.isOk(notifications); - assert.isTrue(notifications[0].userAddressId === userAddress.id); - }); - it('should return addresses filtered by category', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const jwtToken = jwt.sign({publicAddress: walletAddress}, 'xxxx'); - const category = NOTIFICATION_CATEGORY.PROJECT_RELATED; - const result = await Axios.get( - `${apiBaseUrl}/v1/notification_settings?limit=10&category=${category}`, - { - headers: {Authorization: `Bearer ${jwtToken}`}, - }, - ); - const notifications = result.data.notificationSettings; - assert.isOk(notifications); - assert.isTrue(notifications[0]?.userAddressId === userAddress.id); - assert.isTrue(notifications[0]?.notificationType?.category === category); - assert.isTrue(notifications[0]?.notificationType?.showOnSettingPage); + it('should return success response', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const jwtToken = jwt.sign({ publicAddress: walletAddress }, 'xxxx'); + const result = await Axios.get(`${apiBaseUrl}/v1/notification_settings`, { + headers: { Authorization: `Bearer ${jwtToken}` }, }); + const notifications = result.data.notificationSettings; + assert.isOk(notifications); + assert.isTrue(notifications[0].userAddressId === userAddress.id); + }); + it('should return addresses filtered by category', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const jwtToken = jwt.sign({ publicAddress: walletAddress }, 'xxxx'); + const category = NOTIFICATION_CATEGORY.PROJECT_RELATED; + const result = await Axios.get( + `${apiBaseUrl}/v1/notification_settings?limit=10&category=${category}`, + { + headers: { Authorization: `Bearer ${jwtToken}` }, + }, + ); + const notifications = result.data.notificationSettings; + assert.isOk(notifications); + assert.isTrue(notifications[0]?.userAddressId === userAddress.id); + assert.isTrue(notifications[0]?.notificationType?.category === category); + assert.isTrue(notifications[0]?.notificationType?.showOnSettingPage); + }); } function updateNotificationsTestCases() { - it('should update notification setting', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const notificationSetting = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :id', {id: userAddress.id}) - .andWhere('notificationType.isEmailEditable = true') - .andWhere('notificationType.isWebEditable = true') - .andWhere('notificationType.isGroupParent = true') - .getOne(); - const jwtToken = jwt.sign({publicAddress: walletAddress}, 'xxxx'); - const result = await Axios.put( - `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, - { - id: notificationSetting!.id, - allowEmailNotification: false, - allowDappPushNotification: false, - }, - {headers: {Authorization: `Bearer ${jwtToken}`}}, - ); - - const updatedNotification = result.data; - assert.isOk(result); - - assert.isFalse(updatedNotification.allowEmailNotification); - assert.isFalse(updatedNotification.allowDappPushNotification); - //validate child notifications of the group are updated - const updatedChildSettings = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :id', {id: userAddress.id}) - .andWhere( - 'notificationType.isGroupParent = false AND notificationType.categoryGroup = :categoryGroup', - {categoryGroup: notificationSetting?.notificationType?.categoryGroup}, - ) - .getMany(); - - updatedChildSettings.forEach(setting => { - assert.isTrue(setting.allowNotifications); - assert.isFalse(setting.allowEmailNotification); - assert.isFalse(setting.allowDappPushNotification); - }); - }); - it('should update notification setting, when isEmailEditable is false should not change email setting', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const notificationSetting = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :id', {id: userAddress.id}) - .andWhere('notificationType.isEmailEditable = false') - .andWhere('notificationSetting.allowEmailNotification = false') - .getOne(); - const jwtToken = jwt.sign({publicAddress: walletAddress}, 'xxxx'); - const result = await Axios.put( - `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, - { - id: notificationSetting!.id, - allowEmailNotification: true, - allowDappPushNotification: false, - }, - {headers: {Authorization: `Bearer ${jwtToken}`}}, - ); - - const updatedNotification = result.data; - assert.isOk(result); - assert.isFalse(updatedNotification.allowEmailNotification); - }); - it('should update notification setting, when isWebEditable is false should not change dapp push notification setting', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress); - const notificationSetting = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :id', {id: userAddress.id}) - .andWhere('notificationType.isWebEditable = false') - .andWhere('notificationSetting.allowDappPushNotification = true') - .getOne(); - const jwtToken = jwt.sign({publicAddress: walletAddress}, 'xxxx'); - const result = await Axios.put( - `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, - { - id: notificationSetting!.id, - allowEmailNotification: false, - allowDappPushNotification: false, - }, - {headers: {Authorization: `Bearer ${jwtToken}`}}, - ); - - const updatedNotification = result.data; - assert.isOk(result); - - assert.isTrue(updatedNotification.allowDappPushNotification); + it('should update notification setting', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const notificationSetting = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :id', { id: userAddress.id }) + .andWhere('notificationType.isEmailEditable = true') + .andWhere('notificationType.isWebEditable = true') + .andWhere('notificationType.isGroupParent = true') + .getOne(); + const jwtToken = jwt.sign({ publicAddress: walletAddress }, 'xxxx'); + const result = await Axios.put( + `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, + { + id: notificationSetting!.id, + allowEmailNotification: false, + allowDappPushNotification: false, + }, + { headers: { Authorization: `Bearer ${jwtToken}` } }, + ); + + const updatedNotification = result.data; + assert.isOk(result); + + assert.isFalse(updatedNotification.allowEmailNotification); + assert.isFalse(updatedNotification.allowDappPushNotification); + //validate child notifications of the group are updated + const updatedChildSettings = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :id', { id: userAddress.id }) + .andWhere( + 'notificationType.isGroupParent = false AND notificationType.categoryGroup = :categoryGroup', + { categoryGroup: notificationSetting?.notificationType?.categoryGroup }, + ) + .getMany(); + + updatedChildSettings.forEach(setting => { + assert.isTrue(setting.allowNotifications); + assert.isFalse(setting.allowEmailNotification); + assert.isFalse(setting.allowDappPushNotification); }); + }); + it('should update notification setting, when isEmailEditable is false should not change email setting', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const notificationSetting = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :id', { id: userAddress.id }) + .andWhere('notificationType.isEmailEditable = false') + .andWhere('notificationSetting.allowEmailNotification = false') + .getOne(); + const jwtToken = jwt.sign({ publicAddress: walletAddress }, 'xxxx'); + const result = await Axios.put( + `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, + { + id: notificationSetting!.id, + allowEmailNotification: true, + allowDappPushNotification: false, + }, + { headers: { Authorization: `Bearer ${jwtToken}` } }, + ); + + const updatedNotification = result.data; + assert.isOk(result); + assert.isFalse(updatedNotification.allowEmailNotification); + }); + it('should update notification setting, when isWebEditable is false should not change dapp push notification setting', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress); + const notificationSetting = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :id', { id: userAddress.id }) + .andWhere('notificationType.isWebEditable = false') + .andWhere('notificationSetting.allowDappPushNotification = true') + .getOne(); + const jwtToken = jwt.sign({ publicAddress: walletAddress }, 'xxxx'); + const result = await Axios.put( + `${apiBaseUrl}/v1/notification_settings/${notificationSetting?.id}`, + { + id: notificationSetting!.id, + allowEmailNotification: false, + allowDappPushNotification: false, + }, + { headers: { Authorization: `Bearer ${jwtToken}` } }, + ); + + const updatedNotification = result.data; + assert.isOk(result); + + assert.isTrue(updatedNotification.allowDappPushNotification); + }); } function updateMultipleNotificationsTestCases() { - it('should update notification settings', async () => { - const userAddress = await createNewUserAddressIfNotExists(walletAddress2); - const notificationSettings = await NotificationSetting.createQueryBuilder( - 'notificationSetting', - ) - .leftJoinAndSelect( - 'notificationSetting.notificationType', - 'notificationType', - ) - .where('notificationSetting.userAddressId = :id', {id: userAddress.id}) - .andWhere('notificationType.isGroupParent = true') - .andWhere('notificationType.isEmailEditable = true') - .andWhere('notificationType.isWebEditable = true') - // .andWhere('notificationSetting.allowEmailNotification = true') - // .andWhere('notificationSetting.allowDappPushNotification = true') - .take(2) - .getMany(); - assert.equal(notificationSettings.length, 2) - - const jwtToken = jwt.sign({publicAddress: walletAddress2}, 'xxxx'); - const result = await Axios.put( - `${apiBaseUrl}/v1/notification_settings`, - { - settings: notificationSettings.map(setting => { - return { - id: setting!.id, - allowEmailNotification: !setting.allowEmailNotification, - allowDappPushNotification: !setting.allowDappPushNotification, - }; - }), - }, - {headers: {Authorization: `Bearer ${jwtToken}`}}, - ); - - const updatedNotifications: any[] = Object.values(result.data); - assert.isOk(result); - - const updatedNotification1 = updatedNotifications.find((setting: any) => { - return setting.id === notificationSettings[0].id; - }); - - const updatedNotification2 = updatedNotifications.find((setting: any) => { - return setting.id === notificationSettings[1].id; - }); - - // notification 1 - assert.isTrue( - updatedNotification1.allowEmailNotification !== - notificationSettings[0]?.allowEmailNotification, - ); - assert.isTrue( - updatedNotification1.allowDappPushNotification !== - notificationSettings[0]?.allowDappPushNotification, - ); - - // notification 2 - assert.isTrue( - updatedNotification2.allowEmailNotification !== - notificationSettings[1]?.allowEmailNotification, - ); - assert.isTrue( - updatedNotification2.allowDappPushNotification !== - notificationSettings[1]?.allowDappPushNotification, - ); + it('should update notification settings', async () => { + const userAddress = await createNewUserAddressIfNotExists(walletAddress2); + const notificationSettings = await NotificationSetting.createQueryBuilder( + 'notificationSetting', + ) + .leftJoinAndSelect( + 'notificationSetting.notificationType', + 'notificationType', + ) + .where('notificationSetting.userAddressId = :id', { id: userAddress.id }) + .andWhere('notificationType.isGroupParent = true') + .andWhere('notificationType.isEmailEditable = true') + .andWhere('notificationType.isWebEditable = true') + // .andWhere('notificationSetting.allowEmailNotification = true') + // .andWhere('notificationSetting.allowDappPushNotification = true') + .take(2) + .getMany(); + assert.equal(notificationSettings.length, 2); + + const jwtToken = jwt.sign({ publicAddress: walletAddress2 }, 'xxxx'); + const result = await Axios.put( + `${apiBaseUrl}/v1/notification_settings`, + { + settings: notificationSettings.map(setting => { + return { + id: setting!.id, + allowEmailNotification: !setting.allowEmailNotification, + allowDappPushNotification: !setting.allowDappPushNotification, + }; + }), + }, + { headers: { Authorization: `Bearer ${jwtToken}` } }, + ); + + const updatedNotifications: any[] = Object.values(result.data); + assert.isOk(result); + + const updatedNotification1 = updatedNotifications.find((setting: any) => { + return setting.id === notificationSettings[0].id; }); + + const updatedNotification2 = updatedNotifications.find((setting: any) => { + return setting.id === notificationSettings[1].id; + }); + + // notification 1 + assert.isTrue( + updatedNotification1.allowEmailNotification !== + notificationSettings[0]?.allowEmailNotification, + ); + assert.isTrue( + updatedNotification1.allowDappPushNotification !== + notificationSettings[0]?.allowDappPushNotification, + ); + + // notification 2 + assert.isTrue( + updatedNotification2.allowEmailNotification !== + notificationSettings[1]?.allowEmailNotification, + ); + assert.isTrue( + updatedNotification2.allowDappPushNotification !== + notificationSettings[1]?.allowDappPushNotification, + ); + }); } From d02581d2cd25e9972073b8484b64a9d5e5c52c7f Mon Sep 17 00:00:00 2001 From: Mohammad Ranjbar Z Date: Sun, 26 Feb 2023 10:51:20 +0330 Subject: [PATCH 5/5] Fix default value of notification types --- migrations/1660716115917-seedNotificationType.ts | 11 +++++++++-- src/entities/notificationSetting.ts | 2 ++ src/repositories/notificationTypeRepository.ts | 4 ++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/migrations/1660716115917-seedNotificationType.ts b/migrations/1660716115917-seedNotificationType.ts index 8145d0b..fcc6978 100644 --- a/migrations/1660716115917-seedNotificationType.ts +++ b/migrations/1660716115917-seedNotificationType.ts @@ -759,6 +759,8 @@ export const GivethNotificationTypes = { title: 'GIVbacks', description: 'Notify me when my GIV from GIVbacks is ready to claim.', showOnSettingPage: true, + categoryGroup: NOTIFICATION_CATEGORY_GROUPS.GIVBACKS, + isGroupParent: true, emailDefaultValue: false, isEmailEditable: false, microService: MICRO_SERVICES.givEconomyNotificationMicroService, @@ -1184,6 +1186,8 @@ export const GivethNotificationTypes = { showOnSettingPage: true, emailDefaultValue: false, isEmailEditable: false, + isGroupParent: true, + categoryGroup: NOTIFICATION_CATEGORY_GROUPS.YOUR_PROJECT_UPDATE, microService: MICRO_SERVICES.givethio, category: NOTIFICATION_CATEGORY.PROJECT_RELATED, icon: '', @@ -1236,6 +1240,8 @@ export const GivethNotificationTypes = { showOnSettingPage: true, emailDefaultValue: false, isEmailEditable: false, + categoryGroup: NOTIFICATION_CATEGORY_GROUPS.PROJECT_LIKES, + isGroupParent: true, microService: MICRO_SERVICES.givethio, category: NOTIFICATION_CATEGORY.PROJECT_RELATED, icon: 'IconHeartFilled', @@ -1267,12 +1273,13 @@ export const GivethNotificationTypes = { showOnSettingPage: true, emailDefaultValue: false, isEmailEditable: false, + categoryGroup: + NOTIFICATION_CATEGORY_GROUPS.SUPPORTED_BY_YOU_PROJECT_HAS_NEW_UPDATE_GROUP, + isGroupParent: true, microService: MICRO_SERVICES.givethio, category: NOTIFICATION_CATEGORY.SUPPORTED_PROJECTS, icon: '', schemaValidator: SCHEMA_VALIDATORS_NAMES.PROJECT_UPDATED_ADDED_WHO_SUPPORTS, - categoryGroup: - NOTIFICATION_CATEGORY_GROUPS.SUPPORTED_BY_YOU_PROJECT_HAS_NEW_UPDATE_GROUP, emailNotifierService: THIRD_PARTY_EMAIL_SERVICES.SEGMENT, emailNotificationId: 'Project update added - Users who supported', pushNotifierService: null, diff --git a/src/entities/notificationSetting.ts b/src/entities/notificationSetting.ts index 6d67a9d..d471209 100644 --- a/src/entities/notificationSetting.ts +++ b/src/entities/notificationSetting.ts @@ -20,6 +20,8 @@ export const NOTIFICATION_CATEGORY_GROUPS = { 'supportedByYouProjectsStatusChange', SUPPORTED_BY_YOU_PROJECT_HAS_NEW_UPDATE_GROUP: 'supportedByYouProjectsHasNewUpdate', + YOUR_PROJECT_UPDATE: 'yourProjectUpdate', + PROJECT_LIKES: 'projectLikes', PROJECT_STATUS: 'projectStatus', DONATIONS_MADE: 'donationsMade', DONATIONS_RECEIVED: 'donationsReceived', diff --git a/src/repositories/notificationTypeRepository.ts b/src/repositories/notificationTypeRepository.ts index 4ff50cf..b13f7ea 100644 --- a/src/repositories/notificationTypeRepository.ts +++ b/src/repositories/notificationTypeRepository.ts @@ -8,8 +8,8 @@ export const getNotificationTypeByEventName = async (eventName: string) => { export const findNotificationTypeParent = async (categoryGroup: string) => { return NotificationType.createQueryBuilder() - .where('category = :category', { - category: categoryGroup, + .where('"categoryGroup" = :categoryGroup', { + categoryGroup, }) .andWhere('"isGroupParent" = true') .getOne();