Compare commits

...

2 Commits

Author SHA1 Message Date
Fanch bfc731bd96 test(ad pause): fix test after adding update event emission 2024-05-23 07:19:39 +02:00
Fanch d213408c83 feat(pause ad): emit update event after pause ad 2024-05-23 07:08:52 +02:00
6 changed files with 105 additions and 37 deletions

View File

@ -1,19 +1,30 @@
import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens';
import { Inject } from '@nestjs/common';
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { AdRepositoryPort } from '../../ports/ad.repository.port';
import { PauseAdCommand } from './pause-ad.command';
import { AdUpdatedDomainEvent } from '@modules/ad/core/domain/events/ad.domain-event';
@CommandHandler(PauseAdCommand)
export class PauseAdService implements ICommandHandler {
constructor(
@Inject(AD_REPOSITORY)
private readonly adRepository: AdRepositoryPort,
private readonly eventEmitter: EventEmitter2,
) {}
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();
await this.adRepository.update(ad.id, ad);
this.eventEmitter.emitAsync(
AdUpdatedDomainEvent.name,
new AdUpdatedDomainEvent(ad),
);
}
}

View File

@ -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));
}
}

View File

@ -3,7 +3,6 @@ import { v4 } from 'uuid';
import { AdProps, CreateAdProps, Status } from './ad.types';
import { AdCreatedDomainEvent } from './events/ad-created.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 { AdSuspendedDomainEvent } from './events/ad-suspended.domain-event';
import { AdValidatedDomainEvent } from './events/ad-validated.domain-event';
@ -130,15 +129,6 @@ export class AdEntity extends AggregateRoot<AdProps> {
pause(): AdEntity {
this.props.pause = !this.props.pause;
this.addEvent(
new AdPausedDomainEvent({
metadata: {
correlationId: this.id,
timestamp: Date.now(),
},
aggregateId: this.id,
}),
);
return this;
}
}

View File

@ -1,7 +0,0 @@
import { DomainEvent, DomainEventProps } from '@mobicoop/ddd-library';
export class AdPausedDomainEvent extends DomainEvent {
constructor(props: DomainEventProps<AdPausedDomainEvent>) {
super(props);
}
}

View File

@ -0,0 +1,51 @@
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 { EventEmitter2 } from '@nestjs/event-emitter';
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(),
};
const mockEventEmitter = {
emitAsync: jest.fn(),
};
describe('pause-ad.service', () => {
let pauseAdService: PauseAdService;
beforeAll(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
{
provide: AD_REPOSITORY,
useValue: mockAdRepository,
},
{
provide: EventEmitter2,
useValue: mockEventEmitter,
},
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).toHaveBeenCalled();
});
});

View File

@ -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);
});
});