From de366c2b01c07d71555966694b47e70eb5f3b23e Mon Sep 17 00:00:00 2001 From: f-w Date: Sat, 16 Nov 2024 10:15:13 -0800 Subject: [PATCH] changed base controller to common service --- .../notifications/notifications.controller.ts | 105 +++++++++++++----- src/api/notifications/notifications.module.ts | 5 - .../subscriptions/subscriptions.controller.ts | 80 +++++++++---- src/api/subscriptions/subscriptions.module.ts | 5 - src/app.module.ts | 2 + src/common/common.module.ts | 21 ++++ .../common.service.ts} | 22 ++-- test/cron.e2e-spec.ts | 6 +- test/notification.e2e-spec.ts | 44 ++++---- test/redis.e2e-spec.ts | 6 +- test/subscription.e2e-spec.ts | 30 ++--- test/test-helper.ts | 6 +- 12 files changed, 213 insertions(+), 119 deletions(-) create mode 100644 src/common/common.module.ts rename src/{api/common/base.controller.ts => common/common.service.ts} (95%) diff --git a/src/api/notifications/notifications.controller.ts b/src/api/notifications/notifications.controller.ts index 4e35cf988..00d89bf7b 100644 --- a/src/api/notifications/notifications.controller.ts +++ b/src/api/notifications/notifications.controller.ts @@ -51,10 +51,10 @@ import { AnyObject, FilterQuery } from 'mongoose'; import { Role } from 'src/auth/constants'; import { UserProfile } from 'src/auth/dto/user-profile.dto'; import { Roles } from 'src/auth/roles.decorator'; +import { CommonService } from 'src/common/common.service'; import { AppConfigService } from 'src/config/app-config.service'; import { promisify } from 'util'; import { BouncesService } from '../bounces/bounces.service'; -import { BaseController } from '../common/base.controller'; import { CountDto } from '../common/dto/count.dto'; import { FilterDto } from '../common/dto/filter.dto'; import { @@ -82,18 +82,40 @@ enum NotificationDispatchStatusField { }) @ApiTags('notification') @Roles(Role.Admin, Role.SuperAdmin, Role.AuthenticatedUser) -export class NotificationsController extends BaseController { +export class NotificationsController { + readonly appConfig; + readonly handleBounce; + readonly guaranteedBroadcastPushDispatchProcessing; + readonly broadcastSubscriberChunkSize; + readonly logSkippedBroadcastPushDispatches; + readonly inboundSmtpServerDomain; + readonly handleListUnsubscribeByEmail; + constructor( private readonly notificationsService: NotificationsService, private readonly subscriptionsService: SubscriptionsService, readonly appConfigService: AppConfigService, readonly configurationsService: ConfigurationsService, private readonly bouncesService: BouncesService, + private readonly commonService: CommonService, @Inject(REQUEST) private readonly req: Request & { user: UserProfile }, @Inject(getFlowProducerToken()) private readonly flowProducer: FlowProducer, ) { - super(appConfigService, configurationsService); + this.appConfig = appConfigService.get(); + this.handleBounce = this.appConfig.email?.bounce?.enabled; + this.guaranteedBroadcastPushDispatchProcessing = + this.appConfig.notification?.guaranteedBroadcastPushDispatchProcessing; const ft = this.appConfig.notification?.broadcastCustomFilterFunctions; + + this.broadcastSubscriberChunkSize = + this.appConfig.notification?.broadcastSubscriberChunkSize; + this.logSkippedBroadcastPushDispatches = + this.appConfig.notification?.logSkippedBroadcastPushDispatches; + this.inboundSmtpServerDomain = + this.appConfig.email.inboundSmtpServer?.domain; + this.handleListUnsubscribeByEmail = + this.appConfig.email?.listUnsubscribeByEmail?.enabled; + if (ft) { this.jmespathSearchOpts.functionTable = ft; } @@ -320,7 +342,6 @@ export class NotificationsController extends BaseController { return this.sendPushNotification(notification); } - handleBounce = this.appConfig.email?.bounce?.enabled; async updateBounces( userChannelIds: string[] | string, dataNotification: Notification, @@ -383,8 +404,6 @@ export class NotificationsController extends BaseController { } } - guaranteedBroadcastPushDispatchProcessing = - this.appConfig.notification?.guaranteedBroadcastPushDispatchProcessing; async notificationMsgCB(data, err: any, e: Subscription) { if (err) { return this.updateBroadcastPushNotificationStatus( @@ -456,14 +475,6 @@ export class NotificationsController extends BaseController { } } - broadcastSubscriberChunkSize = - this.appConfig.notification?.broadcastSubscriberChunkSize; - logSkippedBroadcastPushDispatches = - this.appConfig.notification?.logSkippedBroadcastPushDispatches; - inboundSmtpServerDomain = this.appConfig.email.inboundSmtpServer?.domain; - handleListUnsubscribeByEmail = - this.appConfig.email?.listUnsubscribeByEmail?.enabled; - async broadcastToSubscriberChunk(data, startIdx) { const subChunk = (data.dispatch.candidates as string[]).slice( startIdx, @@ -535,7 +546,12 @@ export class NotificationsController extends BaseController { } const textBody = data.message.textBody && - this.mailMerge(data.message.textBody, e, data, this.req); + this.commonService.mailMerge( + data.message.textBody, + e, + data, + this.req, + ); switch (e.channel) { case 'sms': try { @@ -544,7 +560,7 @@ export class NotificationsController extends BaseController { undefined, HttpStatus.INTERNAL_SERVER_ERROR, ); - await this.sendSMS(e.userChannelId, textBody, e); + await this.commonService.sendSMS(e.userChannelId, textBody, e); return await this.notificationMsgCB(data, null, e); } catch (ex) { return await this.notificationMsgCB(data, ex, e); @@ -553,11 +569,21 @@ export class NotificationsController extends BaseController { default: { const subject = data.message.subject && - this.mailMerge(data.message.subject, e, data, this.req); + this.commonService.mailMerge( + data.message.subject, + e, + data, + this.req, + ); const htmlBody = data.message.htmlBody && - this.mailMerge(data.message.htmlBody, e, data, this.req); - const unsubscriptUrl = this.mailMerge( + this.commonService.mailMerge( + data.message.htmlBody, + e, + data, + this.req, + ); + const unsubscriptUrl = this.commonService.mailMerge( '{unsubscription_url}', e, data, @@ -569,7 +595,7 @@ export class NotificationsController extends BaseController { this.inboundSmtpServerDomain ) { const unsubEmail = - this.mailMerge( + this.commonService.mailMerge( 'un-{subscription_id}-{unsubscription_code}@', e, data, @@ -589,7 +615,7 @@ export class NotificationsController extends BaseController { }, }; if (this.handleBounce && this.inboundSmtpServerDomain) { - const bounceEmail = this.mailMerge( + const bounceEmail = this.commonService.mailMerge( `bn-{subscription_id}-{unsubscription_code}@${this.inboundSmtpServerDomain}`, e, data, @@ -606,7 +632,7 @@ export class NotificationsController extends BaseController { undefined, HttpStatus.INTERNAL_SERVER_ERROR, ); - await this.sendEmail(mailOptions); + await this.commonService.sendEmail(mailOptions); return await this.notificationMsgCB(data, null, e); } catch (ex) { return await this.notificationMsgCB(data, ex, e); @@ -624,19 +650,38 @@ export class NotificationsController extends BaseController { this.req['NotifyBC.subscription'] ?? {}; const textBody = data.message.textBody && - this.mailMerge(data.message.textBody, sub, data, this.req); + this.commonService.mailMerge( + data.message.textBody, + sub, + data, + this.req, + ); switch (data.channel) { case 'sms': - await this.sendSMS(data.userChannelId as string, textBody, sub); + await this.commonService.sendSMS( + data.userChannelId as string, + textBody, + sub, + ); return; default: { const htmlBody = data.message.htmlBody && - this.mailMerge(data.message.htmlBody, sub, data, this.req); + this.commonService.mailMerge( + data.message.htmlBody, + sub, + data, + this.req, + ); const subject = data.message.subject && - this.mailMerge(data.message.subject, sub, data, this.req); - const unsubscriptUrl = this.mailMerge( + this.commonService.mailMerge( + data.message.subject, + sub, + data, + this.req, + ); + const unsubscriptUrl = this.commonService.mailMerge( '{unsubscription_url}', sub, data, @@ -648,7 +693,7 @@ export class NotificationsController extends BaseController { this.inboundSmtpServerDomain ) { const unsubEmail = - this.mailMerge( + this.commonService.mailMerge( 'un-{subscription_id}-{unsubscription_code}@', sub, data, @@ -668,7 +713,7 @@ export class NotificationsController extends BaseController { }, }; if (this.handleBounce && this.inboundSmtpServerDomain) { - const bounceEmail = this.mailMerge( + const bounceEmail = this.commonService.mailMerge( `bn-{subscription_id}-{unsubscription_code}@${this.inboundSmtpServerDomain}`, sub, data, @@ -679,7 +724,7 @@ export class NotificationsController extends BaseController { to: data.userChannelId, }; } - await this.sendEmail(mailOptions); + await this.commonService.sendEmail(mailOptions); await this.updateBounces(data.userChannelId as string, data); return; } diff --git a/src/api/notifications/notifications.module.ts b/src/api/notifications/notifications.module.ts index 440c96d3c..876ae526a 100644 --- a/src/api/notifications/notifications.module.ts +++ b/src/api/notifications/notifications.module.ts @@ -33,11 +33,6 @@ import { NotificationsService } from './notifications.service'; MongooseModule.forFeature([ { name: Notification.name, schema: NotificationSchema }, ]), - BullModule.registerQueue( - { name: 's' /* sms */ }, - { name: 'e' /* email */ }, - { name: 'n' /* notification */ }, - ), BullModule.registerFlowProducer({}), ], controllers: [NotificationsController], diff --git a/src/api/subscriptions/subscriptions.controller.ts b/src/api/subscriptions/subscriptions.controller.ts index e792a5621..136432912 100644 --- a/src/api/subscriptions/subscriptions.controller.ts +++ b/src/api/subscriptions/subscriptions.controller.ts @@ -49,8 +49,8 @@ import RandExp from 'randexp'; import { Role } from 'src/auth/constants'; import { UserProfile } from 'src/auth/dto/user-profile.dto'; import { Roles } from 'src/auth/roles.decorator'; +import { CommonService } from 'src/common/common.service'; import { AppConfigService } from 'src/config/app-config.service'; -import { BaseController } from '../common/base.controller'; import { FilterDto } from '../common/dto/filter.dto'; import { ApiFilterJsonQuery, @@ -68,13 +68,16 @@ import { SubscriptionsService } from './subscriptions.service'; @Controller('subscriptions') @ApiTags('subscription') @UseInterceptors(SubscriptionAfterRemoteInterceptor) -export class SubscriptionsController extends BaseController { +export class SubscriptionsController { + readonly appConfig; + constructor( private readonly subscriptionsService: SubscriptionsService, readonly appConfigService: AppConfigService, readonly configurationsService: ConfigurationsService, + private readonly commonService: CommonService, ) { - super(appConfigService, configurationsService); + this.appConfig = appConfigService.get(); } @Get('count') @@ -205,7 +208,7 @@ export class SubscriptionsController extends BaseController { req, ); if (!instance) throw new HttpException(undefined, HttpStatus.NOT_FOUND); - const mergedSubscriptionConfig = await this.getMergedConfig( + const mergedSubscriptionConfig = await this.commonService.getMergedConfig( 'subscription', instance.serviceName, ); @@ -349,7 +352,7 @@ export class SubscriptionsController extends BaseController { req, )) as Subscription; if (!instance) throw new HttpException(undefined, HttpStatus.NOT_FOUND); - const mergedSubscriptionConfig = await this.getMergedConfig( + const mergedSubscriptionConfig = await this.commonService.getMergedConfig( 'subscription', instance.serviceName, ); @@ -557,7 +560,7 @@ export class SubscriptionsController extends BaseController { req, ); if (!instance) throw new HttpException(undefined, HttpStatus.NOT_FOUND); - const mergedSubscriptionConfig = await this.getMergedConfig( + const mergedSubscriptionConfig = await this.commonService.getMergedConfig( 'subscription', instance.serviceName, ); @@ -615,8 +618,13 @@ export class SubscriptionsController extends BaseController { let textBody; switch (instance.channel) { case 'sms': - textBody = this.mailMerge(msg.textBody, instance, {}, req); - await this.sendSMS( + textBody = this.commonService.mailMerge( + msg.textBody, + instance, + {}, + req, + ); + await this.commonService.sendSMS( instance.userChannelId, textBody, instance, @@ -624,9 +632,19 @@ export class SubscriptionsController extends BaseController { ); break; case 'email': { - const subject = this.mailMerge(msg.subject, instance, {}, req); - textBody = this.mailMerge(msg.textBody, instance, {}, req); - const htmlBody = this.mailMerge( + const subject = this.commonService.mailMerge( + msg.subject, + instance, + {}, + req, + ); + textBody = this.commonService.mailMerge( + msg.textBody, + instance, + {}, + req, + ); + const htmlBody = this.commonService.mailMerge( msg.htmlBody, instance, {}, @@ -639,7 +657,7 @@ export class SubscriptionsController extends BaseController { text: textBody, html: htmlBody, }; - await this.sendEmail(mailOptions, 3); + await this.commonService.sendEmail(mailOptions, 3); break; } } @@ -826,17 +844,35 @@ export class SubscriptionsController extends BaseController { } let textBody = data.confirmationRequest.textBody && - this.mailMerge(data.confirmationRequest.textBody, data, {}, req, true); + this.commonService.mailMerge( + data.confirmationRequest.textBody, + data, + {}, + req, + true, + ); let mailSubject = data.confirmationRequest.subject && - this.mailMerge(data.confirmationRequest.subject, data, {}, req, true); + this.commonService.mailMerge( + data.confirmationRequest.subject, + data, + {}, + req, + true, + ); let mailHtmlBody = data.confirmationRequest.htmlBody && - this.mailMerge(data.confirmationRequest.htmlBody, data, {}, req, true); + this.commonService.mailMerge( + data.confirmationRequest.htmlBody, + data, + {}, + req, + true, + ); let mailFrom = data.confirmationRequest.from; // handle duplicated request - const mergedSubscriptionConfig = await this.getMergedConfig( + const mergedSubscriptionConfig = await this.commonService.getMergedConfig( 'subscription', data.serviceName, ); @@ -870,7 +906,7 @@ export class SubscriptionsController extends BaseController { mergedSubscriptionConfig.duplicatedSubscriptionNotification[ data.channel ].textBody && - this.mailMerge( + this.commonService.mailMerge( mergedSubscriptionConfig.duplicatedSubscriptionNotification[ data.channel ].textBody, @@ -882,7 +918,7 @@ export class SubscriptionsController extends BaseController { mailSubject = mergedSubscriptionConfig.duplicatedSubscriptionNotification.email .subject && - this.mailMerge( + this.commonService.mailMerge( mergedSubscriptionConfig.duplicatedSubscriptionNotification.email .subject, data, @@ -893,7 +929,7 @@ export class SubscriptionsController extends BaseController { mailHtmlBody = mergedSubscriptionConfig.duplicatedSubscriptionNotification.email .htmlBody && - this.mailMerge( + this.commonService.mailMerge( mergedSubscriptionConfig.duplicatedSubscriptionNotification.email .htmlBody, data, @@ -905,7 +941,7 @@ export class SubscriptionsController extends BaseController { } switch (data.channel) { case 'sms': - await this.sendSMS(data.userChannelId, textBody, data, 1); + await this.commonService.sendSMS(data.userChannelId, textBody, data, 1); break; default: { const mailOptions = { @@ -915,7 +951,7 @@ export class SubscriptionsController extends BaseController { text: textBody, html: mailHtmlBody, }; - await this.sendEmail(mailOptions, 1); + await this.commonService.sendEmail(mailOptions, 1); } } } @@ -924,7 +960,7 @@ export class SubscriptionsController extends BaseController { req: Request & { user: UserProfile }, data: CreateSubscriptionDto, ) { - const mergedSubscriptionConfig = await this.getMergedConfig( + const mergedSubscriptionConfig = await this.commonService.getMergedConfig( 'subscription', data.serviceName, ); diff --git a/src/api/subscriptions/subscriptions.module.ts b/src/api/subscriptions/subscriptions.module.ts index 821f6516c..9381d8bc4 100644 --- a/src/api/subscriptions/subscriptions.module.ts +++ b/src/api/subscriptions/subscriptions.module.ts @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { BullModule } from '@nestjs/bullmq'; import { Module } from '@nestjs/common'; import { MongooseModule } from '@nestjs/mongoose'; import { ConfigurationsModule } from '../configurations/configurations.module'; @@ -29,10 +28,6 @@ import { SubscriptionsService } from './subscriptions.service'; MongooseModule.forFeature([ { name: Subscription.name, schema: SubscriptionSchema }, ]), - BullModule.registerQueue( - { name: 's' /* sms */ }, - { name: 'e' /* email */ }, - ), ], controllers: [SubscriptionsController], providers: [SubscriptionsService], diff --git a/src/app.module.ts b/src/app.module.ts index b4cbb3d58..8a13d6c2c 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -26,6 +26,7 @@ import { NotificationsModule } from './api/notifications/notifications.module'; import { SubscriptionsModule } from './api/subscriptions/subscriptions.module'; import { AppService } from './app.service'; import { AuthModule } from './auth/auth.module'; +import { CommonModule } from './common/common.module'; import { AppConfigService } from './config/app-config.service'; import { ConfigModule } from './config/config.module'; import { DbConfigService } from './config/db-config.service'; @@ -103,6 +104,7 @@ import { RssModule } from './rss/rss.module'; }; }, }), + CommonModule, ], providers: [SwaggerService, AppService], }) diff --git a/src/common/common.module.ts b/src/common/common.module.ts new file mode 100644 index 000000000..978ccbbfb --- /dev/null +++ b/src/common/common.module.ts @@ -0,0 +1,21 @@ +import { BullModule } from '@nestjs/bullmq'; +import { Global, Module } from '@nestjs/common'; +import { ConfigurationsModule } from '../api/configurations/configurations.module'; +import { ConfigModule } from '../config/config.module'; +import { CommonService } from './common.service'; + +@Global() +@Module({ + imports: [ + ConfigModule, + ConfigurationsModule, + BullModule.registerQueue( + { name: 's' /* sms */ }, + { name: 'e' /* email */ }, + { name: 'n' /* notification */ }, + ), + ], + providers: [CommonService], + exports: [CommonService], +}) +export class CommonModule {} diff --git a/src/api/common/base.controller.ts b/src/common/common.service.ts similarity index 95% rename from src/api/common/base.controller.ts rename to src/common/common.service.ts index e87a2a077..1bfab3c32 100644 --- a/src/api/common/base.controller.ts +++ b/src/common/common.service.ts @@ -13,7 +13,7 @@ // limitations under the License. import { getQueueToken } from '@nestjs/bullmq'; -import { Controller, Inject, Logger } from '@nestjs/common'; +import { Inject, Injectable, Logger } from '@nestjs/common'; import { Queue, QueueEvents } from 'bullmq'; import dns from 'dns'; import { get, merge, union } from 'lodash'; @@ -23,17 +23,17 @@ import { AppConfigService } from 'src/config/app-config.service'; import twilio from 'twilio'; import toSentence from 'underscore.string/toSentence'; import util from 'util'; -import { ConfigurationsService } from '../configurations/configurations.service'; -import { Configuration } from '../configurations/entities/configuration.entity'; -import { Subscription } from '../subscriptions/entities/subscription.entity'; +import { ConfigurationsService } from '../api/configurations/configurations.service'; +import { Configuration } from '../api/configurations/entities/configuration.entity'; +import { Subscription } from '../api/subscriptions/entities/subscription.entity'; interface SMSBody { MessageBody: string; [key: string]: string; } -@Controller() -export class BaseController { +@Injectable() +export class CommonService { readonly appConfig; @Inject(getQueueToken('s')) @@ -65,7 +65,7 @@ export class BaseController { queueEvents.on('completed', async ({ jobId }) => { Logger.debug( `job ${jobId} completed on queueEventsListener for ${j?.id}`, - BaseController.name, + CommonService.name, ); if (!j?.id) { queuedID.push(jobId); @@ -137,10 +137,10 @@ export class BaseController { const accountSid = smsConfig.accountSid; const authToken = smsConfig.authToken; //require the Twilio module and create a REST client - BaseController.smsClient = - BaseController.smsClient || twilio(accountSid, authToken); - let req = BaseController.smsClient.messages.create.bind( - BaseController.smsClient.messages, + CommonService.smsClient = + CommonService.smsClient || twilio(accountSid, authToken); + let req = CommonService.smsClient.messages.create.bind( + CommonService.smsClient.messages, ); if (this.appConfig?.sms?.throttle?.enabled) { req = this.rateLimit(this.smsQueue, req, { priority }); diff --git a/test/cron.e2e-spec.ts b/test/cron.e2e-spec.ts index 793a5f1a8..96f224ea6 100644 --- a/test/cron.e2e-spec.ts +++ b/test/cron.e2e-spec.ts @@ -19,10 +19,10 @@ import mongoose from 'mongoose'; import path from 'path'; import { AccessTokenService } from 'src/api/administrators/access-token.service'; import { BouncesService } from 'src/api/bounces/bounces.service'; -import { BaseController } from 'src/api/common/base.controller'; import { ConfigurationsService } from 'src/api/configurations/configurations.service'; import { NotificationsService } from 'src/api/notifications/notifications.service'; import { SubscriptionsService } from 'src/api/subscriptions/subscriptions.service'; +import { CommonService } from 'src/common/common.service'; import { CronTasksService } from 'src/observers/cron-tasks.service'; import { RssService } from 'src/rss/rss.service'; import supertest from 'supertest'; @@ -352,7 +352,7 @@ describe('CRON dispatchLiveNotifications', function () { fail(err); } await wait(3000); - const mockedSendEmail = BaseController.prototype + const mockedSendEmail = CommonService.prototype .sendEmail as unknown as jest.SpyInstance; expect(mockedSendEmail).toHaveBeenCalledTimes(1); const subId = beforeEachRes[2].id; @@ -656,7 +656,7 @@ describe('CRON reDispatchBroadcastPushNotifications', () => { fail(err); } await wait(3000); - const mockedSendEmail = BaseController.prototype + const mockedSendEmail = CommonService.prototype .sendEmail as unknown as jest.SpyInstance; expect(mockedSendEmail).toBeCalledWith( expect.objectContaining({ diff --git a/test/notification.e2e-spec.ts b/test/notification.e2e-spec.ts index cfe7e1cc7..912612d40 100644 --- a/test/notification.e2e-spec.ts +++ b/test/notification.e2e-spec.ts @@ -19,10 +19,10 @@ import dns from 'dns'; import { merge } from 'lodash'; import mailer from 'nodemailer/lib/mailer'; import { BouncesService } from 'src/api/bounces/bounces.service'; -import { BaseController } from 'src/api/common/base.controller'; import { NotificationsController } from 'src/api/notifications/notifications.controller'; import { NotificationsService } from 'src/api/notifications/notifications.service'; import { SubscriptionsService } from 'src/api/subscriptions/subscriptions.service'; +import { CommonService } from 'src/common/common.service'; import { AppConfigService } from 'src/config/app-config.service'; import supertest from 'supertest'; import { getAppAndClient, runAsSuperAdmin, wait } from './test-helper'; @@ -228,7 +228,7 @@ describe('POST /notifications', () => { }) .set('Accept', 'application/json'); expect(res.status).toEqual(200); - const spiedSendEmail = BaseController.prototype + const spiedSendEmail = CommonService.prototype .sendEmail as unknown as jest.SpyInstance; expect(spiedSendEmail).toBeCalled(); expect(spiedSendEmail).nthCalledWith( @@ -428,7 +428,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).toBeCalled(); const data = await notificationsService.findAll( { @@ -460,7 +460,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendSMS as unknown as jest.SpyInstance, + CommonService.prototype.sendSMS as unknown as jest.SpyInstance, ).toBeCalled(); const data = await notificationsService.findAll( { @@ -491,7 +491,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendSMS as unknown as jest.SpyInstance, + CommonService.prototype.sendSMS as unknown as jest.SpyInstance, ).toBeCalled(); const data = await notificationsService.findAll( { @@ -508,7 +508,7 @@ describe('POST /notifications', () => { it('should handle sms broadcast push notification failures', async () => { await runAsSuperAdmin(async () => { ( - BaseController.prototype.sendSMS as unknown as jest.SpyInstance + CommonService.prototype.sendSMS as unknown as jest.SpyInstance ).mockRestore(); const mockedFetch = jest .spyOn(global, 'fetch') @@ -563,7 +563,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).not.toBeCalled(); const data = await notificationsService.findAll( { @@ -682,7 +682,7 @@ describe('POST /notifications', () => { async () => { await runAsSuperAdmin(async () => { ( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance + CommonService.prototype.sendEmail as unknown as jest.SpyInstance ).mockImplementation(async () => { await wait(1000); }); @@ -757,7 +757,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).toBeCalledTimes(2); expect(spiedAxios).toBeCalledTimes(2); const data = await notificationsService.findAll( @@ -794,7 +794,7 @@ describe('POST /notifications', () => { }); ( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance + CommonService.prototype.sendEmail as unknown as jest.SpyInstance ).mockImplementation(async (...args) => { const to = args[0].to; let error: any = null; @@ -845,7 +845,7 @@ describe('POST /notifications', () => { expect(spiedFetch).toBeCalledWith('http://foo.com', expect.any(Object)); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).toBeCalledTimes(2); expect( data[0].dispatch.candidates.indexOf(promiseAllRes[3].id), @@ -888,7 +888,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).not.toBeCalled(); const data = await notificationsService.findAll( { @@ -937,7 +937,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).toBeCalledTimes(2); expect(reqStub).toBeCalledTimes(3); const data = await notificationsService.findAll( @@ -1002,7 +1002,7 @@ describe('POST /notifications', () => { res.abort(); await wait(4000); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).not.toBeCalled(); appConfig.notification = newNotificationConfig; }); @@ -1011,7 +1011,7 @@ describe('POST /notifications', () => { it('should perform client-retry', async () => { await runAsSuperAdmin(async () => { ( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance + CommonService.prototype.sendEmail as unknown as jest.SpyInstance ).mockRestore(); jest .spyOn(mailer.prototype, 'sendMail') @@ -1073,7 +1073,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).toBeCalledTimes(1); const data = await notificationsService.findAll( { @@ -1116,7 +1116,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).not.toBeCalled(); const data = await notificationsService.findAll( { @@ -1278,7 +1278,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - (BaseController.prototype.sendEmail as unknown as jest.SpyInstance) + (CommonService.prototype.sendEmail as unknown as jest.SpyInstance) .mock.calls[0][0].envelope.from, ).toEqual(`bn-${promiseAllRes[0].id}-54321@invalid.local`); }); @@ -1309,7 +1309,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - (BaseController.prototype.sendEmail as unknown as jest.SpyInstance).mock + (CommonService.prototype.sendEmail as unknown as jest.SpyInstance).mock .calls[0][0].envelope, ).toBeUndefined(); appConfig.email = origEmailConfig; @@ -1341,7 +1341,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - (BaseController.prototype.sendEmail as unknown as jest.SpyInstance).mock + (CommonService.prototype.sendEmail as unknown as jest.SpyInstance).mock .calls[0][0].envelope, ).toBeUndefined(); appConfig.email = origEmailConfig; @@ -1425,7 +1425,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).toBeCalledTimes(1); const data = await notificationsService.findAll( { @@ -1492,7 +1492,7 @@ describe('POST /notifications', () => { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).toBeCalledTimes(1); const data = await notificationsService.findAll( { diff --git a/test/redis.e2e-spec.ts b/test/redis.e2e-spec.ts index 6daa324f9..6ed4aa063 100644 --- a/test/redis.e2e-spec.ts +++ b/test/redis.e2e-spec.ts @@ -2,9 +2,9 @@ import { NestExpressApplication } from '@nestjs/platform-express'; import { Queue } from 'bullmq'; import dns from 'dns'; import mailer from 'nodemailer/lib/mailer'; -import { BaseController } from 'src/api/common/base.controller'; import { NotificationsService } from 'src/api/notifications/notifications.service'; import { SubscriptionsService } from 'src/api/subscriptions/subscriptions.service'; +import { CommonService } from 'src/common/common.service'; import supertest from 'supertest'; import { runAsSuperAdmin, setupApplication, wait } from './test-helper'; @@ -47,7 +47,7 @@ skipIfWindows('', () => { let promiseAllRes; beforeEach(async () => { ( - BaseController.prototype.sendSMS as unknown as jest.SpyInstance + CommonService.prototype.sendSMS as unknown as jest.SpyInstance ).mockRestore(); mockedFetch = jest.spyOn(global, 'fetch').mockResolvedValue(new Response()); @@ -115,7 +115,7 @@ skipIfWindows('', () => { it('should perform throttled client-retry', async () => { await runAsSuperAdmin(async () => { ( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance + CommonService.prototype.sendEmail as unknown as jest.SpyInstance ).mockRestore(); jest .spyOn(mailer.prototype, 'sendMail') diff --git a/test/subscription.e2e-spec.ts b/test/subscription.e2e-spec.ts index f60269833..21468d6b0 100644 --- a/test/subscription.e2e-spec.ts +++ b/test/subscription.e2e-spec.ts @@ -14,10 +14,10 @@ import { NestExpressApplication } from '@nestjs/platform-express'; import { merge } from 'lodash'; -import { BaseController } from 'src/api/common/base.controller'; import { ConfigurationsService } from 'src/api/configurations/configurations.service'; import { Subscription } from 'src/api/subscriptions/entities/subscription.entity'; import { SubscriptionsService } from 'src/api/subscriptions/subscriptions.service'; +import { CommonService } from 'src/common/common.service'; import { AppConfigService } from 'src/config/app-config.service'; import supertest from 'supertest'; import { getAppAndClient, runAsSuperAdmin } from './test-helper'; @@ -104,7 +104,7 @@ describe('POST /subscriptions', function () { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).not.toBeCalled(); const data = await subscriptionsService.findAll( { @@ -139,7 +139,7 @@ describe('POST /subscriptions', function () { }) .set('Accept', 'application/json'); expect(res.status).toEqual(200); - const spiedSendEmail = BaseController.prototype + const spiedSendEmail = CommonService.prototype .sendEmail as unknown as jest.SpyInstance; expect(spiedSendEmail).toBeCalled(); expect(spiedSendEmail).not.toBeCalledWith( @@ -286,7 +286,7 @@ describe('POST /subscriptions', function () { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendSMS as unknown as jest.SpyInstance, + CommonService.prototype.sendSMS as unknown as jest.SpyInstance, ).toBeCalledTimes(1); const data = await subscriptionsService.findAll( { @@ -321,7 +321,7 @@ describe('POST /subscriptions', function () { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).toBeCalledTimes(1); const data = await subscriptionsService.findAll( { @@ -338,9 +338,9 @@ describe('POST /subscriptions', function () { it('should allow non-admin user create sms subscription using swift provider', async () => { ( - BaseController.prototype.sendSMS as unknown as jest.SpyInstance + CommonService.prototype.sendSMS as unknown as jest.SpyInstance ).mockRestore(); - const spiedSendSms = jest.spyOn(BaseController.prototype, 'sendSMS'); + const spiedSendSms = jest.spyOn(CommonService.prototype, 'sendSMS'); const fetchStub = jest .spyOn(global, 'fetch') .mockResolvedValue(new Response()); @@ -391,7 +391,7 @@ describe('POST /subscriptions', function () { }) .set('Accept', 'application/json'); expect(res.status).toEqual(200); - const spiedSendEmail = BaseController.prototype + const spiedSendEmail = CommonService.prototype .sendEmail as unknown as jest.SpyInstance; expect(spiedSendEmail).toBeCalledTimes(1); const data = await subscriptionsService.findAll( @@ -442,7 +442,7 @@ describe('POST /subscriptions', function () { .set('Accept', 'application/json'); expect(res.status).toEqual(200); expect( - BaseController.prototype.sendSMS as unknown as jest.SpyInstance, + CommonService.prototype.sendSMS as unknown as jest.SpyInstance, ).toBeCalledTimes(1); const data = await subscriptionsService.findAll( { @@ -458,7 +458,7 @@ describe('POST /subscriptions', function () { it('should detect duplicated subscription', async () => { jest - .spyOn(BaseController.prototype, 'getMergedConfig') + .spyOn(CommonService.prototype, 'getMergedConfig') .mockImplementation(async () => { const res = { detectDuplicatedSubscription: true, @@ -505,7 +505,7 @@ describe('POST /subscriptions', function () { }) .set('Accept', 'application/json'); expect(res.status).toEqual(200); - const spiedSendEmail = BaseController.prototype + const spiedSendEmail = CommonService.prototype .sendEmail as unknown as jest.SpyInstance; expect(spiedSendEmail).toBeCalled(); expect(spiedSendEmail).toBeCalledWith( @@ -810,7 +810,7 @@ describe('DELETE /subscriptions/{id}', () => { it('should redirect onscreen acknowledgements with error', async () => { jest - .spyOn(BaseController.prototype, 'getMergedConfig') + .spyOn(CommonService.prototype, 'getMergedConfig') .mockImplementation(async function () { return { anonymousUnsubscription: { @@ -838,7 +838,7 @@ describe('DELETE /subscriptions/{id}', () => { it('should display onScreen acknowledgements failureMessage', async () => { jest - .spyOn(BaseController.prototype, 'getMergedConfig') + .spyOn(CommonService.prototype, 'getMergedConfig') .mockImplementation(async function () { return { anonymousUnsubscription: { @@ -894,7 +894,7 @@ describe('GET /subscriptions/{id}/unsubscribe', () => { it('should allow bulk unsubscribing all services', async () => { jest - .spyOn(BaseController.prototype, 'getMergedConfig') + .spyOn(CommonService.prototype, 'getMergedConfig') .mockImplementation(async function () { return { anonymousUnsubscription: { @@ -929,7 +929,7 @@ describe('GET /subscriptions/{id}/unsubscribe', () => { ); expect(res.length).toEqual(3); expect( - BaseController.prototype.sendEmail as unknown as jest.SpyInstance, + CommonService.prototype.sendEmail as unknown as jest.SpyInstance, ).toBeCalledWith( expect.objectContaining({ text: expect.stringMatching( diff --git a/test/test-helper.ts b/test/test-helper.ts index 6a5d5f140..51ef7056d 100644 --- a/test/test-helper.ts +++ b/test/test-helper.ts @@ -17,8 +17,8 @@ import { NestExpressApplication } from '@nestjs/platform-express'; import { Test, TestingModule } from '@nestjs/testing'; import { merge } from 'lodash'; import { Connection } from 'mongoose'; -import { BaseController } from 'src/api/common/base.controller'; import { AppModule } from 'src/app.module'; +import { CommonService } from 'src/common/common.service'; import { AppConfigService } from 'src/config/app-config.service'; import { setupApp } from 'src/main'; import supertest from 'supertest'; @@ -62,8 +62,8 @@ afterAll(async () => { }); beforeEach(function () { - jest.spyOn(BaseController.prototype, 'sendEmail').mockResolvedValue({}); - jest.spyOn(BaseController.prototype, 'sendSMS').mockResolvedValue({}); + jest.spyOn(CommonService.prototype, 'sendEmail').mockResolvedValue({}); + jest.spyOn(CommonService.prototype, 'sendSMS').mockResolvedValue({}); }); afterEach(async () => {