feat(pause ad): emit update event after pause ad
This commit is contained in:
		
							parent
							
								
									2ce64cd1c4
								
							
						
					
					
						commit
						d213408c83
					
				| 
						 | 
					@ -1,19 +1,30 @@
 | 
				
			||||||
import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens';
 | 
					import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens';
 | 
				
			||||||
import { Inject } from '@nestjs/common';
 | 
					import { Inject } from '@nestjs/common';
 | 
				
			||||||
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
 | 
					import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
 | 
				
			||||||
 | 
					import { EventEmitter2 } from '@nestjs/event-emitter';
 | 
				
			||||||
import { AdRepositoryPort } from '../../ports/ad.repository.port';
 | 
					import { AdRepositoryPort } from '../../ports/ad.repository.port';
 | 
				
			||||||
import { PauseAdCommand } from './pause-ad.command';
 | 
					import { PauseAdCommand } from './pause-ad.command';
 | 
				
			||||||
 | 
					import { AdUpdatedDomainEvent } from '@modules/ad/core/domain/events/ad.domain-event';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@CommandHandler(PauseAdCommand)
 | 
					@CommandHandler(PauseAdCommand)
 | 
				
			||||||
export class PauseAdService implements ICommandHandler {
 | 
					export class PauseAdService implements ICommandHandler {
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    @Inject(AD_REPOSITORY)
 | 
					    @Inject(AD_REPOSITORY)
 | 
				
			||||||
    private readonly adRepository: AdRepositoryPort,
 | 
					    private readonly adRepository: AdRepositoryPort,
 | 
				
			||||||
 | 
					    private readonly eventEmitter: EventEmitter2,
 | 
				
