feat: refine builtin nlp entities weight updates

This commit is contained in:
MohamedAliBouhaouala 2025-04-14 11:45:27 +01:00
parent eeb9142c45
commit 3fc5762ee8
4 changed files with 101 additions and 7 deletions

View File

@ -262,19 +262,65 @@ describe('NlpEntityController', () => {
).rejects.toThrow(NotFoundException);
});
it('should update the NLP entity even if it is builtin', async () => {
it('should throw an exception if entity is builtin but weight not provided', async () => {
const updateNlpEntity: NlpEntityCreateDto = {
name: 'intent',
name: 'updated',
doc: '',
lookups: ['trait'],
builtin: true,
weight: 2,
builtin: false,
};
await expect(
nlpEntityController.updateOne(buitInEntityId!, updateNlpEntity),
).rejects.toThrow(MethodNotAllowedException);
});
it('should update weight if entity is builtin and weight is provided', async () => {
const updatedNlpEntity: NlpEntityCreateDto = {
name: 'updated',
doc: '',
lookups: ['trait'],
builtin: false,
weight: 4,
};
const findOneSpy = jest.spyOn(nlpEntityService, 'findOne');
const updateWeightSpy = jest.spyOn(nlpEntityService, 'updateWeight');
const result = await nlpEntityController.updateOne(
buitInEntityId!,
updateNlpEntity,
updatedNlpEntity,
);
expect(result).toEqual(expect.objectContaining(updateNlpEntity));
expect(findOneSpy).toHaveBeenCalledWith(buitInEntityId!);
expect(updateWeightSpy).toHaveBeenCalledWith(
buitInEntityId!,
updatedNlpEntity.weight,
);
expect(result.weight).toBe(updatedNlpEntity.weight);
});
it('should update only the weight of the builtin entity', async () => {
const updatedNlpEntity: NlpEntityCreateDto = {
name: 'updated',
doc: '',
lookups: ['trait'],
builtin: false,
weight: 4,
};
const originalEntity = await nlpEntityService.findOne(buitInEntityId!);
const result = await nlpEntityController.updateOne(
buitInEntityId!,
updatedNlpEntity,
);
// Check weight is updated
expect(result.weight).toBe(updatedNlpEntity.weight);
Object.entries(originalEntity!).forEach(([key, value]) => {
if (key !== 'weight' && key !== 'updatedAt') {
expect(result[key as keyof typeof result]).toEqual(value);
}
});
});
});
describe('deleteMany', () => {

View File

@ -158,6 +158,20 @@ export class NlpEntityController extends BaseController<
throw new NotFoundException(`NLP Entity with ID ${id} not found`);
}
if (nlpEntity.builtin) {
// Only allow weight update for builtin entities
if (updateNlpEntityDto.weight) {
return await this.nlpEntityService.updateWeight(
id,
updateNlpEntityDto.weight,
);
} else {
throw new MethodNotAllowedException(
`Cannot update builtin NLP Entity ${nlpEntity.name} except for weight`,
);
}
}
return await this.nlpEntityService.updateOne(id, updateNlpEntityDto);
}

View File

@ -118,6 +118,25 @@ describe('nlpEntityService', () => {
});
});
describe('NlpEntityService - updateWeight', () => {
it('should update the weight of an NLP entity', async () => {
const createdEntity = await nlpEntityRepository.create({
name: 'testentity',
builtin: true,
weight: 1,
});
const newWeight = 3;
const updatedEntity = await nlpEntityService.updateWeight(
createdEntity.id,
newWeight,
);
expect(updatedEntity.weight).toBe(newWeight);
});
});
describe('storeNewEntities', () => {
it('should store new entities', async () => {
const result = await nlpEntityService.storeNewEntities(

View File

@ -1,5 +1,5 @@
/*
* Copyright © 2024 Hexastack. All rights reserved.
* Copyright © 2025 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
@ -45,6 +45,21 @@ export class NlpEntityService extends BaseService<
async deleteCascadeOne(id: string) {
return await this.repository.deleteOne(id);
}
/**
* Updates the `weight` field of a specific NLP entity by its ID.
*
* @param id - The unique identifier of the entity to update.
* @param updatedWeight - The new weight value to be assigned to the entity.
* @returns A promise that resolves to the updated entity.
*/
async updateWeight(id: string, updatedWeight: number) {
return this.repository.updateOne(
id,
{ weight: updatedWeight },
{ new: true },
);
}
/**
* Stores new entities based on the sample text and sample entities.