diff --git a/src/app.constants.ts b/src/app.constants.ts index 4980881..ac3626d 100644 --- a/src/app.constants.ts +++ b/src/app.constants.ts @@ -17,6 +17,9 @@ export const MATCHER_AD_UPDATE_FAILED_ROUTING_KEY = 'matcher-ad.update-failed'; export const AD_CREATED_MESSAGE_HANDLER = 'adCreated'; export const AD_CREATED_ROUTING_KEY = 'ad.created'; export const AD_CREATED_QUEUE = 'matcher.ad.created'; +export const AD_UPDATED_MESSAGE_HANDLER = 'adUpdated'; +export const AD_UPDATED_ROUTING_KEY = 'ad.updated'; +export const AD_UPDATED_QUEUE = 'matcher.ad.updated'; export const AD_DELETED_MESSAGE_HANDLER = 'adDeleted'; export const AD_DELETED_ROUTING_KEY = 'ad.deleted'; export const AD_DELETED_QUEUE = 'matcher.ad.deleted'; diff --git a/src/modules/ad/ad.module.ts b/src/modules/ad/ad.module.ts index adb71c4..a2668d2 100644 --- a/src/modules/ad/ad.module.ts +++ b/src/modules/ad/ad.module.ts @@ -45,6 +45,7 @@ import { TimezoneFinder } from './infrastructure/timezone-finder'; import { MatchGrpcController } from './interface/grpc-controllers/match.grpc-controller'; import { AdCreatedMessageHandler } from './interface/message-handlers/ad-created.message-handler'; import { AdDeletedMessageHandler } from './interface/message-handlers/ad-deleted.message-handler'; +import { AdUpdatedMessageHandler } from './interface/message-handlers/ad-updated.message-handler'; import { MatchMapper } from './match.mapper'; import { MatchingMapper } from './matching.mapper'; @@ -99,7 +100,11 @@ const imports = [ const grpcControllers = [MatchGrpcController]; -const messageHandlers = [AdCreatedMessageHandler, AdDeletedMessageHandler]; +const messageHandlers = [ + AdCreatedMessageHandler, + AdUpdatedMessageHandler, + AdDeletedMessageHandler, +]; const eventHandlers: Provider[] = [ PublishMessageWhenMatcherAdIsCreatedDomainEventHandler, diff --git a/src/modules/ad/interface/message-handlers/ad-updated.message-handler.ts b/src/modules/ad/interface/message-handlers/ad-updated.message-handler.ts new file mode 100644 index 0000000..46c3488 --- /dev/null +++ b/src/modules/ad/interface/message-handlers/ad-updated.message-handler.ts @@ -0,0 +1,28 @@ +import { RabbitSubscribe } from '@mobicoop/message-broker-module'; +import { UpdateAdCommand } from '@modules/ad/core/application/commands/update-ad/update-ad.command'; +import { Injectable } from '@nestjs/common'; +import { CommandBus } from '@nestjs/cqrs'; +import { + AD_UPDATED_MESSAGE_HANDLER, + AD_UPDATED_ROUTING_KEY, +} from '@src/app.constants'; +import { Ad } from './ad.types'; + +@Injectable() +export class AdUpdatedMessageHandler { + constructor(private readonly commandBus: CommandBus) {} + + @RabbitSubscribe({ + name: AD_UPDATED_MESSAGE_HANDLER, + routingKey: AD_UPDATED_ROUTING_KEY, + }) + public async adUpdated(message: string) { + try { + const updatedAd: { data: Ad } = JSON.parse(message); + await this.commandBus.execute(new UpdateAdCommand(updatedAd.data)); + } catch (error: any) { + // do not throw error to acknowledge incoming message + // error handling should be done in the command handler, if relevant + } + } +} diff --git a/src/modules/ad/tests/unit/interface/ad-updated.message-handler.spec.ts b/src/modules/ad/tests/unit/interface/ad-updated.message-handler.spec.ts new file mode 100644 index 0000000..d827fdf --- /dev/null +++ b/src/modules/ad/tests/unit/interface/ad-updated.message-handler.spec.ts @@ -0,0 +1,43 @@ +import { AdUpdatedMessageHandler } from '@modules/ad/interface/message-handlers/ad-updated.message-handler'; +import { CommandBus } from '@nestjs/cqrs'; +import { Test, TestingModule } from '@nestjs/testing'; + +const adUpdatedMessage = + '{"data": {"id":"4eb6a6af-ecfd-41c3-9118-473a507014d4","driver":"true","passenger":"true","frequency":"PUNCTUAL","fromDate":"2023-08-18","toDate":"2023-08-18","schedule":[{"day":"5","time":"10:00","margin":"900"}],"seatsProposed":"3","seatsRequested":"1","strict":"false","waypoints":[{"position":"0","houseNumber":"5","street":"rue de la monnaie","locality":"Nancy","postalCode":"54000","country":"France","lon":"48.689445","lat":"6.17651"},{"position":"1","locality":"Paris","postalCode":"75000","country":"France","lon":"48.8566","lat":"2.3522"}]}}'; + +const mockCommandBus = { + execute: jest.fn(), +}; + +describe('Ad Updated Message Handler', () => { + let adUpdatedMessageHandler: AdUpdatedMessageHandler; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: CommandBus, + useValue: mockCommandBus, + }, + AdUpdatedMessageHandler, + ], + }).compile(); + + adUpdatedMessageHandler = module.get( + AdUpdatedMessageHandler, + ); + }); + + afterEach(async () => { + jest.clearAllMocks(); + }); + + it('should be defined', () => { + expect(adUpdatedMessageHandler).toBeDefined(); + }); + + it('should update an ad', async () => { + await adUpdatedMessageHandler.adUpdated(adUpdatedMessage); + expect(mockCommandBus.execute).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/modules/messager/messager.module.ts b/src/modules/messager/messager.module.ts index 73086db..ec29ef4 100644 --- a/src/modules/messager/messager.module.ts +++ b/src/modules/messager/messager.module.ts @@ -12,6 +12,9 @@ import { AD_DELETED_MESSAGE_HANDLER, AD_DELETED_QUEUE, AD_DELETED_ROUTING_KEY, + AD_UPDATED_MESSAGE_HANDLER, + AD_UPDATED_QUEUE, + AD_UPDATED_ROUTING_KEY, SERVICE_NAME, } from '@src/app.constants'; import { MESSAGE_PUBLISHER } from './messager.di-tokens'; @@ -36,6 +39,10 @@ const imports = [ routingKey: AD_CREATED_ROUTING_KEY, queue: AD_CREATED_QUEUE, }, + [AD_UPDATED_MESSAGE_HANDLER]: { + routingKey: AD_UPDATED_ROUTING_KEY, + queue: AD_UPDATED_QUEUE, + }, [AD_DELETED_MESSAGE_HANDLER]: { routingKey: AD_DELETED_ROUTING_KEY, queue: AD_DELETED_QUEUE,