			||||||
  ) {}
 | 
					  ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async execute(command: PauseAdCommand): Promise<void> {
 | 
					  async execute(command: PauseAdCommand): Promise<void> {
 | 
				
			||||||
    const ad = await this.adRepository.findOneById(command.id);
 | 
					    const ad = await this.adRepository.findOneById(command.id, {
 | 
				
			||||||
 | 
					      // TODO: waypoints and schedule needed for event, should be optional if no modif on them ...
 | 
				
			||||||
 | 
					      waypoints: true,
 | 
				
			||||||
 | 
					      schedule: true,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
    ad.pause();
 | 
					    ad.pause();
 | 
				
			||||||
    await this.adRepository.update(ad.id, ad);
 | 
					    await this.adRepository.update(ad.id, ad);
 | 
				
			||||||
 | 
					    this.eventEmitter.emitAsync(
 | 
				
			||||||
 | 
					      AdUpdatedDomainEvent.name,
 | 
				
			||||||
 | 
					      new AdUpdatedDomainEvent(ad),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,19 +0,0 @@
 | 
				
			||||||
import { MessagePublisherPort } from '@mobicoop/ddd-library';
 | 
					 | 
				
			||||||
import { AD_MESSAGE_PUBLISHER } from '@modules/ad/ad.di-tokens';
 | 
					 | 
				
			||||||
import { Inject, Injectable } from '@nestjs/common';
 | 
					 | 
				
			||||||
import { OnEvent } from '@nestjs/event-emitter';
 | 
					 | 
				
			||||||
import { AD_PAUSED_ROUTING_KEY } from '@src/app.constants';
 | 
					 | 
				
			||||||
import { AdPausedDomainEvent } from '../../domain/events/ad-paused.domain-event';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Injectable()
 | 
					 | 
				
			||||||
export class PublishMessageWhenAdIsPausedDomainEventHandler {
 | 
					 | 
				
			||||||
  constructor(
 | 
					 | 
				
			||||||
    @Inject(AD_MESSAGE_PUBLISHER)
 | 
					 | 
				
			||||||
    private readonly messagePublisher: MessagePublisherPort,
 | 
					 | 
				
			||||||
  ) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @OnEvent(AdPausedDomainEvent.name, { async: true, promisify: true })
 | 
					 | 
				
			||||||
  async handle(event: AdPausedDomainEvent): Promise<void> {
 | 
					 | 
				
			||||||
    this.messagePublisher.publish(AD_PAUSED_ROUTING_KEY, JSON.stringify(event));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@ import { v4 } from 'uuid';
 | 
				
			||||||
import { AdProps, CreateAdProps, Status } from './ad.types';
 | 
					import { AdProps, CreateAdProps, Status } from './ad.types';
 | 
				
			||||||
import { AdCreatedDomainEvent } from './events/ad-created.domain-event';
 | 
					import { AdCreatedDomainEvent } from './events/ad-created.domain-event';
 | 
				
			||||||
import { AdDeletedDomainEvent } from './events/ad-delete.domain-event';
 | 
					import { AdDeletedDomainEvent } from './events/ad-delete.domain-event';
 | 
				
			||||||
import { AdPausedDomainEvent } from './events/ad-paused.domain-event';
 | 
					 | 
				
			||||||
import { AdInvalidatedDomainEvent } from './events/ad-invalidated.domain-event';
 | 
					import { AdInvalidatedDomainEvent } from './events/ad-invalidated.domain-event';
 | 
				
			||||||
import { AdSuspendedDomainEvent } from './events/ad-suspended.domain-event';
 | 
					import { AdSuspendedDomainEvent } from './events/ad-suspended.domain-event';
 | 
				
			||||||
import { AdValidatedDomainEvent } from './events/ad-validated.domain-event';
 | 
					import { AdValidatedDomainEvent } from './events/ad-validated.domain-event';
 | 
				
			||||||
| 
						 | 
					@ -130,15 +129,6 @@ export class AdEntity extends AggregateRoot<AdProps> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pause(): AdEntity {
 | 
					  pause(): AdEntity {
 | 
				
			||||||
    this.props.pause = !this.props.pause;
 | 
					    this.props.pause = !this.props.pause;
 | 
				
			||||||
    this.addEvent(
 | 
					 | 
				
			||||||
      new AdPausedDomainEvent({
 | 
					 | 
				
			||||||
        metadata: {
 | 
					 | 
				
			||||||
          correlationId: this.id,
 | 
					 | 
				
			||||||
          timestamp: Date.now(),
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        aggregateId: this.id,
 | 
					 | 
				
			||||||
      }),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    return this;
 | 
					    return this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +0,0 @@
 | 
				
			||||||
import { DomainEvent, DomainEventProps } from '@mobicoop/ddd-library';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export class AdPausedDomainEvent extends DomainEvent {
 | 
					 | 
				
			||||||
  constructor(props: DomainEventProps<AdPausedDomainEvent>) {
 | 
					 | 
				
			||||||
    super(props);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens';
 | 
				
			||||||
 | 
					import { PauseAdCommand } from '@modules/ad/core/application/commands/pause-ad/pause-ad.command';
 | 
				
			||||||
 | 
					import { PauseAdService } from '@modules/ad/core/application/commands/pause-ad/pause-ad.service';
 | 
				
			||||||
 | 
					import { AdEntity } from '@modules/ad/core/domain/ad.entity';
 | 
				
			||||||
 | 
					import { Test, TestingModule } from '@nestjs/testing';
 | 
				
			||||||
 | 
					import { punctualPassengerCreateAdProps } from './ad.fixtures';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ad: AdEntity = AdEntity.create(punctualPassengerCreateAdProps());
 | 
				
			||||||
 | 
					jest.spyOn(ad, 'pause');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const mockAdRepository = {
 | 
				
			||||||
 | 
					  findOneById: jest.fn().mockImplementation(() => ad),
 | 
				
			||||||
 | 
					  update: jest.fn(),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('pause-ad.service', () => {
 | 
				
			||||||
 | 
					  let pauseAdService: PauseAdService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeAll(async () => {
 | 
				
			||||||
 | 
					    const module: TestingModule = await Test.createTestingModule({
 | 
				
			||||||
 | 
					      providers: [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          provide: AD_REPOSITORY,
 | 
				
			||||||
 | 
					          useValue: mockAdRepository,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        PauseAdService,
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    }).compile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pauseAdService = module.get<PauseAdService>(PauseAdService);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should be defined', () => {
 | 
				
			||||||
 | 
					    expect(pauseAdService).toBeDefined();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should trigger the pause logic and pause the ad from the repository', async () => {
 | 
				
			||||||
 | 
					    await pauseAdService.execute(new PauseAdCommand({ id: ad.id }));
 | 
				
			||||||
 | 
					    expect(ad.pause).toHaveBeenCalled();
 | 
				
			||||||
 | 
					    expect(mockAdRepository.update).toHaveBeenCalledWith(ad);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					import { PauseAdGrpcController } from '@modules/ad/interface/grpc-controllers/pause-ad.grpc.controller';
 | 
				
			||||||
 | 
					import { CommandBus } from '@nestjs/cqrs';
 | 
				
			||||||
 | 
					import { Test, TestingModule } from '@nestjs/testing';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const mockCommandBus = {
 | 
				
			||||||
 | 
					  execute: jest.fn(),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('Pause Ad Grpc Controller', () => {
 | 
				
			||||||
 | 
					  let pauseAdGrpcController: PauseAdGrpcController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeAll(async () => {
 | 
				
			||||||
 | 
					    const module: TestingModule = await Test.createTestingModule({
 | 
				
			||||||
 | 
					      providers: [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          provide: CommandBus,
 | 
				
			||||||
 | 
					          useValue: mockCommandBus,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        PauseAdGrpcController,
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    }).compile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pauseAdGrpcController = module.get<PauseAdGrpcController>(
 | 
				
			||||||
 | 
					      PauseAdGrpcController,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterEach(async () => {
 | 
				
			||||||
 | 
					    jest.clearAllMocks();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should be defined', () => {
 | 
				
			||||||
 | 
					    expect(pauseAdGrpcController).toBeDefined();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('should execute the pause ad command', async () => {
 | 
				
			||||||
 | 
					    await pauseAdGrpcController.pause({
 | 
				
			||||||
 | 
					      id: '200d61a8-d878-4378-a609-c19ea71633d2',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    expect(mockCommandBus.execute).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
		Loading…
	
		Reference in New Issue