diff --git a/api/src/chat/controllers/block.controller.spec.ts b/api/src/chat/controllers/block.controller.spec.ts index a68dc7d9..767e69b4 100644 --- a/api/src/chat/controllers/block.controller.spec.ts +++ b/api/src/chat/controllers/block.controller.spec.ts @@ -61,11 +61,11 @@ describe('BlockController', () => { let blockController: BlockController; let blockService: BlockService; let categoryService: CategoryService; - let category: Category | null; - let block: Block | null; - let blockToDelete: Block | null; - let hasNextBlocks: Block | null; - let hasPreviousBlocks: Block | null; + let category: Category; + let block: Block; + let blockToDelete: Block; + let hasNextBlocks: Block; + let hasPreviousBlocks: Block; const FIELDS_TO_POPULATE = [ 'trigger_labels', 'assign_labels', @@ -142,18 +142,19 @@ describe('BlockController', () => { blockController = module.get(BlockController); blockService = module.get(BlockService); categoryService = module.get(CategoryService); - category = await categoryService.findOne({ label: 'default' }); - block = await blockService.findOne({ name: 'first' }); - blockToDelete = await blockService.findOne({ name: 'buttons' }); - hasNextBlocks = await blockService.findOne({ + category = (await categoryService.findOne({ label: 'default' }))!; + block = (await blockService.findOne({ name: 'first' }))!; + blockToDelete = (await blockService.findOne({ name: 'buttons' }))!; + hasNextBlocks = (await blockService.findOne({ name: 'hasNextBlocks', - }); - hasPreviousBlocks = await blockService.findOne({ + }))!; + hasPreviousBlocks = (await blockService.findOne({ name: 'hasPreviousBlocks', - }); + }))!; }); afterEach(jest.clearAllMocks); + afterAll(closeInMongodConnection); describe('find', () => { @@ -162,9 +163,9 @@ describe('BlockController', () => { const result = await blockController.find([], {}); const blocksWithCategory = blockFixtures.map((blockFixture) => ({ ...blockFixture, - category: category!.id, + category: category.id, nextBlocks: - blockFixture.name === 'hasNextBlocks' ? [hasPreviousBlocks!.id] : [], + blockFixture.name === 'hasNextBlocks' ? [hasPreviousBlocks.id] : [], })); expect(blockService.find).toHaveBeenCalledWith({}, undefined); @@ -196,13 +197,13 @@ describe('BlockController', () => { describe('findOne', () => { it('should find one block by id', async () => { jest.spyOn(blockService, 'findOne'); - const result = await blockController.findOne(hasNextBlocks!.id, []); - expect(blockService.findOne).toHaveBeenCalledWith(hasNextBlocks!.id); + const result = await blockController.findOne(hasNextBlocks.id, []); + expect(blockService.findOne).toHaveBeenCalledWith(hasNextBlocks.id); expect(result).toEqualPayload( { - ...blockFixtures.find(({ name }) => name === hasNextBlocks!.name), - category: category!.id, - nextBlocks: [hasPreviousBlocks!.id], + ...blockFixtures.find(({ name }) => name === hasNextBlocks.name), + category: category.id, + nextBlocks: [hasPreviousBlocks.id], }, [...IGNORED_TEST_FIELDS, 'attachedToBlock'], ); @@ -211,11 +212,11 @@ describe('BlockController', () => { it('should find one block by id, and populate its category and previousBlocks', async () => { jest.spyOn(blockService, 'findOneAndPopulate'); const result = await blockController.findOne( - hasPreviousBlocks!.id, + hasPreviousBlocks.id, FIELDS_TO_POPULATE, ); expect(blockService.findOneAndPopulate).toHaveBeenCalledWith( - hasPreviousBlocks!.id, + hasPreviousBlocks.id, ); expect(result).toEqualPayload({ ...blockFixtures.find(({ name }) => name === 'hasPreviousBlocks'), @@ -227,12 +228,12 @@ describe('BlockController', () => { it('should find one block by id, and populate its category and an empty previousBlocks', async () => { jest.spyOn(blockService, 'findOneAndPopulate'); - block = await blockService.findOne({ name: 'attachment' }); + block = (await blockService.findOne({ name: 'attachment' }))!; const result = await blockController.findOne( - block!.id, + block.id, FIELDS_TO_POPULATE, ); - expect(blockService.findOneAndPopulate).toHaveBeenCalledWith(block!.id); + expect(blockService.findOneAndPopulate).toHaveBeenCalledWith(block.id); expect(result).toEqualPayload({ ...blockFixtures.find(({ name }) => name === 'attachment'), category, @@ -247,12 +248,12 @@ describe('BlockController', () => { jest.spyOn(blockService, 'create'); const mockedBlockCreateDto: BlockCreateDto = { name: 'block with nextBlocks', - nextBlocks: [hasNextBlocks!.id], + nextBlocks: [hasNextBlocks.id], patterns: ['Hi'], trigger_labels: [], assign_labels: [], trigger_channels: [], - category: category!.id, + category: category.id, options: { typing: 0, fallback: { @@ -284,17 +285,15 @@ describe('BlockController', () => { describe('deleteOne', () => { it('should delete block', async () => { jest.spyOn(blockService, 'deleteOne'); - const result = await blockController.deleteOne(blockToDelete!.id); + const result = await blockController.deleteOne(blockToDelete.id); - expect(blockService.deleteOne).toHaveBeenCalledWith(blockToDelete!.id); + expect(blockService.deleteOne).toHaveBeenCalledWith(blockToDelete.id); expect(result).toEqual({ acknowledged: true, deletedCount: 1 }); }); it('should throw NotFoundException when attempting to delete a block by id', async () => { - await expect( - blockController.deleteOne(blockToDelete!.id), - ).rejects.toThrow( - new NotFoundException(`Block with ID ${blockToDelete!.id} not found`), + await expect(blockController.deleteOne(blockToDelete.id)).rejects.toThrow( + new NotFoundException(`Block with ID ${blockToDelete.id} not found`), ); }); }); @@ -305,16 +304,16 @@ describe('BlockController', () => { const updateBlock: BlockUpdateDto = { name: 'modified block name', }; - const result = await blockController.updateOne(block!.id, updateBlock); + const result = await blockController.updateOne(block.id, updateBlock); expect(blockService.updateOne).toHaveBeenCalledWith( - block!.id, + block.id, updateBlock, ); expect(result).toEqualPayload( { - ...blockFixtures.find(({ name }) => name === block!.name), - category: category!.id, + ...blockFixtures.find(({ name }) => name === block.name), + category: category.id, ...updateBlock, }, [...IGNORED_TEST_FIELDS, 'attachedToBlock'], @@ -327,9 +326,9 @@ describe('BlockController', () => { }; await expect( - blockController.updateOne(blockToDelete!.id, updateBlock), + blockController.updateOne(blockToDelete.id, updateBlock), ).rejects.toThrow( - new NotFoundException(`Block with ID ${blockToDelete!.id} not found`), + new NotFoundException(`Block with ID ${blockToDelete.id} not found`), ); }); }); diff --git a/api/src/chat/controllers/context-var.controller.spec.ts b/api/src/chat/controllers/context-var.controller.spec.ts index 11a88eb8..d14a7dd6 100644 --- a/api/src/chat/controllers/context-var.controller.spec.ts +++ b/api/src/chat/controllers/context-var.controller.spec.ts @@ -36,8 +36,8 @@ import { ContextVarController } from './context-var.controller'; describe('ContextVarController', () => { let contextVarController: ContextVarController; let contextVarService: ContextVarService; - let contextVar: ContextVar | null; - let contextVarToDelete: ContextVar | null; + let contextVar: ContextVar; + let contextVarToDelete: ContextVar; beforeAll(async () => { const module = await Test.createTestingModule({ @@ -56,15 +56,16 @@ describe('ContextVarController', () => { contextVarController = module.get(ContextVarController); contextVarService = module.get(ContextVarService); - contextVar = await contextVarService.findOne({ + contextVar = (await contextVarService.findOne({ label: 'test context var 1', - }); - contextVarToDelete = await contextVarService.findOne({ + }))!; + contextVarToDelete = (await contextVarService.findOne({ label: 'test context var 2', - }); + }))!; }); afterEach(jest.clearAllMocks); + afterAll(closeInMongodConnection); describe('count', () => { @@ -91,11 +92,11 @@ describe('ContextVarController', () => { describe('findOne', () => { it('should return the existing contextVar', async () => { jest.spyOn(contextVarService, 'findOne'); - const result = await contextVarController.findOne(contextVar!.id); + const result = await contextVarController.findOne(contextVar.id); - expect(contextVarService.findOne).toHaveBeenCalledWith(contextVar!.id); + expect(contextVarService.findOne).toHaveBeenCalledWith(contextVar.id); expect(result).toEqualPayload( - contextVarFixtures.find(({ label }) => label === contextVar!.label)!, + contextVarFixtures.find(({ label }) => label === contextVar.label)!, ); }); }); @@ -121,11 +122,11 @@ describe('ContextVarController', () => { it('should delete a contextVar by id', async () => { jest.spyOn(contextVarService, 'deleteOne'); const result = await contextVarController.deleteOne( - contextVarToDelete!.id, + contextVarToDelete.id, ); expect(contextVarService.deleteOne).toHaveBeenCalledWith( - contextVarToDelete!.id, + contextVarToDelete.id, ); expect(result).toEqual({ acknowledged: true, @@ -135,10 +136,10 @@ describe('ContextVarController', () => { it('should throw a NotFoundException when attempting to delete a contextVar by id', async () => { await expect( - contextVarController.deleteOne(contextVarToDelete!.id), + contextVarController.deleteOne(contextVarToDelete.id), ).rejects.toThrow( new NotFoundException( - `Context var with ID ${contextVarToDelete!.id} not found.`, + `Context var with ID ${contextVarToDelete.id} not found.`, ), ); }); @@ -152,12 +153,12 @@ describe('ContextVarController', () => { .spyOn(contextVarService, 'deleteMany') .mockResolvedValue(deleteResult); const result = await contextVarController.deleteMany([ - contextVarToDelete!.id, - contextVar!.id, + contextVarToDelete.id, + contextVar.id, ]); expect(contextVarService.deleteMany).toHaveBeenCalledWith({ - _id: { $in: [contextVarToDelete!.id, contextVar!.id] }, + _id: { $in: [contextVarToDelete.id, contextVar.id] }, }); expect(result).toEqual(deleteResult); }); @@ -175,10 +176,7 @@ describe('ContextVarController', () => { }); await expect( - contextVarController.deleteMany([ - contextVarToDelete!.id, - contextVar!.id, - ]), + contextVarController.deleteMany([contextVarToDelete.id, contextVar.id]), ).rejects.toThrow( new NotFoundException('Context vars with provided IDs not found'), ); @@ -192,16 +190,16 @@ describe('ContextVarController', () => { it('should return updated contextVar', async () => { jest.spyOn(contextVarService, 'updateOne'); const result = await contextVarController.updateOne( - contextVar!.id, + contextVar.id, contextVarUpdatedDto, ); expect(contextVarService.updateOne).toHaveBeenCalledWith( - contextVar!.id, + contextVar.id, contextVarUpdatedDto, ); expect(result).toEqualPayload({ - ...contextVarFixtures.find(({ label }) => label === contextVar!.label), + ...contextVarFixtures.find(({ label }) => label === contextVar.label), ...contextVarUpdatedDto, }); }); @@ -209,12 +207,12 @@ describe('ContextVarController', () => { it('should throw a NotFoundException when attempting to update an non existing contextVar by id', async () => { await expect( contextVarController.updateOne( - contextVarToDelete!.id, + contextVarToDelete.id, contextVarUpdatedDto, ), ).rejects.toThrow( new NotFoundException( - `ContextVar with ID ${contextVarToDelete!.id} not found`, + `ContextVar with ID ${contextVarToDelete.id} not found`, ), ); }); diff --git a/api/src/chat/controllers/message.controller.spec.ts b/api/src/chat/controllers/message.controller.spec.ts index b7dad706..d2e9c2d3 100644 --- a/api/src/chat/controllers/message.controller.spec.ts +++ b/api/src/chat/controllers/message.controller.spec.ts @@ -53,10 +53,10 @@ describe('MessageController', () => { let messageService: MessageService; let subscriberService: SubscriberService; let userService: UserService; - let sender: Subscriber | null; - let recipient: Subscriber | null; - let user: User | null; - let message: Message | null; + let sender: Subscriber; + let recipient: Subscriber; + let user: User; + let message: Message; let allMessages: Message[]; let allUsers: User[]; let allSubscribers: Subscriber[]; @@ -128,16 +128,17 @@ describe('MessageController', () => { userService = module.get(UserService); subscriberService = module.get(SubscriberService); messageController = module.get(MessageController); - message = await messageService.findOne({ mid: 'mid-1' }); - sender = await subscriberService.findOne(message!.sender!); - recipient = await subscriberService.findOne(message!.recipient!); - user = await userService.findOne(message!.sentBy!); + message = (await messageService.findOne({ mid: 'mid-1' }))!; + sender = (await subscriberService.findOne(message.sender!))!; + recipient = (await subscriberService.findOne(message.recipient!))!; + user = (await userService.findOne(message.sentBy!))!; allSubscribers = await subscriberService.findAll(); allUsers = await userService.findAll(); allMessages = await messageService.findAll(); }); afterEach(jest.clearAllMocks); + afterAll(closeInMongodConnection); describe('count', () => { @@ -153,31 +154,31 @@ describe('MessageController', () => { describe('findOne', () => { it('should find message by id, and populate its corresponding sender and recipient', async () => { jest.spyOn(messageService, 'findOneAndPopulate'); - const result = await messageController.findOne(message!.id, [ + const result = await messageController.findOne(message.id, [ 'sender', 'recipient', ]); expect(messageService.findOneAndPopulate).toHaveBeenCalledWith( - message!.id, + message.id, ); expect(result).toEqualPayload({ - ...messageFixtures.find(({ mid }) => mid === message!.mid), + ...messageFixtures.find(({ mid }) => mid === message.mid), sender, recipient, - sentBy: user!.id, + sentBy: user.id, }); }); it('should find message by id', async () => { jest.spyOn(messageService, 'findOne'); - const result = await messageController.findOne(message!.id, []); + const result = await messageController.findOne(message.id, []); - expect(messageService.findOne).toHaveBeenCalledWith(message!.id); + expect(messageService.findOne).toHaveBeenCalledWith(message.id); expect(result).toEqualPayload({ - ...messageFixtures.find(({ mid }) => mid === message!.mid), - sender: sender!.id, - recipient: recipient!.id, - sentBy: user!.id, + ...messageFixtures.find(({ mid }) => mid === message.mid), + sender: sender.id, + recipient: recipient.id, + sentBy: user.id, }); }); }); diff --git a/api/src/chat/controllers/subscriber.controller.spec.ts b/api/src/chat/controllers/subscriber.controller.spec.ts index af810f15..6e280f99 100644 --- a/api/src/chat/controllers/subscriber.controller.spec.ts +++ b/api/src/chat/controllers/subscriber.controller.spec.ts @@ -48,7 +48,7 @@ describe('SubscriberController', () => { let subscriberService: SubscriberService; let labelService: LabelService; let userService: UserService; - let subscriber: Subscriber | null; + let subscriber: Subscriber; let allLabels: Label[]; let allSubscribers: Subscriber[]; let allUsers: User[]; @@ -90,15 +90,16 @@ describe('SubscriberController', () => { subscriberController = module.get(SubscriberController); - subscriber = await subscriberService.findOne({ + subscriber = (await subscriberService.findOne({ first_name: 'Jhon', - }); + }))!; allLabels = await labelService.findAll(); allSubscribers = await subscriberService.findAll(); allUsers = await userService.findAll(); }); afterEach(jest.clearAllMocks); + afterAll(closeInMongodConnection); describe('count', () => { @@ -114,39 +115,38 @@ describe('SubscriberController', () => { describe('findOne', () => { it('should find one subscriber by id', async () => { jest.spyOn(subscriberService, 'findOne'); - const result = await subscriberService.findOne(subscriber!.id); + const result = await subscriberService.findOne(subscriber.id); const labelIDs = allLabels - .filter((label) => subscriber!.labels.includes(label.id)) + .filter((label) => subscriber.labels.includes(label.id)) .map(({ id }) => id); - expect(subscriberService.findOne).toHaveBeenCalledWith(subscriber!.id); + expect(subscriberService.findOne).toHaveBeenCalledWith(subscriber.id); expect(result).toEqualPayload({ ...subscriberFixtures.find( - ({ first_name }) => first_name === subscriber!.first_name, + ({ first_name }) => first_name === subscriber.first_name, ), labels: labelIDs, - assignedTo: allUsers.find(({ id }) => subscriber!.assignedTo === id) - ?.id, + assignedTo: allUsers.find(({ id }) => subscriber.assignedTo === id)?.id, }); }); it('should find one subscriber by id, and populate its corresponding labels', async () => { jest.spyOn(subscriberService, 'findOneAndPopulate'); - const result = await subscriberController.findOne(subscriber!.id, [ + const result = await subscriberController.findOne(subscriber.id, [ 'labels', ]); expect(subscriberService.findOneAndPopulate).toHaveBeenCalledWith( - subscriber!.id, + subscriber.id, ); expect(result).toEqualPayload({ ...subscriberFixtures.find( - ({ first_name }) => first_name === subscriber!.first_name, + ({ first_name }) => first_name === subscriber.first_name, ), labels: allLabels.filter((label) => - subscriber!.labels.includes(label.id), + subscriber.labels.includes(label.id), ), - assignedTo: allUsers.find(({ id }) => subscriber!.assignedTo === id), + assignedTo: allUsers.find(({ id }) => subscriber.assignedTo === id), }); }); }); @@ -178,7 +178,7 @@ describe('SubscriberController', () => { ({ labels, ...rest }) => ({ ...rest, labels: allLabels.filter((label) => labels.includes(label.id)), - assignedTo: allUsers.find(({ id }) => subscriber!.assignedTo === id), + assignedTo: allUsers.find(({ id }) => subscriber.assignedTo === id), }), ); diff --git a/api/src/chat/repositories/block.repository.spec.ts b/api/src/chat/repositories/block.repository.spec.ts index 0948e427..8556266c 100644 --- a/api/src/chat/repositories/block.repository.spec.ts +++ b/api/src/chat/repositories/block.repository.spec.ts @@ -31,9 +31,9 @@ describe('BlockRepository', () => { let blockRepository: BlockRepository; let categoryRepository: CategoryRepository; let blockModel: Model; - let category: Category | null; - let hasPreviousBlocks: Block | null; - let hasNextBlocks: Block | null; + let category: Category; + let hasPreviousBlocks: Block; + let hasNextBlocks: Block; let validIds: string[]; let validCategory: string; @@ -51,13 +51,13 @@ describe('BlockRepository', () => { validIds = ['64abc1234def567890fedcba', '64abc1234def567890fedcbc']; validCategory = '64def5678abc123490fedcba'; - category = await categoryRepository.findOne({ label: 'default' }); - hasPreviousBlocks = await blockRepository.findOne({ + category = (await categoryRepository.findOne({ label: 'default' }))!; + hasPreviousBlocks = (await blockRepository.findOne({ name: 'hasPreviousBlocks', - }); - hasNextBlocks = await blockRepository.findOne({ + }))!; + hasNextBlocks = (await blockRepository.findOne({ name: 'hasNextBlocks', - }); + }))!; }); afterEach(jest.clearAllMocks); @@ -67,15 +67,13 @@ describe('BlockRepository', () => { it('should find one block by id, and populate its trigger_labels, assign_labels, nextBlocks, attachedBlock, category,previousBlocks', async () => { jest.spyOn(blockModel, 'findById'); - const result = await blockRepository.findOneAndPopulate( - hasNextBlocks!.id, - ); + const result = await blockRepository.findOneAndPopulate(hasNextBlocks.id); expect(blockModel.findById).toHaveBeenCalledWith( - hasNextBlocks!.id, + hasNextBlocks.id, undefined, ); expect(result).toEqualPayload({ - ...blockFixtures.find(({ name }) => name === hasNextBlocks!.name), + ...blockFixtures.find(({ name }) => name === hasNextBlocks.name), category, nextBlocks: [hasPreviousBlocks], previousBlocks: [], diff --git a/api/src/chat/repositories/message.repository.spec.ts b/api/src/chat/repositories/message.repository.spec.ts index 9793f2e3..f817f2a9 100644 --- a/api/src/chat/repositories/message.repository.spec.ts +++ b/api/src/chat/repositories/message.repository.spec.ts @@ -62,23 +62,20 @@ describe('MessageRepository', () => { describe('findOneAndPopulate', () => { it('should find one message by id, and populate its sender and recipient', async () => { jest.spyOn(messageModel, 'findById'); - const message = await messageRepository.findOne({ mid: 'mid-1' }); + const message = (await messageRepository.findOne({ mid: 'mid-1' }))!; const sender = await subscriberRepository.findOne(message!['sender']); const recipient = await subscriberRepository.findOne( message!['recipient'], ); - const user = await userRepository.findOne(message!['sentBy']); - const result = await messageRepository.findOneAndPopulate(message!.id); + const user = (await userRepository.findOne(message!['sentBy']))!; + const result = await messageRepository.findOneAndPopulate(message.id); - expect(messageModel.findById).toHaveBeenCalledWith( - message!.id, - undefined, - ); + expect(messageModel.findById).toHaveBeenCalledWith(message.id, undefined); expect(result).toEqualPayload({ - ...messageFixtures.find(({ mid }) => mid === message!.mid), + ...messageFixtures.find(({ mid }) => mid === message.mid), sender, recipient, - sentBy: user!.id, + sentBy: user.id, }); }); }); diff --git a/api/src/chat/repositories/subscriber.repository.spec.ts b/api/src/chat/repositories/subscriber.repository.spec.ts index 2b54b03d..fd553e5f 100644 --- a/api/src/chat/repositories/subscriber.repository.spec.ts +++ b/api/src/chat/repositories/subscriber.repository.spec.ts @@ -97,30 +97,31 @@ describe('SubscriberRepository', () => { }); afterEach(jest.clearAllMocks); + afterAll(closeInMongodConnection); describe('findOneAndPopulate', () => { it('should find one subscriber by id,and populate its labels', async () => { jest.spyOn(subscriberModel, 'findById'); - const subscriber = await subscriberRepository.findOne({ + const subscriber = (await subscriberRepository.findOne({ first_name: 'Jhon', - }); + }))!; const allLabels = await labelRepository.findAll(); const result = await subscriberRepository.findOneAndPopulate( - subscriber!.id, + subscriber.id, ); const subscriberWithLabels = { ...subscriberFixtures.find( - ({ first_name }) => first_name === subscriber!.first_name, + ({ first_name }) => first_name === subscriber.first_name, ), labels: allLabels.filter((label) => - subscriber!.labels.includes(label.id), + subscriber.labels.includes(label.id), ), - assignedTo: allUsers.find(({ id }) => subscriber!.assignedTo === id), + assignedTo: allUsers.find(({ id }) => subscriber.assignedTo === id), }; expect(subscriberModel.findById).toHaveBeenCalledWith( - subscriber!.id, + subscriber.id, undefined, ); expect(result).toEqualPayload(subscriberWithLabels); diff --git a/api/src/chat/services/block.service.spec.ts b/api/src/chat/services/block.service.spec.ts index f4d21374..cf436248 100644 --- a/api/src/chat/services/block.service.spec.ts +++ b/api/src/chat/services/block.service.spec.ts @@ -74,10 +74,10 @@ import { CategoryService } from './category.service'; describe('BlockService', () => { let blockRepository: BlockRepository; let categoryRepository: CategoryRepository; - let category: Category | null; - let block: Block | null; + let category: Category; + let block: Block; let blockService: BlockService; - let hasPreviousBlocks: Block | null; + let hasPreviousBlocks: Block; let contentService: ContentService; let contentTypeService: ContentTypeService; let settingService: SettingService; @@ -154,11 +154,11 @@ describe('BlockService', () => { contentTypeService = module.get(ContentTypeService); categoryRepository = module.get(CategoryRepository); blockRepository = module.get(BlockRepository); - category = await categoryRepository.findOne({ label: 'default' }); - hasPreviousBlocks = await blockRepository.findOne({ + category = (await categoryRepository.findOne({ label: 'default' }))!; + hasPreviousBlocks = (await blockRepository.findOne({ name: 'hasPreviousBlocks', - }); - block = await blockRepository.findOne({ name: 'hasNextBlocks' }); + }))!; + block = (await blockRepository.findOne({ name: 'hasNextBlocks' }))!; settings = await settingService.getSettings(); }); @@ -168,10 +168,10 @@ describe('BlockService', () => { describe('findOneAndPopulate', () => { it('should find one block by id, and populate its trigger_labels, assign_labels,attachedBlock,category,nextBlocks', async () => { jest.spyOn(blockRepository, 'findOneAndPopulate'); - const result = await blockService.findOneAndPopulate(block!.id); + const result = await blockService.findOneAndPopulate(block.id); expect(blockRepository.findOneAndPopulate).toHaveBeenCalledWith( - block!.id, + block.id, undefined, ); expect(result).toEqualPayload({ @@ -441,8 +441,10 @@ describe('BlockService', () => { describe('processMessage', () => { it('should process list message (with limit = 2 and skip = 0)', async () => { - const contentType = await contentTypeService.findOne({ name: 'Product' }); - blockProductListMock.options!.content!.entity = contentType!.id; + const contentType = (await contentTypeService.findOne({ + name: 'Product', + }))!; + blockProductListMock.options.content!.entity = contentType.id; const result = await blockService.processMessage( blockProductListMock, { @@ -454,27 +456,29 @@ describe('BlockService', () => { 'conv_id', ); const elements = await contentService.findPage( - { status: true, entity: contentType!.id }, + { status: true, entity: contentType.id }, { skip: 0, limit: 2, sort: ['createdAt', 'desc'] }, ); const flattenedElements = elements.map(Content.toElement); - expect(result!.format).toEqualPayload( - blockProductListMock.options!.content!.display, + expect(result.format).toEqualPayload( + blockProductListMock.options.content!.display, ); expect( - (result!.message as StdOutgoingListMessage).elements, + (result.message as StdOutgoingListMessage).elements, ).toEqualPayload(flattenedElements); + expect((result.message as StdOutgoingListMessage).options).toEqualPayload( + blockProductListMock.options.content!, + ); expect( - (result!.message as StdOutgoingListMessage).options, - ).toEqualPayload(blockProductListMock.options!.content!); - expect( - (result!.message as StdOutgoingListMessage).pagination, + (result.message as StdOutgoingListMessage).pagination, ).toEqualPayload({ total: 4, skip: 0, limit: 2 }); }); it('should process list message (with limit = 2 and skip = 2)', async () => { - const contentType = await contentTypeService.findOne({ name: 'Product' }); - blockProductListMock.options!.content!.entity = contentType!.id; + const contentType = (await contentTypeService.findOne({ + name: 'Product', + }))!; + blockProductListMock.options.content!.entity = contentType.id; const result = await blockService.processMessage( blockProductListMock, { @@ -486,20 +490,20 @@ describe('BlockService', () => { 'conv_id', ); const elements = await contentService.findPage( - { status: true, entity: contentType!.id }, + { status: true, entity: contentType.id }, { skip: 2, limit: 2, sort: ['createdAt', 'desc'] }, ); const flattenedElements = elements.map(Content.toElement); - expect(result!.format).toEqual( - blockProductListMock.options!.content?.display, + expect(result.format).toEqual( + blockProductListMock.options.content?.display, ); - expect((result!.message as StdOutgoingListMessage).elements).toEqual( + expect((result.message as StdOutgoingListMessage).elements).toEqual( flattenedElements, ); - expect((result!.message as StdOutgoingListMessage).options).toEqual( - blockProductListMock.options!.content, + expect((result.message as StdOutgoingListMessage).options).toEqual( + blockProductListMock.options.content, ); - expect((result!.message as StdOutgoingListMessage).pagination).toEqual({ + expect((result.message as StdOutgoingListMessage).pagination).toEqual({ total: 4, skip: 2, limit: 2, diff --git a/api/src/chat/services/block.service.ts b/api/src/chat/services/block.service.ts index 736c5595..2b6f6346 100644 --- a/api/src/chat/services/block.service.ts +++ b/api/src/chat/services/block.service.ts @@ -440,7 +440,7 @@ export class BlockService extends BaseService< subscriberContext: SubscriberContext, fallback = false, conversationId?: string, - ) { + ): Promise { const settings = await this.settingService.getSettings(); const blockMessage: BlockMessage = fallback && block.options?.fallback @@ -592,13 +592,18 @@ export class BlockService extends BaseService< ); // Process custom plugin block try { - return await plugin?.process(block, context, conversationId); + const envelope = await plugin?.process(block, context, conversationId); + + if (!envelope) { + throw new Error('Unable to find envelope'); + } + + return envelope; } catch (e) { this.logger.error('Plugin was unable to load/process ', e); throw new Error(`Unknown plugin - ${JSON.stringify(blockMessage)}`); } - } else { - throw new Error('Invalid message format.'); } + throw new Error('Invalid message format.'); } } diff --git a/api/src/chat/services/bot.service.ts b/api/src/chat/services/bot.service.ts index 7b1a71a4..8a9ab5ed 100644 --- a/api/src/chat/services/bot.service.ts +++ b/api/src/chat/services/bot.service.ts @@ -21,10 +21,7 @@ import { getDefaultConversationContext, } from '../schemas/conversation.schema'; import { Context } from '../schemas/types/context'; -import { - IncomingMessageType, - StdOutgoingEnvelope, -} from '../schemas/types/message'; +import { IncomingMessageType } from '../schemas/types/message'; import { SubscriberContext } from '../schemas/types/subscriberContext'; import { BlockService } from './block.service'; @@ -71,13 +68,13 @@ export class BotService { ); // Process message : Replace tokens with context data and then send the message const recipient = event.getSender(); - const envelope = (await this.blockService.processMessage( + const envelope = await this.blockService.processMessage( block, context, recipient?.context as SubscriberContext, fallback, conservationId, - )) as StdOutgoingEnvelope; + ); // Send message through the right channel const response = await event @@ -258,7 +255,7 @@ export class BotService { convo.context.attempt++; fallback = true; } else { - if (convo.context) convo.context.attempt = 0; + convo.context.attempt = 0; fallbackBlock = undefined; } diff --git a/api/src/chat/services/chat.service.ts b/api/src/chat/services/chat.service.ts index ddf71e4d..5fa9fcc2 100644 --- a/api/src/chat/services/chat.service.ts +++ b/api/src/chat/services/chat.service.ts @@ -296,7 +296,9 @@ export class ChatService { @OnEvent('hook:subscriber:postCreate') async onSubscriberCreate({ _id }: SubscriberDocument) { const subscriber = await this.subscriberService.findOne(_id); - if (subscriber) this.websocketGateway.broadcastSubscriberNew(subscriber); + if (subscriber) { + this.websocketGateway.broadcastSubscriberNew(subscriber); + } } /** @@ -307,6 +309,8 @@ export class ChatService { @OnEvent('hook:subscriber:postUpdate') async onSubscriberUpdate({ _id }: SubscriberDocument) { const subscriber = await this.subscriberService.findOne(_id); - if (subscriber) this.websocketGateway.broadcastSubscriberUpdate(subscriber); + if (subscriber) { + this.websocketGateway.broadcastSubscriberUpdate(subscriber); + } } } diff --git a/api/src/chat/services/context-var.service.ts b/api/src/chat/services/context-var.service.ts index 420833dc..d93f96d5 100644 --- a/api/src/chat/services/context-var.service.ts +++ b/api/src/chat/services/context-var.service.ts @@ -36,7 +36,7 @@ export class ContextVarService extends BaseService< block: Block | BlockFull, ): Promise> { const vars = await this.find({ - name: { $in: block.capture_vars?.map(({ context_var }) => context_var) }, + name: { $in: block.capture_vars.map(({ context_var }) => context_var) }, }); return vars.reduce((acc, cv) => { acc[cv.name] = cv; diff --git a/api/src/chat/services/conversation.service.ts b/api/src/chat/services/conversation.service.ts index 593ca1e6..118f367f 100644 --- a/api/src/chat/services/conversation.service.ts +++ b/api/src/chat/services/conversation.service.ts @@ -71,8 +71,6 @@ export class ConversationService extends BaseService< const msgType = event.getMessageType(); const profile = event.getSender(); - if (!convo.context) throw new Error('Missing conversation context'); - // Capture channel specific context data convo.context.channel = event.getHandler().getName(); convo.context.text = event.getText(); diff --git a/api/src/chat/services/message.service.spec.ts b/api/src/chat/services/message.service.spec.ts index 07f2b8e9..1e7899b8 100644 --- a/api/src/chat/services/message.service.spec.ts +++ b/api/src/chat/services/message.service.spec.ts @@ -48,11 +48,11 @@ describe('MessageService', () => { let allMessages: Message[]; let allSubscribers: Subscriber[]; let allUsers: User[]; - let message: Message | null; - let sender: Subscriber | null; - let recipient: Subscriber | null; + let message: Message; + let sender: Subscriber; + let recipient: Subscriber; let messagesWithSenderAndRecipient: Message[]; - let user: User | null; + let user: User; beforeAll(async () => { const module = await Test.createTestingModule({ @@ -90,10 +90,10 @@ describe('MessageService', () => { allSubscribers = await subscriberRepository.findAll(); allUsers = await userRepository.findAll(); allMessages = await messageRepository.findAll(); - message = await messageRepository.findOne({ mid: 'mid-1' }); - sender = await subscriberRepository.findOne(message!.sender!); - recipient = await subscriberRepository.findOne(message!.recipient!); - user = await userRepository.findOne(message!.sentBy!); + message = (await messageRepository.findOne({ mid: 'mid-1' }))!; + sender = (await subscriberRepository.findOne(message.sender!))!; + recipient = (await subscriberRepository.findOne(message.recipient!))!; + user = (await userRepository.findOne(message.sentBy!))!; messagesWithSenderAndRecipient = allMessages.map((message) => ({ ...message, sender: allSubscribers.find(({ id }) => id === message.sender)?.id, @@ -108,17 +108,17 @@ describe('MessageService', () => { describe('findOneAndPopulate', () => { it('should find message by id, and populate its corresponding sender and recipient', async () => { jest.spyOn(messageRepository, 'findOneAndPopulate'); - const result = await messageService.findOneAndPopulate(message!.id); + const result = await messageService.findOneAndPopulate(message.id); expect(messageRepository.findOneAndPopulate).toHaveBeenCalledWith( - message!.id, + message.id, undefined, ); expect(result).toEqualPayload({ - ...messageFixtures.find(({ mid }) => mid === message!.mid), + ...messageFixtures.find(({ mid }) => mid === message.mid), sender, recipient, - sentBy: user!.id, + sentBy: user.id, }); }); }); diff --git a/api/src/chat/services/subscriber.service.spec.ts b/api/src/chat/services/subscriber.service.spec.ts index ce93c156..9eec453c 100644 --- a/api/src/chat/services/subscriber.service.spec.ts +++ b/api/src/chat/services/subscriber.service.spec.ts @@ -90,20 +90,20 @@ describe('SubscriberService', () => { describe('findOneAndPopulate', () => { it('should find subscribers, and foreach subscriber populate its corresponding labels', async () => { jest.spyOn(subscriberService, 'findOneAndPopulate'); - const subscriber = await subscriberRepository.findOne({ + const subscriber = (await subscriberRepository.findOne({ first_name: 'Jhon', - }); - const result = await subscriberService.findOneAndPopulate(subscriber!.id); + }))!; + const result = await subscriberService.findOneAndPopulate(subscriber.id); expect(subscriberService.findOneAndPopulate).toHaveBeenCalledWith( - subscriber!.id, + subscriber.id, ); expect(result).toEqualPayload({ ...subscriber, labels: allLabels.filter((label) => - subscriber!.labels.includes(label.id), + subscriber.labels.includes(label.id), ), - assignedTo: allUsers.find(({ id }) => subscriber!.assignedTo === id), + assignedTo: allUsers.find(({ id }) => subscriber.assignedTo === id), }); }); }); @@ -133,13 +133,13 @@ describe('SubscriberService', () => { await subscriberService.findOneByForeignId('foreign-id-dimelo'); const subscriber = allSubscribers.find( ({ foreign_id }) => foreign_id === 'foreign-id-dimelo', - ); + )!; expect(subscriberRepository.findOneByForeignId).toHaveBeenCalled(); expect(result).toEqualPayload({ ...subscriber, labels: allLabels - .filter((label) => subscriber!.labels.includes(label.id)) + .filter((label) => subscriber.labels.includes(label.id)) .map((label) => label.id), }); }); diff --git a/api/src/utils/test/fixtures/conversation.ts b/api/src/utils/test/fixtures/conversation.ts index c438f301..5550eeab 100644 --- a/api/src/utils/test/fixtures/conversation.ts +++ b/api/src/utils/test/fixtures/conversation.ts @@ -58,6 +58,9 @@ const conversations: ConversationCreateDto[] = [ labels: [], assignedTo: null, channel: { name: 'messenger-channel' }, + avatar: null, + context: {}, + assignedAt: new Date(), }, skip: {}, attempt: 0, @@ -104,6 +107,9 @@ const conversations: ConversationCreateDto[] = [ labels: [], assignedTo: null, channel: { name: 'web-channel' }, + avatar: null, + context: {}, + assignedAt: new Date(), }, skip: {}, attempt: 0, @@ -136,9 +142,9 @@ export const installConversationTypeFixtures = async () => { conversationFixtures.map((conversationFixture) => ({ ...conversationFixture, sender: subscribers[parseInt(conversationFixture.sender)].id, - current: conversationFixture?.current - ? blocks[parseInt(conversationFixture.current)].id - : null, + current: conversationFixture.current + ? blocks[parseInt(conversationFixture.current)]?.id + : undefined, next: conversationFixture.next?.map((n) => blocks[parseInt(n)].id), })), );