Implement the delete GRPC command
This commit is contained in:
parent
b17fc32a12
commit
e8903099d7
|
@ -7,6 +7,8 @@ export const GRPC_SERVICE_NAME = 'AdService';
|
||||||
|
|
||||||
// messaging output
|
// messaging output
|
||||||
export const AD_CREATED_ROUTING_KEY = 'ad.created';
|
export const AD_CREATED_ROUTING_KEY = 'ad.created';
|
||||||
|
// messaging output
|
||||||
|
export const AD_DELETED_ROUTING_KEY = 'ad.deleted';
|
||||||
|
|
||||||
// messaging input
|
// messaging input
|
||||||
export const MATCHER_AD_CREATED_MESSAGE_HANDLER = 'matcherAdCreated';
|
export const MATCHER_AD_CREATED_MESSAGE_HANDLER = 'matcherAdCreated';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
import { MessageBrokerPublisher } from '@mobicoop/message-broker-module';
|
||||||
import { Module, Provider } from '@nestjs/common';
|
import { Module, Provider } from '@nestjs/common';
|
||||||
import { CreateAdGrpcController } from './interface/grpc-controllers/create-ad.grpc.controller';
|
|
||||||
import { CqrsModule } from '@nestjs/cqrs';
|
import { CqrsModule } from '@nestjs/cqrs';
|
||||||
import {
|
import {
|
||||||
AD_MESSAGE_PUBLISHER,
|
AD_MESSAGE_PUBLISHER,
|
||||||
|
@ -9,29 +9,33 @@ import {
|
||||||
TIMEZONE_FINDER,
|
TIMEZONE_FINDER,
|
||||||
TIME_CONVERTER,
|
TIME_CONVERTER,
|
||||||
} from './ad.di-tokens';
|
} from './ad.di-tokens';
|
||||||
import { AdRepository } from './infrastructure/ad.repository';
|
|
||||||
import { AdMapper } from './ad.mapper';
|
import { AdMapper } from './ad.mapper';
|
||||||
import { CreateAdService } from './core/application/commands/create-ad/create-ad.service';
|
import { CreateAdService } from './core/application/commands/create-ad/create-ad.service';
|
||||||
import { TimezoneFinder } from './infrastructure/timezone-finder';
|
import { DeleteAdService } from './core/application/commands/delete-ad/delete-ad.service';
|
||||||
import { TimeConverter } from './infrastructure/time-converter';
|
import { InvalidateAdService } from './core/application/commands/invalidate-ad/invalidate-ad.service';
|
||||||
import { FindAdByIdGrpcController } from './interface/grpc-controllers/find-ad-by-id.grpc.controller';
|
import { ValidateAdService } from './core/application/commands/validate-ad/validate-ad.service';
|
||||||
import { FindAdByIdQueryHandler } from './core/application/queries/find-ad-by-id/find-ad-by-id.query-handler';
|
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 { PublishMessageWhenAdIsCreatedDomainEventHandler } from './core/application/event-handlers/publish-message-when-ad-is-created.domain-event-handler';
|
||||||
import { PrismaService } from './infrastructure/prisma.service';
|
import { FindAdByIdQueryHandler } from './core/application/queries/find-ad-by-id/find-ad-by-id.query-handler';
|
||||||
import { MessageBrokerPublisher } from '@mobicoop/message-broker-module';
|
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';
|
||||||
|
import { AdRepository } from './infrastructure/ad.repository';
|
||||||
import { InputDateTimeTransformer } from './infrastructure/input-datetime-transformer';
|
import { InputDateTimeTransformer } from './infrastructure/input-datetime-transformer';
|
||||||
import { OutputDateTimeTransformer } from './infrastructure/output-datetime-transformer';
|
import { OutputDateTimeTransformer } from './infrastructure/output-datetime-transformer';
|
||||||
|
import { PrismaService } from './infrastructure/prisma.service';
|
||||||
|
import { TimeConverter } from './infrastructure/time-converter';
|
||||||
|
import { TimezoneFinder } from './infrastructure/timezone-finder';
|
||||||
|
import { CreateAdGrpcController } from './interface/grpc-controllers/create-ad.grpc.controller';
|
||||||
|
import { DeleteAdGrpcController } from './interface/grpc-controllers/delete-ad.grpc.controller';
|
||||||
|
import { FindAdByIdGrpcController } from './interface/grpc-controllers/find-ad-by-id.grpc.controller';
|
||||||
import { FindAdsByIdsGrpcController } from './interface/grpc-controllers/find-ads-by-ids.grpc.controller';
|
import { FindAdsByIdsGrpcController } from './interface/grpc-controllers/find-ads-by-ids.grpc.controller';
|
||||||
import { FindAdsByIdsQueryHandler } from './core/application/queries/find-ads-by-ids/find-ads-by-ids.query-handler';
|
|
||||||
import { MatcherAdCreatedMessageHandler } from './interface/message-handlers/matcher-ad-created.message-handler';
|
|
||||||
import { ValidateAdService } from './core/application/commands/validate-ad/validate-ad.service';
|
|
||||||
import { MatcherAdCreationFailedMessageHandler } from './interface/message-handlers/matcher-ad-creation-failed.message-handler';
|
|
||||||
import { InvalidateAdService } from './core/application/commands/invalidate-ad/invalidate-ad.service';
|
|
||||||
import { FindAdsByUserIdGrpcController } from './interface/grpc-controllers/find-ads-by-user-id.grpc.controller';
|
import { FindAdsByUserIdGrpcController } from './interface/grpc-controllers/find-ads-by-user-id.grpc.controller';
|
||||||
import { FindAdsByUserIdQueryHandler } from './core/application/queries/find-ads-by-user-id/find-ads-by-user-id.query-handler';
|
import { MatcherAdCreatedMessageHandler } from './interface/message-handlers/matcher-ad-created.message-handler';
|
||||||
|
import { MatcherAdCreationFailedMessageHandler } from './interface/message-handlers/matcher-ad-creation-failed.message-handler';
|
||||||
|
|
||||||
const grpcControllers = [
|
const grpcControllers = [
|
||||||
CreateAdGrpcController,
|
CreateAdGrpcController,
|
||||||
|
DeleteAdGrpcController,
|
||||||
FindAdByIdGrpcController,
|
FindAdByIdGrpcController,
|
||||||
FindAdsByIdsGrpcController,
|
FindAdsByIdsGrpcController,
|
||||||
FindAdsByUserIdGrpcController,
|
FindAdsByUserIdGrpcController,
|
||||||
|
@ -44,10 +48,12 @@ const messageHandlers = [
|
||||||
|
|
||||||
const eventHandlers: Provider[] = [
|
const eventHandlers: Provider[] = [
|
||||||
PublishMessageWhenAdIsCreatedDomainEventHandler,
|
PublishMessageWhenAdIsCreatedDomainEventHandler,
|
||||||
|
PublishMessageWhenAdIsDeletedDomainEventHandler,
|
||||||
];
|
];
|
||||||
|
|
||||||
const commandHandlers: Provider[] = [
|
const commandHandlers: Provider[] = [
|
||||||
CreateAdService,
|
CreateAdService,
|
||||||
|
DeleteAdService,
|
||||||
ValidateAdService,
|
ValidateAdService,
|
||||||
InvalidateAdService,
|
InvalidateAdService,
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { Command, CommandProps } from '@mobicoop/ddd-library';
|
||||||
|
|
||||||
|
export class DeleteAdCommand extends Command {
|
||||||
|
constructor(props: CommandProps<DeleteAdCommand>) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens';
|
||||||
|
import { Inject } from '@nestjs/common';
|
||||||
|
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
||||||
|
import { AdRepositoryPort } from '../../ports/ad.repository.port';
|
||||||
|
import { DeleteAdCommand } from './delete-ad.command';
|
||||||
|
|
||||||
|
@CommandHandler(DeleteAdCommand)
|
||||||
|
export class DeleteAdService implements ICommandHandler {
|
||||||
|
constructor(
|
||||||
|
@Inject(AD_REPOSITORY) private readonly adRepository: AdRepositoryPort,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async execute(command: DeleteAdCommand): Promise<boolean> {
|
||||||
|
const ad = await this.adRepository.findOneById(command.id);
|
||||||
|
ad.delete();
|
||||||
|
return this.adRepository.delete(ad);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
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_DELETED_ROUTING_KEY } from '@src/app.constants';
|
||||||
|
import { AdDeletedDomainEvent } from '../../domain/events/ad-delete.domain-event';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PublishMessageWhenAdIsDeletedDomainEventHandler {
|
||||||
|
constructor(
|
||||||
|
@Inject(AD_MESSAGE_PUBLISHER)
|
||||||
|
private readonly messagePublisher: MessagePublisherPort,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@OnEvent(AdDeletedDomainEvent.name, { async: true, promisify: true })
|
||||||
|
async handle(event: AdDeletedDomainEvent): Promise<void> {
|
||||||
|
this.messagePublisher.publish(
|
||||||
|
AD_DELETED_ROUTING_KEY,
|
||||||
|
JSON.stringify(event),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,13 @@
|
||||||
import { AggregateRoot, AggregateID } from '@mobicoop/ddd-library';
|
import { AggregateID, AggregateRoot } from '@mobicoop/ddd-library';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { AdCreatedDomainEvent } from './events/ad-created.domain-event';
|
|
||||||
import { AdProps, CreateAdProps, Status } from './ad.types';
|
import { AdProps, CreateAdProps, Status } from './ad.types';
|
||||||
import { ScheduleItemProps } from './value-objects/schedule-item.value-object';
|
import { AdCreatedDomainEvent } from './events/ad-created.domain-event';
|
||||||
import { WaypointProps } from './value-objects/waypoint.value-object';
|
import { AdDeletedDomainEvent } from './events/ad-delete.domain-event';
|
||||||
import { AdValidatedDomainEvent } from './events/ad-validated.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 { ScheduleItemProps } from './value-objects/schedule-item.value-object';
|
||||||
|
import { WaypointProps } from './value-objects/waypoint.value-object';
|
||||||
|
|
||||||
export class AdEntity extends AggregateRoot<AdProps> {
|
export class AdEntity extends AggregateRoot<AdProps> {
|
||||||
protected readonly _id: AggregateID;
|
protected readonly _id: AggregateID;
|
||||||
|
@ -95,6 +96,14 @@ export class AdEntity extends AggregateRoot<AdProps> {
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
delete(): void {
|
||||||
|
this.addEvent(
|
||||||
|
new AdDeletedDomainEvent({
|
||||||
|
aggregateId: this.id,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
validate(): void {
|
validate(): void {
|
||||||
// entity business rules validation to protect it's invariant before saving entity to a database
|
// entity business rules validation to protect it's invariant before saving entity to a database
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { DomainEvent, DomainEventProps } from '@mobicoop/ddd-library';
|
||||||
|
|
||||||
|
export class AdDeletedDomainEvent extends DomainEvent {
|
||||||
|
constructor(props: DomainEventProps<AdDeletedDomainEvent>) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
import {
|
||||||
|
DatabaseErrorException,
|
||||||
|
NotFoundException,
|
||||||
|
RpcExceptionCode,
|
||||||
|
RpcValidationPipe,
|
||||||
|
} from '@mobicoop/ddd-library';
|
||||||
|
import { DeleteAdCommand } from '@modules/ad/core/application/commands/delete-ad/delete-ad.command';
|
||||||
|
import { Controller, UsePipes } from '@nestjs/common';
|
||||||
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
|
import { GrpcMethod, RpcException } from '@nestjs/microservices';
|
||||||
|
import { GRPC_SERVICE_NAME } from '@src/app.constants';
|
||||||
|
import { DeleteAdRequestDto } from './dtos/delete-ad.request.dto';
|
||||||
|
|
||||||
|
@UsePipes(
|
||||||
|
new RpcValidationPipe({
|
||||||
|
whitelist: false,
|
||||||
|
forbidUnknownValues: false,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
@Controller()
|
||||||
|
export class DeleteAdGrpcController {
|
||||||
|
constructor(private readonly commandBus: CommandBus) {}
|
||||||
|
|
||||||
|
@GrpcMethod(GRPC_SERVICE_NAME, 'Delete')
|
||||||
|
async delete(data: DeleteAdRequestDto): Promise<void> {
|
||||||
|
try {
|
||||||
|
await this.commandBus.execute(new DeleteAdCommand(data));
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error instanceof NotFoundException)
|
||||||
|
throw new RpcException({
|
||||||
|
code: RpcExceptionCode.NOT_FOUND,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
if (error instanceof DatabaseErrorException)
|
||||||
|
throw new RpcException({
|
||||||
|
code: RpcExceptionCode.INTERNAL,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
throw new RpcException({
|
||||||
|
code: RpcExceptionCode.UNKNOWN,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
export class DeleteAdRequestDto {
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
id: string;
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { CreateAdProps, Frequency } from '@modules/ad/core/domain/ad.types';
|
||||||
|
import { WaypointProps } from '@modules/ad/core/domain/value-objects/waypoint.value-object';
|
||||||
|
|
||||||
|
const originWaypointProps: WaypointProps = {
|
||||||
|
position: 0,
|
||||||
|
address: {
|
||||||
|
houseNumber: '5',
|
||||||
|
street: 'Avenue Foch',
|
||||||
|
locality: 'Nancy',
|
||||||
|
postalCode: '54000',
|
||||||
|
country: 'France',
|
||||||
|
coordinates: {
|
||||||
|
lat: 48.689445,
|
||||||
|
lon: 6.17651,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const destinationWaypointProps: WaypointProps = {
|
||||||
|
position: 1,
|
||||||
|
address: {
|
||||||
|
locality: 'Paris',
|
||||||
|
postalCode: '75000',
|
||||||
|
country: 'France',
|
||||||
|
coordinates: {
|
||||||
|
lat: 48.8566,
|
||||||
|
lon: 2.3522,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const baseCreateAdProps = {
|
||||||
|
userId: 'e8fe64b1-4c33-49e1-9f69-4db48b21df36',
|
||||||
|
seatsProposed: 3,
|
||||||
|
seatsRequested: 1,
|
||||||
|
strict: false,
|
||||||
|
waypoints: [originWaypointProps, destinationWaypointProps],
|
||||||
|
};
|
||||||
|
const punctualCreateAdProps = {
|
||||||
|
fromDate: '2023-06-22',
|
||||||
|
toDate: '2023-06-22',
|
||||||
|
schedule: [
|
||||||
|
{
|
||||||
|
time: '08:30',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
frequency: Frequency.PUNCTUAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function punctualPassengerCreateAdProps(): CreateAdProps {
|
||||||
|
return {
|
||||||
|
...baseCreateAdProps,
|
||||||
|
...punctualCreateAdProps,
|
||||||
|
driver: false,
|
||||||
|
passenger: true,
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens';
|
||||||
|
import { DeleteAdCommand } from '@modules/ad/core/application/commands/delete-ad/delete-ad.command';
|
||||||
|
import { DeleteAdService } from '@modules/ad/core/application/commands/delete-ad/delete-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, 'delete');
|
||||||
|
|
||||||
|
const mockAdRepository = {
|
||||||
|
findOneById: jest.fn().mockImplementation(() => ad),
|
||||||
|
delete: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('delete-ad.service', () => {
|
||||||
|
let deleteAdService: DeleteAdService;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: AD_REPOSITORY,
|
||||||
|
useValue: mockAdRepository,
|
||||||
|
},
|
||||||
|
DeleteAdService,
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
deleteAdService = module.get<DeleteAdService>(DeleteAdService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(deleteAdService).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should trigger the delete logic and delete the ad from the repository', async () => {
|
||||||
|
await deleteAdService.execute(new DeleteAdCommand({ id: ad.id }));
|
||||||
|
expect(ad.delete).toHaveBeenCalled();
|
||||||
|
expect(mockAdRepository.delete).toHaveBeenCalledWith(ad);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,62 +1,11 @@
|
||||||
import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens';
|
import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens';
|
||||||
import { AdEntity } from '@modules/ad/core/domain/ad.entity';
|
|
||||||
import { CreateAdProps, Frequency } from '@modules/ad/core/domain/ad.types';
|
|
||||||
import { FindAdByIdQuery } from '@modules/ad/core/application/queries/find-ad-by-id/find-ad-by-id.query';
|
import { FindAdByIdQuery } from '@modules/ad/core/application/queries/find-ad-by-id/find-ad-by-id.query';
|
||||||
import { FindAdByIdQueryHandler } from '@modules/ad/core/application/queries/find-ad-by-id/find-ad-by-id.query-handler';
|
import { FindAdByIdQueryHandler } from '@modules/ad/core/application/queries/find-ad-by-id/find-ad-by-id.query-handler';
|
||||||
import { WaypointProps } from '@modules/ad/core/domain/value-objects/waypoint.value-object';
|
import { AdEntity } from '@modules/ad/core/domain/ad.entity';
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { punctualPassengerCreateAdProps } from './ad.fixtures';
|
||||||
|
|
||||||
const originWaypointProps: WaypointProps = {
|
const ad: AdEntity = AdEntity.create(punctualPassengerCreateAdProps());
|
||||||
position: 0,
|
|
||||||
address: {
|
|
||||||
houseNumber: '5',
|
|
||||||
street: 'Avenue Foch',
|
|
||||||
locality: 'Nancy',
|
|
||||||
postalCode: '54000',
|
|
||||||
country: 'France',
|
|
||||||
coordinates: {
|
|
||||||
lat: 48.689445,
|
|
||||||
lon: 6.17651,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const destinationWaypointProps: WaypointProps = {
|
|
||||||
position: 1,
|
|
||||||
address: {
|
|
||||||
locality: 'Paris',
|
|
||||||
postalCode: '75000',
|
|
||||||
country: 'France',
|
|
||||||
coordinates: {
|
|
||||||
lat: 48.8566,
|
|
||||||
lon: 2.3522,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const baseCreateAdProps = {
|
|
||||||
userId: 'e8fe64b1-4c33-49e1-9f69-4db48b21df36',
|
|
||||||
seatsProposed: 3,
|
|
||||||
seatsRequested: 1,
|
|
||||||
strict: false,
|
|
||||||
waypoints: [originWaypointProps, destinationWaypointProps],
|
|
||||||
};
|
|
||||||
const punctualCreateAdProps = {
|
|
||||||
fromDate: '2023-06-22',
|
|
||||||
toDate: '2023-06-22',
|
|
||||||
schedule: [
|
|
||||||
{
|
|
||||||
time: '08:30',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
frequency: Frequency.PUNCTUAL,
|
|
||||||
};
|
|
||||||
const punctualPassengerCreateAdProps: CreateAdProps = {
|
|
||||||
...baseCreateAdProps,
|
|
||||||
...punctualCreateAdProps,
|
|
||||||
driver: false,
|
|
||||||
passenger: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ad: AdEntity = AdEntity.create(punctualPassengerCreateAdProps);
|
|
||||||
|
|
||||||
const mockAdRepository = {
|
const mockAdRepository = {
|
||||||
findOneById: jest.fn().mockImplementation(() => ad),
|
findOneById: jest.fn().mockImplementation(() => ad),
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { DeleteAdGrpcController } from '@modules/ad/interface/grpc-controllers/delete-ad.grpc.controller';
|
||||||
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
|
const mockCommandBus = {
|
||||||
|
execute: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Delete Ad Grpc Controller', () => {
|
||||||
|
let deleteAdGrpcController: DeleteAdGrpcController;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: CommandBus,
|
||||||
|
useValue: mockCommandBus,
|
||||||
|
},
|
||||||
|
DeleteAdGrpcController,
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
deleteAdGrpcController = module.get<DeleteAdGrpcController>(
|
||||||
|
DeleteAdGrpcController,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(deleteAdGrpcController).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should execute the delete ad command', async () => {
|
||||||
|
await deleteAdGrpcController.delete({
|
||||||
|
id: '200d61a8-d878-4378-a609-c19ea71633d2',
|
||||||
|
});
|
||||||
|
expect(mockCommandBus.execute).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue