feat: use mongo test db for unit tests

This commit is contained in:
MohamedAliBouhaouala 2025-05-07 17:47:25 +01:00 committed by Mohamed Marrouchi
parent c7189758a9
commit 9642e823d0
8 changed files with 71 additions and 152 deletions

View File

@ -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
});
});

View File

@ -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',

View File

@ -51,7 +51,7 @@ describe('NlpEntityRepository', () => {
NlpValueRepository,
]);
firstNameNlpEntity = await nlpEntityRepository.findOne({
name: 'first_name',
name: 'firstname',
});
});

View File

@ -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<NlpEntity>({ 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<NlpEntityFull>;
const secondMockValues = {
id: '2',
weight: 5,
};
const secondMockEntity = {
name: 'subject',
...secondMockValues,
values: [{ value: 'product' }],
} as unknown as Partial<NlpEntityFull>;
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: [],
}),
);
});
});
});

View File

@ -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',

View File

@ -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 () => {

View File

@ -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 () => {

View File

@ -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(),
},
],
]);