diff --git a/app/api/externalIntegrations.v2/automaticTranslation/AutomaticTranslationFactory.ts b/app/api/externalIntegrations.v2/automaticTranslation/AutomaticTranslationFactory.ts index 1e9b7f2188..7315d3bdc6 100644 --- a/app/api/externalIntegrations.v2/automaticTranslation/AutomaticTranslationFactory.ts +++ b/app/api/externalIntegrations.v2/automaticTranslation/AutomaticTranslationFactory.ts @@ -1,13 +1,19 @@ -import { getConnection } from 'api/common.v2/database/getConnectionForCurrentTenant'; -import { MongoTemplatesDataSource } from 'api/templates.v2/database/MongoTemplatesDataSource'; import { DefaultTransactionManager } from 'api/common.v2/database/data_source_defaults'; -import { DefaultTemplatesDataSource } from 'api/templates.v2/database/data_source_defaults'; +import { getConnection } from 'api/common.v2/database/getConnectionForCurrentTenant'; import { DefaultEntitiesDataSource } from 'api/entities.v2/database/data_source_defaults'; +import { TaskManager } from 'api/services/tasksmanager/TaskManager'; +import { DefaultSettingsDataSource } from 'api/settings.v2/database/data_source_defaults'; +import { DefaultTemplatesDataSource } from 'api/templates.v2/database/data_source_defaults'; +import { MongoTemplatesDataSource } from 'api/templates.v2/database/MongoTemplatesDataSource'; import { GenerateAutomaticTranslationsCofig } from './GenerateAutomaticTranslationConfig'; -import { MongoATConfigDataSource } from './infrastructure/MongoATConfigDataSource'; import { AJVATConfigValidator } from './infrastructure/AJVATConfigValidator'; -import { SaveEntityTranslations } from './SaveEntityTranslations'; import { AJVTranslationResultValidator } from './infrastructure/AJVTranslationResultValidator'; +import { ATExternalAPI } from './infrastructure/ATExternalAPI'; +import { AJVEntityInputValidator } from './infrastructure/EntityInputValidator'; +import { MongoATConfigDataSource } from './infrastructure/MongoATConfigDataSource'; +import { ATTaskMessage, RequestEntityTranslation } from './RequestEntityTranslation'; +import { SaveEntityTranslations } from './SaveEntityTranslations'; +import { ATConfigService } from './services/GetAutomaticTranslationConfig'; const AutomaticTranslationFactory = { defaultGenerateATConfig() { @@ -26,6 +32,27 @@ const AutomaticTranslationFactory = { new AJVTranslationResultValidator() ); }, + + defaultATConfigService() { + const transactionManager = DefaultTransactionManager(); + return new ATConfigService( + DefaultSettingsDataSource(transactionManager), + new MongoATConfigDataSource(getConnection(), transactionManager), + DefaultTemplatesDataSource(transactionManager), + new ATExternalAPI() + ); + }, + + defaultRequestEntityTranslation() { + return new RequestEntityTranslation( + new TaskManager({ + serviceName: RequestEntityTranslation.SERVICE_NAME, + }), + DefaultTemplatesDataSource(DefaultTransactionManager()), + AutomaticTranslationFactory.defaultATConfigService(), + new AJVEntityInputValidator() + ); + }, }; export { AutomaticTranslationFactory }; diff --git a/app/api/externalIntegrations.v2/automaticTranslation/adapters/driving/ATEntityCreationListener.ts b/app/api/externalIntegrations.v2/automaticTranslation/adapters/driving/ATEntityCreationListener.ts new file mode 100644 index 0000000000..502d95e0c7 --- /dev/null +++ b/app/api/externalIntegrations.v2/automaticTranslation/adapters/driving/ATEntityCreationListener.ts @@ -0,0 +1,25 @@ +import { EntityCreatedEvent } from 'api/entities/events/EntityCreatedEvent'; +import { EventsBus } from 'api/eventsbus'; +import { RequestEntityTranslation } from '../../RequestEntityTranslation'; + +export class ATEntityCreationListener { + private requestEntityTranslation: RequestEntityTranslation; + + private eventBus: EventsBus; + + constructor(requestEntityTranslation: RequestEntityTranslation, eventBus: EventsBus) { + this.requestEntityTranslation = requestEntityTranslation; + this.eventBus = eventBus; + } + + start() { + this.eventBus.on(EntityCreatedEvent, async event => { + const entityFrom = event.entities.find(e => e.language === event.targetLanguageKey) || {}; + + entityFrom._id = entityFrom._id?.toString(); + entityFrom.template = entityFrom.template?.toString(); + + await this.requestEntityTranslation.execute(entityFrom); + }); + } +} diff --git a/app/api/externalIntegrations.v2/automaticTranslation/adapters/driving/specs/ATEntityCreatedListener.spec.ts b/app/api/externalIntegrations.v2/automaticTranslation/adapters/driving/specs/ATEntityCreatedListener.spec.ts new file mode 100644 index 0000000000..6113681746 --- /dev/null +++ b/app/api/externalIntegrations.v2/automaticTranslation/adapters/driving/specs/ATEntityCreatedListener.spec.ts @@ -0,0 +1,46 @@ +import { EntityCreatedEvent } from 'api/entities/events/EntityCreatedEvent'; +import { EventsBus } from 'api/eventsbus'; +import { RequestEntityTranslation } from 'api/externalIntegrations.v2/automaticTranslation/RequestEntityTranslation'; +import { testingEnvironment } from 'api/utils/testingEnvironment'; +import { AutomaticTranslationFactory } from 'api/externalIntegrations.v2/automaticTranslation/AutomaticTranslationFactory'; +import { getFixturesFactory } from 'api/utils/fixturesFactory'; +import { ATEntityCreationListener } from '../ATEntityCreationListener'; + +const factory = getFixturesFactory(); + +describe('ATEntityCreationListener', () => { + let listener: ATEntityCreationListener; + const eventBus: EventsBus = new EventsBus(); + let requestEntityTranslation: RequestEntityTranslation; + + beforeEach(async () => { + await testingEnvironment.setUp({ + settings: [{ features: { automaticTranslation: { active: true } } }], + }); + await testingEnvironment.setTenant('tenant'); + + requestEntityTranslation = AutomaticTranslationFactory.defaultRequestEntityTranslation(); + jest.spyOn(requestEntityTranslation, 'execute'); + + listener = new ATEntityCreationListener(requestEntityTranslation, eventBus); + listener.start(); + }); + + afterAll(async () => { + await testingEnvironment.tearDown(); + }); + + describe('Request entity translation', () => { + it('should call RequestEntityTranslation on receiving entity creation event', async () => { + const entityEn = factory.entity('entity1', 'template1', {}, { language: 'en' }); + const entityCreationEvent = new EntityCreatedEvent({ + entities: [factory.entity('entity1', 'template1', {}, { language: 'es' }), entityEn], + targetLanguageKey: 'en', + }); + + await eventBus.emit(entityCreationEvent); + + expect(requestEntityTranslation.execute).toHaveBeenCalledWith(entityEn); + }); + }); +}); diff --git a/app/api/externalIntegrations.v2/automaticTranslation/adapters/driving/specs/ATServiceListener.spec.ts b/app/api/externalIntegrations.v2/automaticTranslation/adapters/driving/specs/ATServiceListener.spec.ts index aa74f45a1c..1a18cb2d68 100644 --- a/app/api/externalIntegrations.v2/automaticTranslation/adapters/driving/specs/ATServiceListener.spec.ts +++ b/app/api/externalIntegrations.v2/automaticTranslation/adapters/driving/specs/ATServiceListener.spec.ts @@ -10,6 +10,7 @@ import { SaveEntityTranslations } from 'api/externalIntegrations.v2/automaticTra import { ATServiceListener } from '../ATServiceListener'; const prepareATFactory = (executeSpy: jest.Mock) => { + // @ts-ignore const ATFactory: typeof AutomaticTranslationFactory = { defaultGenerateATConfig() { return {} as GenerateAutomaticTranslationsCofig; diff --git a/package.json b/package.json index b04f987e2b..f858e8cfed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uwazi", - "version": "1.186.0-rc6", + "version": "1.186.0-rc7", "description": "Uwazi is a free, open-source solution for organising, analysing and publishing your documents.", "keywords": [ "react"