publish integration event when an ad is updated
This commit is contained in:
		
							parent
							
								
									3ff5277d5f
								
							
						
					
					
						commit
						3d4ff00066
					
				| 
						 | 
				
			
			@ -7,7 +7,7 @@ export const GRPC_SERVICE_NAME = 'AdService';
 | 
			
		|||
 | 
			
		||||
// messaging output
 | 
			
		||||
export const AD_CREATED_ROUTING_KEY = 'ad.created';
 | 
			
		||||
// messaging output
 | 
			
		||||
export const AD_UPDATED_ROUTING_KEY = 'ad.updated';
 | 
			
		||||
export const AD_DELETED_ROUTING_KEY = 'ad.deleted';
 | 
			
		||||
 | 
			
		||||
// messaging input
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -141,6 +141,7 @@ export class AdMapper
 | 
			
		|||
    response.userId = props.userId;
 | 
			
		||||
    response.driver = props.driver as boolean;
 | 
			
		||||
    response.passenger = props.passenger as boolean;
 | 
			
		||||
    response.strict = props.strict;
 | 
			
		||||
    response.status = props.status;
 | 
			
		||||
    response.frequency = props.frequency;
 | 
			
		||||
    response.fromDate = this.outputDatetimeTransformer.fromDate(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,7 @@ import { InvalidateAdService } from './core/application/commands/invalidate-ad/i
 | 
			
		|||
import { ValidateAdService } from './core/application/commands/validate-ad/validate-ad.service';
 | 
			
		||||
import { PublishMessageWhenAdIsDeletedDomainEventHandler } from './core/application/event-handlers/publish-message-when-ad-deleted.domain-event-handler';
 | 
			
		||||
import { PublishMessageWhenAdIsCreatedDomainEventHandler } from './core/application/event-handlers/publish-message-when-ad-is-created.domain-event-handler';
 | 
			
		||||
import { PublishMessageWhenAdIsUpdatedDomainEventHandler } from './core/application/event-handlers/publish-message-when-ad-is-updated.domain-event-handler';
 | 
			
		||||
import { FindAdByIdQueryHandler } from './core/application/queries/find-ad-by-id/find-ad-by-id.query-handler';
 | 
			
		||||
import { FindAdsByIdsQueryHandler } from './core/application/queries/find-ads-by-ids/find-ads-by-ids.query-handler';
 | 
			
		||||
import { FindAdsByUserIdQueryHandler } from './core/application/queries/find-ads-by-user-id/find-ads-by-user-id.query-handler';
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +52,7 @@ const messageHandlers = [
 | 
			
		|||
 | 
			
		||||
const eventHandlers: Provider[] = [
 | 
			
		||||
  PublishMessageWhenAdIsCreatedDomainEventHandler,
 | 
			
		||||
  PublishMessageWhenAdIsUpdatedDomainEventHandler,
 | 
			
		||||
  PublishMessageWhenAdIsDeletedDomainEventHandler,
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
import {
 | 
			
		||||
  IntegrationEvent,
 | 
			
		||||
  IntegrationEventProps,
 | 
			
		||||
  MessagePublisherPort,
 | 
			
		||||
} from '@mobicoop/ddd-library';
 | 
			
		||||
import { AD_MESSAGE_PUBLISHER } from '@modules/ad/ad.di-tokens';
 | 
			
		||||
import { AdMapper } from '@modules/ad/ad.mapper';
 | 
			
		||||
import { AdResponseDto } from '@modules/ad/interface/dtos/ad.response.dto';
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { OnEvent } from '@nestjs/event-emitter';
 | 
			
		||||
import { AD_UPDATED_ROUTING_KEY } from '@src/app.constants';
 | 
			
		||||
import { v4 } from 'uuid';
 | 
			
		||||
import { AdUpdatedDomainEvent } from '../../domain/events/ad.domain-event';
 | 
			
		||||
 | 
			
		||||
class AdIntegrationEvent extends IntegrationEvent {
 | 
			
		||||
  readonly data: AdResponseDto;
 | 
			
		||||
 | 
			
		||||
  constructor(props: IntegrationEventProps<unknown>, data: AdResponseDto) {
 | 
			
		||||
    super(props);
 | 
			
		||||
    this.data = data;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class PublishMessageWhenAdIsUpdatedDomainEventHandler {
 | 
			
		||||
  constructor(
 | 
			
		||||
    @Inject(AD_MESSAGE_PUBLISHER)
 | 
			
		||||
    private readonly messagePublisher: MessagePublisherPort,
 | 
			
		||||
    private readonly mapper: AdMapper,
 | 
			
		||||
  ) {}
 | 
			
		||||
 | 
			
		||||
  @OnEvent(AdUpdatedDomainEvent.name, { async: true, promisify: true })
 | 
			
		||||
  async handle(event: AdUpdatedDomainEvent): Promise<void> {
 | 
			
		||||
    this.messagePublisher.publish(
 | 
			
		||||
      AD_UPDATED_ROUTING_KEY,
 | 
			
		||||
      JSON.stringify(
 | 
			
		||||
        new AdIntegrationEvent(
 | 
			
		||||
          { id: v4(), metadata: event.metadata },
 | 
			
		||||
          this.mapper.toResponse(event.ad),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
import {
 | 
			
		||||
  AD_MESSAGE_PUBLISHER,
 | 
			
		||||
  OUTPUT_DATETIME_TRANSFORMER,
 | 
			
		||||
  TIMEZONE_FINDER,
 | 
			
		||||
  TIME_CONVERTER,
 | 
			
		||||
} from '@modules/ad/ad.di-tokens';
 | 
			
		||||
import { AdMapper } from '@modules/ad/ad.mapper';
 | 
			
		||||
import { PublishMessageWhenAdIsUpdatedDomainEventHandler } from '@modules/ad/core/application/event-handlers/publish-message-when-ad-is-updated.domain-event-handler';
 | 
			
		||||
import { AdEntity } from '@modules/ad/core/domain/ad.entity';
 | 
			
		||||
import { AdUpdatedDomainEvent } from '@modules/ad/core/domain/events/ad.domain-event';
 | 
			
		||||
import { OutputDateTimeTransformer } from '@modules/ad/infrastructure/output-datetime-transformer';
 | 
			
		||||
import { TimeConverter } from '@modules/ad/infrastructure/time-converter';
 | 
			
		||||
import { TimezoneFinder } from '@modules/ad/infrastructure/timezone-finder';
 | 
			
		||||
import { Test, TestingModule } from '@nestjs/testing';
 | 
			
		||||
import { punctualPassengerCreateAdProps } from './ad.fixtures';
 | 
			
		||||
 | 
			
		||||
const mockMessagePublisher = {
 | 
			
		||||
  publish: jest.fn(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
describe('Publish message when ad is updated domain event handler', () => {
 | 
			
		||||
  let updatedDomainEventHandler: PublishMessageWhenAdIsUpdatedDomainEventHandler;
 | 
			
		||||
 | 
			
		||||
  beforeAll(async () => {
 | 
			
		||||
    const module: TestingModule = await Test.createTestingModule({
 | 
			
		||||
      providers: [
 | 
			
		||||
        {
 | 
			
		||||
          provide: AD_MESSAGE_PUBLISHER,
 | 
			
		||||
          useValue: mockMessagePublisher,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          provide: OUTPUT_DATETIME_TRANSFORMER,
 | 
			
		||||
          useClass: OutputDateTimeTransformer,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          provide: TIMEZONE_FINDER,
 | 
			
		||||
          useClass: TimezoneFinder,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          provide: TIME_CONVERTER,
 | 
			
		||||
          useClass: TimeConverter,
 | 
			
		||||
        },
 | 
			
		||||
        AdMapper,
 | 
			
		||||
        PublishMessageWhenAdIsUpdatedDomainEventHandler,
 | 
			
		||||
      ],
 | 
			
		||||
    }).compile();
 | 
			
		||||
 | 
			
		||||
    updatedDomainEventHandler =
 | 
			
		||||
      module.get<PublishMessageWhenAdIsUpdatedDomainEventHandler>(
 | 
			
		||||
        PublishMessageWhenAdIsUpdatedDomainEventHandler,
 | 
			
		||||
      );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should publish a message', () => {
 | 
			
		||||
    expect(updatedDomainEventHandler).toBeDefined();
 | 
			
		||||
    const ad = AdEntity.create(punctualPassengerCreateAdProps());
 | 
			
		||||
    const adUpdatedDomainEvent = new AdUpdatedDomainEvent(ad);
 | 
			
		||||
    updatedDomainEventHandler.handle(adUpdatedDomainEvent);
 | 
			
		||||
    expect(mockMessagePublisher.publish).toHaveBeenCalledTimes(1);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
		Loading…
	
		Reference in New Issue