diff --git a/api/src/chat/services/block.service.spec.ts b/api/src/chat/services/block.service.spec.ts index 6fb810f3..5b9b2afd 100644 --- a/api/src/chat/services/block.service.spec.ts +++ b/api/src/chat/services/block.service.spec.ts @@ -46,6 +46,7 @@ import { installBlockFixtures, } from '@/utils/test/fixtures/block'; import { installContentFixtures } from '@/utils/test/fixtures/content'; +import { installNlpValueFixtures } from '@/utils/test/fixtures/nlpvalue'; import { blockEmpty, blockGetStarted, @@ -64,7 +65,6 @@ import { subscriberContextBlankInstance, } from '@/utils/test/mocks/conversation'; import { - mockNlpCacheMap, mockNlpEntitiesSetOne, nlpEntitiesGreeting, } from '@/utils/test/mocks/nlp'; @@ -102,6 +102,7 @@ describe('BlockService', () => { rootMongooseTestModule(async () => { await installContentFixtures(); await installBlockFixtures(); + await installNlpValueFixtures(); }), MongooseModule.forFeature([ BlockModel, @@ -357,10 +358,7 @@ describe('BlockService', () => { describe('matchBestNLP', () => { it('should return the block with the highest NLP score', async () => { - jest - .spyOn(nlpEntityService, 'getNlpMap') - .mockResolvedValue(mockNlpCacheMap); - const blocks = [mockNlpBlock, blockGetStarted]; // You can add more blocks with different patterns and scores + const blocks = [mockNlpBlock, blockGetStarted]; const nlp = mockNlpEntitiesSetOne; // Spy on calculateBlockScore to check if it's called const calculateBlockScoreSpy = jest.spyOn( @@ -379,10 +377,7 @@ describe('BlockService', () => { }); it('should return the block with the highest NLP score applying penalties', async () => { - jest - .spyOn(nlpEntityService, 'getNlpMap') - .mockResolvedValue(mockNlpCacheMap); - const blocks = [mockNlpBlock, mockModifiedNlpBlock]; // You can add more blocks with different patterns and scores + const blocks = [mockNlpBlock, mockModifiedNlpBlock]; const nlp = mockNlpEntitiesSetOne; // Spy on calculateBlockScore to check if it's called const calculateBlockScoreSpy = jest.spyOn( @@ -401,9 +396,6 @@ describe('BlockService', () => { }); it('another case where it should return the block with the highest NLP score applying penalties', async () => { - jest - .spyOn(nlpEntityService, 'getNlpMap') - .mockResolvedValue(mockNlpCacheMap); const blocks = [mockModifiedNlpBlockOne, mockModifiedNlpBlockTwo]; // You can add more blocks with different patterns and scores const nlp = mockNlpEntitiesSetOne; // Spy on calculateBlockScore to check if it's called @@ -423,10 +415,7 @@ describe('BlockService', () => { }); it('should return undefined if no blocks match or the list is empty', async () => { - jest - .spyOn(nlpEntityService, 'getNlpMap') - .mockResolvedValue(mockNlpCacheMap); - const blocks: BlockFull[] = []; // Empty block array + const blocks: BlockFull[] = []; const nlp = mockNlpEntitiesSetOne; const bestBlock = await blockService.matchBestNLP(blocks, nlp); @@ -438,9 +427,7 @@ describe('BlockService', () => { describe('calculateBlockScore', () => { it('should calculate the correct NLP score for a block', async () => { - jest - .spyOn(nlpEntityService, 'getNlpMap') - .mockResolvedValue(mockNlpCacheMap); + const getNlpCacheMapSpy = jest.spyOn(nlpEntityService, 'getNlpMap'); const score = await blockService.calculateBlockScore( mockNlpPatternsSetOne, mockNlpEntitiesSetOne, @@ -449,16 +436,15 @@ describe('BlockService', () => { mockNlpPatternsSetTwo, mockNlpEntitiesSetOne, ); - + expect(getNlpCacheMapSpy).toHaveBeenCalledTimes(2); + getNlpCacheMapSpy.mockRestore(); expect(score).toBeGreaterThan(0); expect(score2).toBe(0); expect(score).toBeGreaterThan(score2); }); it('should calculate the correct NLP score for a block and apply penalties ', async () => { - jest - .spyOn(nlpEntityService, 'getNlpMap') - .mockResolvedValue(mockNlpCacheMap); + const getNlpCacheMapSpy = jest.spyOn(nlpEntityService, 'getNlpMap'); const score = await blockService.calculateBlockScore( mockNlpPatternsSetOne, mockNlpEntitiesSetOne, @@ -468,19 +454,25 @@ describe('BlockService', () => { mockNlpEntitiesSetOne, ); + expect(getNlpCacheMapSpy).toHaveBeenCalledTimes(2); + getNlpCacheMapSpy.mockRestore(); + expect(score).toBeGreaterThan(0); expect(score2).toBeGreaterThan(0); expect(score).toBeGreaterThan(score2); }); it('should return 0 if no matching entities are found', async () => { - jest.spyOn(nlpEntityService, 'getNlpMap').mockResolvedValue(new Map()); + const getNlpCacheMapSpy = jest.spyOn(nlpEntityService, 'getNlpMap'); + const score = await blockService.calculateBlockScore( mockNlpPatternsSetTwo, mockNlpEntitiesSetOne, ); + expect(getNlpCacheMapSpy).toHaveBeenCalledTimes(1); + getNlpCacheMapSpy.mockRestore(); - expect(score).toBe(0); // No matching entity, so score should be 0 + expect(score).toBe(0); // No matching entity }); }); diff --git a/api/src/nlp/controllers/nlp-entity.controller.spec.ts b/api/src/nlp/controllers/nlp-entity.controller.spec.ts index fd70a91b..484f41c8 100644 --- a/api/src/nlp/controllers/nlp-entity.controller.spec.ts +++ b/api/src/nlp/controllers/nlp-entity.controller.spec.ts @@ -201,18 +201,18 @@ describe('NlpEntityController', () => { describe('findOne', () => { it('should find a nlp entity', async () => { const firstNameEntity = await nlpEntityService.findOne({ - name: 'first_name', + name: 'firstname', }); const result = await nlpEntityController.findOne(firstNameEntity!.id, []); expect(result).toEqualPayload( - nlpEntityFixtures.find(({ name }) => name === 'first_name')!, + nlpEntityFixtures.find(({ name }) => name === 'firstname')!, ); }); it('should find a nlp entity, and populate its values', async () => { const firstNameEntity = await nlpEntityService.findOne({ - name: 'first_name', + name: 'firstname', }); const firstNameValues = await nlpValueService.findOne({ value: 'jhon' }); const firstNameWithValues: NlpEntityFull = { @@ -242,7 +242,7 @@ describe('NlpEntityController', () => { describe('updateOne', () => { it('should update a nlp entity', async () => { const firstNameEntity = await nlpEntityService.findOne({ - name: 'first_name', + name: 'firstname', }); const updatedNlpEntity: NlpEntityCreateDto = { name: 'updated', diff --git a/api/src/nlp/repositories/nlp-entity.repository.spec.ts b/api/src/nlp/repositories/nlp-entity.repository.spec.ts index 7f9bccd3..fd8f2262 100644 --- a/api/src/nlp/repositories/nlp-entity.repository.spec.ts +++ b/api/src/nlp/repositories/nlp-entity.repository.spec.ts @@ -51,7 +51,7 @@ describe('NlpEntityRepository', () => { NlpValueRepository, ]); firstNameNlpEntity = await nlpEntityRepository.findOne({ - name: 'first_name', + name: 'firstname', }); }); diff --git a/api/src/nlp/services/nlp-entity.service.spec.ts b/api/src/nlp/services/nlp-entity.service.spec.ts index 5cc877ff..eae5b51f 100644 --- a/api/src/nlp/services/nlp-entity.service.spec.ts +++ b/api/src/nlp/services/nlp-entity.service.spec.ts @@ -22,11 +22,7 @@ import { buildTestingMocks } from '@/utils/test/utils'; import { NlpEntityRepository } from '../repositories/nlp-entity.repository'; import { NlpSampleEntityRepository } from '../repositories/nlp-sample-entity.repository'; import { NlpValueRepository } from '../repositories/nlp-value.repository'; -import { - NlpEntity, - NlpEntityFull, - NlpEntityModel, -} from '../schemas/nlp-entity.schema'; +import { NlpEntity, NlpEntityModel } from '../schemas/nlp-entity.schema'; import { NlpSampleEntityModel } from '../schemas/nlp-sample-entity.schema'; import { NlpValueModel } from '../schemas/nlp-value.schema'; @@ -91,7 +87,7 @@ describe('nlpEntityService', () => { describe('findOneAndPopulate', () => { it('should return a nlp entity with populate', async () => { const firstNameNlpEntity = await nlpEntityRepository.findOne({ - name: 'first_name', + name: 'firstname', }); const result = await nlpEntityService.findOneAndPopulate( firstNameNlpEntity!.id, @@ -112,7 +108,7 @@ describe('nlpEntityService', () => { it('should return all nlp entities with populate', async () => { const pageQuery = getPageQuery({ sort: ['name', 'desc'] }); const firstNameNlpEntity = await nlpEntityRepository.findOne({ - name: 'first_name', + name: 'firstname', }); const result = await nlpEntityService.findPageAndPopulate( { _id: firstNameNlpEntity!.id }, @@ -221,45 +217,37 @@ describe('nlpEntityService', () => { }); describe('getNlpMap', () => { it('should return a NlpCacheMap with the correct structure', async () => { - // Arrange - const firstMockValues = { - id: '1', - weight: 1, - }; - const firstMockEntity = { - name: 'intent', - ...firstMockValues, - values: [{ value: 'buy' }, { value: 'sell' }], - } as unknown as Partial; - const secondMockValues = { - id: '2', - weight: 5, - }; - const secondMockEntity = { - name: 'subject', - ...secondMockValues, - values: [{ value: 'product' }], - } as unknown as Partial; - const mockEntities = [firstMockEntity, secondMockEntity]; - - // Mock findAndPopulate - jest - .spyOn(nlpEntityService, 'findAllAndPopulate') - .mockResolvedValue(mockEntities as unknown as NlpEntityFull[]); - // Act const result = await nlpEntityService.getNlpMap(); expect(result).toBeInstanceOf(Map); - expect(result.size).toBe(2); - expect(result.get('intent')).toEqual({ - name: 'intent', - ...firstMockEntity, - }); - expect(result.get('subject')).toEqual({ - name: 'subject', - ...secondMockEntity, - }); + expect(result.get('firstname')).toEqual( + expect.objectContaining({ + name: 'firstname', + lookups: ['keywords'], + doc: '', + builtin: false, + weight: 1, + values: [ + expect.objectContaining({ + value: 'jhon', + expressions: ['john', 'joohn', 'jhonny'], + builtin: true, + doc: '', + }), + ], + }), + ); + expect(result.get('subject')).toEqual( + expect.objectContaining({ + name: 'subject', + lookups: ['trait'], + doc: '', + builtin: false, + weight: 1, + values: [], + }), + ); }); }); }); diff --git a/api/src/nlp/services/nlp-value.service.spec.ts b/api/src/nlp/services/nlp-value.service.spec.ts index eacae606..f55b5a68 100644 --- a/api/src/nlp/services/nlp-value.service.spec.ts +++ b/api/src/nlp/services/nlp-value.service.spec.ts @@ -63,6 +63,8 @@ describe('NlpValueService', () => { provide: CACHE_MANAGER, useValue: { del: jest.fn(), + set: jest.fn(), + get: jest.fn(), }, }, ], @@ -132,7 +134,7 @@ describe('NlpValueService', () => { 'Hello do you see me', [ { entity: 'intent', value: 'greeting' }, - { entity: 'first_name', value: 'jhon' }, + { entity: 'firstname', value: 'jhon' }, ], storedEntities, ); @@ -140,7 +142,7 @@ describe('NlpValueService', () => { name: 'intent', }); const firstNameEntity = await nlpEntityRepository.findOne({ - name: 'first_name', + name: 'firstname', }); const greetingValue = await nlpValueRepository.findOne({ value: 'greeting', diff --git a/api/src/utils/test/fixtures/nlpentity.ts b/api/src/utils/test/fixtures/nlpentity.ts index deb44e97..78f29236 100644 --- a/api/src/utils/test/fixtures/nlpentity.ts +++ b/api/src/utils/test/fixtures/nlpentity.ts @@ -20,7 +20,7 @@ export const nlpEntityFixtures: NlpEntityCreateDto[] = [ weight: 1, }, { - name: 'first_name', + name: 'firstname', lookups: ['keywords'], doc: '', builtin: false, @@ -33,6 +33,13 @@ export const nlpEntityFixtures: NlpEntityCreateDto[] = [ builtin: true, weight: 1, }, + { + name: 'subject', + lookups: ['trait'], + doc: '', + builtin: false, + weight: 1, + }, ]; export const installNlpEntityFixtures = async () => { diff --git a/api/src/utils/test/fixtures/nlpvalue.ts b/api/src/utils/test/fixtures/nlpvalue.ts index fe8714b6..cf99f63c 100644 --- a/api/src/utils/test/fixtures/nlpvalue.ts +++ b/api/src/utils/test/fixtures/nlpvalue.ts @@ -49,6 +49,13 @@ export const nlpValueFixtures: NlpValueCreateDto[] = [ builtin: true, doc: '', }, + { + entity: '0', + value: 'affirmation', + expressions: ['yes', 'oui', 'yeah'], + builtin: false, + doc: '', + }, ]; export const installNlpValueFixtures = async () => { diff --git a/api/src/utils/test/mocks/nlp.ts b/api/src/utils/test/mocks/nlp.ts index b5a08c02..04c1742d 100644 --- a/api/src/utils/test/mocks/nlp.ts +++ b/api/src/utils/test/mocks/nlp.ts @@ -7,7 +7,6 @@ */ import { NLU } from '@/helper/types'; -import { NlpCacheMap } from '@/nlp/schemas/types'; export const nlpEntitiesGreeting: NLU.ParseEntities = { entities: [ @@ -58,79 +57,3 @@ export const mockNlpEntitiesSetTwo: NLU.ParseEntities = { }, ], }; - -export const mockNlpCacheMap: NlpCacheMap = new Map([ - [ - 'intent', - { - id: '1', - weight: 1, - name: 'intent', - values: [ - { - id: '11', - value: 'greeting', - createdAt: new Date(), - updatedAt: new Date(), - doc: '', - entity: '1', - builtin: false, - metadata: {}, - expressions: [], - }, - { - id: '12', - value: 'affirmation', - createdAt: new Date(), - updatedAt: new Date(), - doc: '', - entity: '1', - builtin: false, - metadata: {}, - expressions: [], - }, - ], - lookups: ['trait'], - builtin: false, - createdAt: new Date(), - updatedAt: new Date(), - }, - ], - [ - 'firstname', - - { - id: '2', - weight: 1, - name: 'firstname', - values: [ - { - id: '21', - value: 'jhon', - createdAt: new Date(), - updatedAt: new Date(), - doc: '', - entity: '2', - builtin: false, - metadata: {}, - expressions: [], - }, - { - id: '22', - value: 'doe', - createdAt: new Date(), - updatedAt: new Date(), - doc: '', - entity: '2', - builtin: false, - metadata: {}, - expressions: [], - }, - ], - lookups: ['trait'], - builtin: false, - createdAt: new Date(), - updatedAt: new Date(), - }, - ], -]);