findUserById
This commit is contained in:
parent
cc170779cb
commit
979ea5e98f
|
@ -0,0 +1,17 @@
|
|||
import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
|
||||
import { FindUserByIdQuery } from './find-user-by-id.query';
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { USER_REPOSITORY } from '@modules/user/user.di-tokens';
|
||||
import { UserRepositoryPort } from '../../ports/user.repository.port';
|
||||
import { UserEntity } from '@modules/user/core/domain/user.entity';
|
||||
|
||||
@QueryHandler(FindUserByIdQuery)
|
||||
export class FindUserByIdQueryHandler implements IQueryHandler {
|
||||
constructor(
|
||||
@Inject(USER_REPOSITORY)
|
||||
private readonly userRepository: UserRepositoryPort,
|
||||
) {}
|
||||
async execute(query: FindUserByIdQuery): Promise<UserEntity> {
|
||||
return await this.userRepository.findOneById(query.id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import { QueryBase } from '@mobicoop/ddd-library';
|
||||
|
||||
export class FindUserByIdQuery extends QueryBase {
|
||||
readonly id: string;
|
||||
|
||||
constructor(id: string) {
|
||||
super();
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { IsNotEmpty, IsString } from 'class-validator';
|
||||
|
||||
export class FindUserByIdRequestDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
id: string;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
import { Controller, UsePipes } from '@nestjs/common';
|
||||
import { QueryBus } from '@nestjs/cqrs';
|
||||
import { GrpcMethod, RpcException } from '@nestjs/microservices';
|
||||
import { NotFoundException } from '@mobicoop/ddd-library';
|
||||
import { RpcExceptionCode } from '@mobicoop/ddd-library';
|
||||
import { RpcValidationPipe } from '@mobicoop/ddd-library';
|
||||
import { UserMapper } from '@modules/user/user.mapper';
|
||||
import { FindUserByIdRequestDto } from './dtos/find-user-by-id.request.dto';
|
||||
import { UserResponseDto } from '../dtos/user.response.dto';
|
||||
import { UserEntity } from '@modules/user/core/domain/user.entity';
|
||||
import { FindUserByIdQuery } from '@modules/user/core/application/queries/find-user-by-id/find-user-by-id.query';
|
||||
|
||||
@UsePipes(
|
||||
new RpcValidationPipe({
|
||||
whitelist: false,
|
||||
forbidUnknownValues: false,
|
||||
}),
|
||||
)
|
||||
@Controller()
|
||||
export class FindUserByIdGrpcController {
|
||||
constructor(
|
||||
protected readonly mapper: UserMapper,
|
||||
private readonly queryBus: QueryBus,
|
||||
) {}
|
||||
|
||||
@GrpcMethod('UserService', 'FindOneById')
|
||||
async findOnebyId(data: FindUserByIdRequestDto): Promise<UserResponseDto> {
|
||||
try {
|
||||
const user: UserEntity = await this.queryBus.execute(
|
||||
new FindUserByIdQuery(data.id),
|
||||
);
|
||||
return this.mapper.toResponse(user);
|
||||
} catch (e) {
|
||||
if (e instanceof NotFoundException) {
|
||||
throw new RpcException({
|
||||
code: RpcExceptionCode.NOT_FOUND,
|
||||
message: e.message,
|
||||
});
|
||||
}
|
||||
throw new RpcException({
|
||||
code: RpcExceptionCode.UNKNOWN,
|
||||
message: e.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { UserEntity } from '@modules/user/core/domain/user.entity';
|
||||
import { FindUserByIdQueryHandler } from '@modules/user/core/application/queries/find-user-by-id/find-user-by-id.query-handler';
|
||||
import { USER_REPOSITORY } from '@modules/user/user.di-tokens';
|
||||
import { FindUserByIdQuery } from '@modules/user/core/application/queries/find-user-by-id/find-user-by-id.query';
|
||||
|
||||
const now = new Date('2023-06-21 06:00:00');
|
||||
const user: UserEntity = new UserEntity({
|
||||
id: 'c160cf8c-f057-4962-841f-3ad68346df44',
|
||||
props: {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
email: 'john.doe@email.com',
|
||||
phone: '+33611223344',
|
||||
},
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
});
|
||||
|
||||
const mockUserRepository = {
|
||||
findOneById: jest.fn().mockImplementation(() => user),
|
||||
};
|
||||
|
||||
describe('find-user-by-id.query-handler', () => {
|
||||
let findUserByIdQueryHandler: FindUserByIdQueryHandler;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
{
|
||||
provide: USER_REPOSITORY,
|
||||
useValue: mockUserRepository,
|
||||
},
|
||||
FindUserByIdQueryHandler,
|
||||
],
|
||||
}).compile();
|
||||
|
||||
findUserByIdQueryHandler = module.get<FindUserByIdQueryHandler>(
|
||||
FindUserByIdQueryHandler,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(findUserByIdQueryHandler).toBeDefined();
|
||||
});
|
||||
|
||||
describe('execution', () => {
|
||||
it('should return a user', async () => {
|
||||
const findUserbyIdQuery = new FindUserByIdQuery(
|
||||
'dd264806-13b4-4226-9b18-87adf0ad5dd1',
|
||||
);
|
||||
const user: UserEntity = await findUserByIdQueryHandler.execute(
|
||||
findUserbyIdQuery,
|
||||
);
|
||||
expect(user.getProps().lastName).toBe('Doe');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,103 @@
|
|||
import { NotFoundException } from '@mobicoop/ddd-library';
|
||||
import { RpcExceptionCode } from '@mobicoop/ddd-library';
|
||||
import { FindUserByIdGrpcController } from '@modules/user/interface/grpc-controllers/find-user-by-id.grpc.controller';
|
||||
import { UserMapper } from '@modules/user/user.mapper';
|
||||
import { QueryBus } from '@nestjs/cqrs';
|
||||
import { RpcException } from '@nestjs/microservices';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
const mockQueryBus = {
|
||||
execute: jest
|
||||
.fn()
|
||||
.mockImplementationOnce(() => '200d61a8-d878-4378-a609-c19ea71633d2')
|
||||
.mockImplementationOnce(() => {
|
||||
throw new NotFoundException();
|
||||
})
|
||||
.mockImplementationOnce(() => {
|
||||
throw new Error();
|
||||
}),
|
||||
};
|
||||
|
||||
const mockUserMapper = {
|
||||
toResponse: jest.fn().mockImplementationOnce(() => ({
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
email: 'john.doe@email.com',
|
||||
phone: '+33611223344',
|
||||
})),
|
||||
};
|
||||
|
||||
describe('Find User By Id Grpc Controller', () => {
|
||||
let findUserbyIdGrpcController: FindUserByIdGrpcController;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
{
|
||||
provide: QueryBus,
|
||||
useValue: mockQueryBus,
|
||||
},
|
||||
{
|
||||
provide: UserMapper,
|
||||
useValue: mockUserMapper,
|
||||
},
|
||||
FindUserByIdGrpcController,
|
||||
],
|
||||
}).compile();
|
||||
|
||||
findUserbyIdGrpcController = module.get<FindUserByIdGrpcController>(
|
||||
FindUserByIdGrpcController,
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(findUserbyIdGrpcController).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return a user', async () => {
|
||||
jest.spyOn(mockQueryBus, 'execute');
|
||||
jest.spyOn(mockUserMapper, 'toResponse');
|
||||
const response = await findUserbyIdGrpcController.findOnebyId({
|
||||
id: '6dcf093c-c7db-4dae-8e9c-c715cebf83c7',
|
||||
});
|
||||
expect(response.firstName).toBe('John');
|
||||
expect(mockQueryBus.execute).toHaveBeenCalledTimes(1);
|
||||
expect(mockUserMapper.toResponse).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should throw a dedicated RpcException if user is not found', async () => {
|
||||
jest.spyOn(mockQueryBus, 'execute');
|
||||
jest.spyOn(mockUserMapper, 'toResponse');
|
||||
expect.assertions(4);
|
||||
try {
|
||||
await findUserbyIdGrpcController.findOnebyId({
|
||||
id: 'ac85f5f4-41cd-4c5d-9aee-0a1acb176fb8',
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(RpcException);
|
||||
expect(e.error.code).toBe(RpcExceptionCode.NOT_FOUND);
|
||||
}
|
||||
expect(mockQueryBus.execute).toHaveBeenCalledTimes(1);
|
||||
expect(mockUserMapper.toResponse).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should throw a generic RpcException', async () => {
|
||||
jest.spyOn(mockQueryBus, 'execute');
|
||||
jest.spyOn(mockUserMapper, 'toResponse');
|
||||
expect.assertions(4);
|
||||
try {
|
||||
await findUserbyIdGrpcController.findOnebyId({
|
||||
id: '53c8e7ec-ef68-42bc-ba4c-5ef3effa60a6',
|
||||
});
|
||||
} catch (e: any) {
|
||||
expect(e).toBeInstanceOf(RpcException);
|
||||
expect(e.error.code).toBe(RpcExceptionCode.UNKNOWN);
|
||||
}
|
||||
expect(mockQueryBus.execute).toHaveBeenCalledTimes(1);
|
||||
expect(mockUserMapper.toResponse).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue