From 3e74ec0ffde1a658928b4c72ac3a4380c6ed2c68 Mon Sep 17 00:00:00 2001 From: Ellie Re'em Date: Tue, 23 Jul 2024 17:46:33 +0100 Subject: [PATCH 1/2] fix: session-feedback adjustments after review --- src/api/slack/slack-api.ts | 19 +++++++++++++++++++ .../dtos/session-feedback.dto.ts | 1 - .../session-feedback.service.spec.ts | 10 ++++++++-- .../session-feedback.service.ts | 11 ++++++++++- src/session/session.service.ts | 8 ++++++++ 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/api/slack/slack-api.ts b/src/api/slack/slack-api.ts index 362363c2..54d4be38 100644 --- a/src/api/slack/slack-api.ts +++ b/src/api/slack/slack-api.ts @@ -25,4 +25,23 @@ export class SlackMessageClient { return err; } } + + public async sendMessageToBloomUserChannel(text: string): Promise { + if (!isProduction) return; // only send messages in production environment + + try { + const response = await apiCall({ + url: process.env.SLACK_BLOOM_USERS_WEBHOOK_URL, + type: 'post', + data: { + text: text, + }, + }); + this.logger.log({ event: 'SESSION_FEEDBACK_SLACK_MESSAGE_SENT' }); + return response; + } catch (err) { + this.logger.error('Unable to sendMessageToBloomUserSlackChannel', err); + return err; + } + } } diff --git a/src/session-feedback/dtos/session-feedback.dto.ts b/src/session-feedback/dtos/session-feedback.dto.ts index 4dea3b32..598320f1 100644 --- a/src/session-feedback/dtos/session-feedback.dto.ts +++ b/src/session-feedback/dtos/session-feedback.dto.ts @@ -17,7 +17,6 @@ export class SessionFeedbackDto { }) feedbackTags: FEEDBACK_TAGS_ENUM; - @IsNotEmpty() @IsString() @ApiProperty({ type: String }) feedbackDescription: string; diff --git a/src/session-feedback/session-feedback.service.spec.ts b/src/session-feedback/session-feedback.service.spec.ts index 91962645..634052b9 100644 --- a/src/session-feedback/session-feedback.service.spec.ts +++ b/src/session-feedback/session-feedback.service.spec.ts @@ -2,6 +2,7 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { HttpException, HttpStatus } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; +import { SlackMessageClient } from 'src/api/slack/slack-api'; import { PartnerAccessEntity } from 'src/entities/partner-access.entity'; import { PartnerEntity } from 'src/entities/partner.entity'; import { SessionFeedbackEntity } from 'src/entities/session-feedback.entity'; @@ -34,6 +35,7 @@ describe('SessionFeedbackService', () => { let mockTherapySessionRepository: DeepMocked>; let mockSessionFeedbackRepository: DeepMocked>; let mockSessionService: DeepMocked; + let mockSlackMessageClient: DeepMocked; beforeEach(async () => { mockPartnerAccessRepository = createMock>(); @@ -45,6 +47,7 @@ describe('SessionFeedbackService', () => { mockTherapySessionRepository = createMock>(); mockSessionFeedbackRepository = createMock>(); mockSessionService = createMock(); + mockSlackMessageClient = createMock(); const module: TestingModule = await Test.createTestingModule({ providers: [ @@ -85,6 +88,7 @@ describe('SessionFeedbackService', () => { provide: SessionService, useValue: mockSessionService, }, + { provide: SlackMessageClient, useValue: mockSlackMessageClient }, ], }).compile(); @@ -96,13 +100,15 @@ describe('SessionFeedbackService', () => { }); describe('createSessionFeedback', () => { it('when session id exists should return dto', async () => { - jest.spyOn(mockSessionService, 'getSession').mockResolvedValueOnce(mockSessionEntity); + jest + .spyOn(mockSessionService, 'getSessionAndCourse') + .mockResolvedValueOnce(mockSessionEntity); const response = await service.createSessionFeedback(sessionFeedbackDto); expect(response).toMatchObject(sessionFeedbackDto); }); it('when session id does not exist should throw exception', async () => { - jest.spyOn(mockSessionService, 'getSession').mockResolvedValueOnce(null); + jest.spyOn(mockSessionService, 'getSessionAndCourse').mockResolvedValueOnce(null); await expect(service.createSessionFeedback(sessionFeedbackDto)).rejects.toThrow( new HttpException('SESSION NOT FOUND', HttpStatus.NOT_FOUND), diff --git a/src/session-feedback/session-feedback.service.ts b/src/session-feedback/session-feedback.service.ts index b8946819..25c980cd 100644 --- a/src/session-feedback/session-feedback.service.ts +++ b/src/session-feedback/session-feedback.service.ts @@ -1,5 +1,6 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; +import { SlackMessageClient } from 'src/api/slack/slack-api'; import { PartnerAccessEntity } from 'src/entities/partner-access.entity'; import { PartnerEntity } from 'src/entities/partner.entity'; import { SessionFeedbackEntity } from 'src/entities/session-feedback.entity'; @@ -32,12 +33,13 @@ export class SessionFeedbackService { @InjectRepository(SessionFeedbackEntity) private sessionFeedbackRepository: Repository, private readonly sessionService: SessionService, + private slackMessageClient: SlackMessageClient, ) {} public async createSessionFeedback( sessionFeedbackDto: SessionFeedbackDto, ): Promise { - const session = await this.sessionService.getSession(sessionFeedbackDto.sessionId); + const session = await this.sessionService.getSessionAndCourse(sessionFeedbackDto.sessionId); if (!session) { throw new HttpException('SESSION NOT FOUND', HttpStatus.NOT_FOUND); @@ -45,7 +47,14 @@ export class SessionFeedbackService { const sessionFeedbackObject = this.sessionFeedbackRepository.create(sessionFeedbackDto); await this.sessionFeedbackRepository.save(sessionFeedbackObject); + this.sendSlackSessionFeedback(sessionFeedbackDto, session); return sessionFeedbackDto; } + // We don't need to wait for this to finish so async is not needed + sendSlackSessionFeedback(sessionFeedbackDto: SessionFeedbackDto, session: SessionEntity) { + this.slackMessageClient.sendMessageToBloomUserChannel( + `*${session.name}* in *${session.course?.name}* was rated *_${sessionFeedbackDto.feedbackTags}_* ${sessionFeedbackDto.feedbackDescription.length > 0 ? `with the comment: \n> _${sessionFeedbackDto.feedbackDescription}_` : ''}`, + ); + } } diff --git a/src/session/session.service.ts b/src/session/session.service.ts index ede3ce9f..e10da0d2 100644 --- a/src/session/session.service.ts +++ b/src/session/session.service.ts @@ -13,6 +13,14 @@ export class SessionService { return await this.sessionRepository.findOneBy({ id }); } + async getSessionAndCourse(id: string): Promise { + return await this.sessionRepository + .createQueryBuilder('session') + .leftJoinAndSelect('session.course', 'course') + .where('session.id = :id', { id }) + .getOne(); + } + async getSessionByStoryblokId(storyblokId: number): Promise { return await this.sessionRepository .createQueryBuilder('session') From 85c120ef720599e34160e5ea4c11d1d79c16cc92 Mon Sep 17 00:00:00 2001 From: Ellie Re'em Date: Tue, 23 Jul 2024 17:46:54 +0100 Subject: [PATCH 2/2] fix: update authguard on bulk upload mailchimp --- src/user/user.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts index 77c5bf57..9683964d 100644 --- a/src/user/user.controller.ts +++ b/src/user/user.controller.ts @@ -108,7 +108,7 @@ export class UserController { // Use only if users have not been added to mailchimp due to e.g. an ongoing bug @ApiBearerAuth() @Post('/bulk-mailchimp-upload') - @UseGuards(FirebaseAuthGuard) + @UseGuards(SuperAdminAuthGuard) async bulkUploadMailchimpProfiles() { return await this.userService.bulkUploadMailchimpProfiles(); }