basic crud
This commit is contained in:
parent
1da111bba9
commit
5b63d8ba1a
|
@ -80,6 +80,11 @@
|
|||
"json",
|
||||
"ts"
|
||||
],
|
||||
"modulePathIgnorePatterns": [
|
||||
".controller.ts",
|
||||
".module.ts",
|
||||
"main.ts"
|
||||
],
|
||||
"rootDir": "src",
|
||||
"testRegex": ".*\\.spec\\.ts$",
|
||||
"transform": {
|
||||
|
|
|
@ -13,4 +13,5 @@ CREATE TABLE "territory" (
|
|||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "territory_name_key" ON "territory"("name");
|
||||
CREATE INDEX "shape_idx" ON "territory" USING GIST ("shape");
|
||||
|
|
|
@ -14,7 +14,7 @@ datasource db {
|
|||
|
||||
model Territory {
|
||||
uuid String @id @default(uuid()) @db.Uuid
|
||||
name String
|
||||
name String @unique
|
||||
shape Unsupported("geometry")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
|
|
@ -7,14 +7,24 @@ import {
|
|||
UseInterceptors,
|
||||
UsePipes,
|
||||
} from '@nestjs/common';
|
||||
import { QueryBus } from '@nestjs/cqrs';
|
||||
import { GrpcMethod } from '@nestjs/microservices';
|
||||
import { CommandBus, QueryBus } from '@nestjs/cqrs';
|
||||
import { GrpcMethod, RpcException } from '@nestjs/microservices';
|
||||
import { Territory } from '../../domain/entities/territory';
|
||||
import { FindForPointQuery } from '../../queries/find-for-point.query';
|
||||
import { FindAllTerritoriesForPointQuery } from '../../queries/find-all-territories-for-point.query';
|
||||
import { TerritoryPresenter } from './territory.presenter';
|
||||
import { ICollection } from '../../../database/src/interfaces/collection.interface';
|
||||
import { RpcValidationPipe } from '../../../../utils/pipes/rpc.validation-pipe';
|
||||
import { FindForPointRequest } from '../../domain/dtos/find-for-point.request';
|
||||
import { FindAllTerritoriesForPointRequest } from '../../domain/dtos/find-all-territories-for-point.request';
|
||||
import { FindAllTerritoriesRequest } from '../../domain/dtos/find-all-territories.request';
|
||||
import { FindAllTerritoriesQuery } from '../../queries/find-all-territories.query';
|
||||
import { FindTerritoryByUuidRequest } from '../../domain/dtos/find-territory-by-uuid.request';
|
||||
import { FindTerritoryByUuidQuery } from '../../queries/find-territory-by-uuid.query';
|
||||
import { CreateTerritoryRequest } from '../../domain/dtos/create-territory.request';
|
||||
import { CreateTerritoryCommand } from '../../commands/create-territory.command';
|
||||
import { DatabaseException } from 'src/modules/database/src/exceptions/database.exception';
|
||||
import { UpdateTerritoryRequest } from '../../domain/dtos/update-territory.request';
|
||||
import { UpdateTerritoryCommand } from '../../commands/update-territory.command';
|
||||
import { DeleteTerritoryCommand } from '../../commands/delete-territory.command';
|
||||
|
||||
@UsePipes(
|
||||
new RpcValidationPipe({
|
||||
|
@ -25,18 +35,19 @@ import { FindForPointRequest } from '../../domain/dtos/find-for-point.request';
|
|||
@Controller()
|
||||
export class TerritoriesController {
|
||||
constructor(
|
||||
private readonly _commandBus: CommandBus,
|
||||
private readonly _queryBus: QueryBus,
|
||||
@InjectMapper() private readonly _mapper: Mapper,
|
||||
) {}
|
||||
|
||||
@GrpcMethod('TerritoriesService', 'FindForPoint')
|
||||
@GrpcMethod('TerritoriesService', 'FindAllForPoint')
|
||||
@UseInterceptors(CacheInterceptor)
|
||||
@CacheKey('TerritoriesServiceFindForPoint')
|
||||
async findForPoint(
|
||||
data: FindForPointRequest,
|
||||
@CacheKey('TerritoriesServiceFindAllForPoint')
|
||||
async findAllTerritoriesForPoint(
|
||||
data: FindAllTerritoriesForPointRequest,
|
||||
): Promise<ICollection<Territory>> {
|
||||
const territoryCollection = await this._queryBus.execute(
|
||||
new FindForPointQuery(data),
|
||||
new FindAllTerritoriesForPointQuery(data),
|
||||
);
|
||||
return Promise.resolve({
|
||||
data: territoryCollection.data.map((territory: Territory) =>
|
||||
|
@ -45,4 +56,104 @@ export class TerritoriesController {
|
|||
total: territoryCollection.total,
|
||||
});
|
||||
}
|
||||
|
||||
@GrpcMethod('TerritoriesService', 'FindAll')
|
||||
@UseInterceptors(CacheInterceptor)
|
||||
@CacheKey('TerritoriesServiceFindAll')
|
||||
async findAll(
|
||||
data: FindAllTerritoriesRequest,
|
||||
): Promise<ICollection<Territory>> {
|
||||
const territoryCollection = await this._queryBus.execute(
|
||||
new FindAllTerritoriesQuery(data),
|
||||
);
|
||||
return Promise.resolve({
|
||||
data: territoryCollection.data.map((territory: Territory) =>
|
||||
this._mapper.map(territory, Territory, TerritoryPresenter),
|
||||
),
|
||||
total: territoryCollection.total,
|
||||
});
|
||||
}
|
||||
|
||||
@GrpcMethod('TerritoriesService', 'FindOneByUuid')
|
||||
@UseInterceptors(CacheInterceptor)
|
||||
@CacheKey('TerritoriesServiceFindOneByUuid')
|
||||
async findOneByUuid(
|
||||
data: FindTerritoryByUuidRequest,
|
||||
): Promise<TerritoryPresenter> {
|
||||
try {
|
||||
const territory = await this._queryBus.execute(
|
||||
new FindTerritoryByUuidQuery(data),
|
||||
);
|
||||
return this._mapper.map(territory, Territory, TerritoryPresenter);
|
||||
} catch (error) {
|
||||
throw new RpcException({
|
||||
code: 5,
|
||||
message: 'Territory not found',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@GrpcMethod('TerritoriesService', 'Create')
|
||||
async createTerritory(
|
||||
data: CreateTerritoryRequest,
|
||||
): Promise<TerritoryPresenter> {
|
||||
try {
|
||||
const territory = await this._commandBus.execute(
|
||||
new CreateTerritoryCommand(data),
|
||||
);
|
||||
return this._mapper.map(territory, Territory, TerritoryPresenter);
|
||||
} catch (e) {
|
||||
if (e instanceof DatabaseException) {
|
||||
if (e.message.includes('Already exists')) {
|
||||
throw new RpcException({
|
||||
code: 6,
|
||||
message: 'Territory already exists',
|
||||
});
|
||||
}
|
||||
}
|
||||
throw new RpcException({});
|
||||
}
|
||||
}
|
||||
|
||||
@GrpcMethod('TerritoriesService', 'Update')
|
||||
async updateTerritory(
|
||||
data: UpdateTerritoryRequest,
|
||||
): Promise<TerritoryPresenter> {
|
||||
try {
|
||||
const territory = await this._commandBus.execute(
|
||||
new UpdateTerritoryCommand(data),
|
||||
);
|
||||
|
||||
return this._mapper.map(territory, Territory, TerritoryPresenter);
|
||||
} catch (e) {
|
||||
if (e instanceof DatabaseException) {
|
||||
if (e.message.includes('not found')) {
|
||||
throw new RpcException({
|
||||
code: 5,
|
||||
message: 'Territory not found',
|
||||
});
|
||||
}
|
||||
}
|
||||
throw new RpcException({});
|
||||
}
|
||||
}
|
||||
|
||||
@GrpcMethod('TerritoriesService', 'Delete')
|
||||
async deleteTerritory(data: FindTerritoryByUuidRequest): Promise<void> {
|
||||
try {
|
||||
await this._commandBus.execute(new DeleteTerritoryCommand(data.uuid));
|
||||
|
||||
return Promise.resolve();
|
||||
} catch (e) {
|
||||
if (e instanceof DatabaseException) {
|
||||
if (e.message.includes('not found')) {
|
||||
throw new RpcException({
|
||||
code: 5,
|
||||
message: 'Territory not found',
|
||||
});
|
||||
}
|
||||
}
|
||||
throw new RpcException({});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,27 @@ syntax = "proto3";
|
|||
package territory;
|
||||
|
||||
service TerritoriesService {
|
||||
rpc FindForPoint(Point) returns (Territories);
|
||||
rpc FindOneByUuid(TerritoryByUuid) returns (Territory);
|
||||
rpc FindAll(TerritoryFilter) returns (Territories);
|
||||
rpc FindAllForPoint(Point) returns (Territories);
|
||||
rpc Create(Territory) returns (Territory);
|
||||
rpc Update(Territory) returns (Territory);
|
||||
rpc Delete(TerritoryByUuid) returns (Empty);
|
||||
}
|
||||
|
||||
message Point {
|
||||
float lon = 1;
|
||||
float lat = 2;
|
||||
message TerritoryByUuid {
|
||||
string uuid = 1;
|
||||
}
|
||||
|
||||
message Territory {
|
||||
string uuid = 1;
|
||||
string name = 2;
|
||||
string shape = 3;
|
||||
}
|
||||
|
||||
message TerritoryFilter {
|
||||
optional int32 page = 1;
|
||||
optional int32 perPage = 2;
|
||||
}
|
||||
|
||||
message Territories {
|
||||
|
@ -16,6 +31,7 @@ message Territories {
|
|||
int32 total = 2;
|
||||
}
|
||||
|
||||
message Territory {
|
||||
string name = 1;
|
||||
message Point {
|
||||
float lon = 1;
|
||||
float lat = 2;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import { CreateTerritoryRequest } from '../domain/dtos/create-territory.request';
|
||||
|
||||
export class CreateTerritoryCommand {
|
||||
readonly createTerritoryRequest: CreateTerritoryRequest;
|
||||
|
||||
constructor(request: CreateTerritoryRequest) {
|
||||
this.createTerritoryRequest = request;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export class DeleteTerritoryCommand {
|
||||
readonly uuid: string;
|
||||
|
||||
constructor(uuid: string) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { UpdateTerritoryRequest } from '../domain/dtos/update-territory.request';
|
||||
|
||||
export class UpdateTerritoryCommand {
|
||||
readonly updateTerritoryRequest: UpdateTerritoryRequest;
|
||||
|
||||
constructor(request: UpdateTerritoryRequest) {
|
||||
this.updateTerritoryRequest = request;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { AutoMap } from '@automapper/classes';
|
||||
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
export class CreateTerritoryRequest {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@AutoMap()
|
||||
uuid?: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@AutoMap()
|
||||
name: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@AutoMap()
|
||||
shape: string;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { IsNotEmpty, IsNumber } from 'class-validator';
|
||||
|
||||
export class FindForPointRequest {
|
||||
export class FindAllTerritoriesForPointRequest {
|
||||
@IsNumber()
|
||||
@IsNotEmpty()
|
||||
lon: number;
|
|
@ -0,0 +1,11 @@
|
|||
import { IsInt, IsOptional } from 'class-validator';
|
||||
|
||||
export class FindAllTerritoriesRequest {
|
||||
@IsInt()
|
||||
@IsOptional()
|
||||
page?: number;
|
||||
|
||||
@IsInt()
|
||||
@IsOptional()
|
||||
perPage?: number;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { IsNotEmpty, IsString } from 'class-validator';
|
||||
|
||||
export class FindTerritoryByUuidRequest {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
uuid: string;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { AutoMap } from '@automapper/classes';
|
||||
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
export class UpdateTerritoryRequest {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@AutoMap()
|
||||
uuid: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@AutoMap()
|
||||
name?: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
@AutoMap()
|
||||
shape?: string;
|
||||
}
|
|
@ -6,4 +6,7 @@ export class Territory {
|
|||
|
||||
@AutoMap()
|
||||
name: string;
|
||||
|
||||
@AutoMap()
|
||||
shape: string;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import { Mapper } from '@automapper/core';
|
||||
import { InjectMapper } from '@automapper/nestjs';
|
||||
import { CommandHandler } from '@nestjs/cqrs';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { CreateTerritoryCommand } from '../../commands/create-territory.command';
|
||||
import { TerritoryMessager } from '../../adapters/secondaries/territory.messager';
|
||||
import { Territory } from '../entities/territory';
|
||||
import { CreateTerritoryRequest } from '../dtos/create-territory.request';
|
||||
|
||||
@CommandHandler(CreateTerritoryCommand)
|
||||
export class CreateTerritoryUseCase {
|
||||
constructor(
|
||||
private readonly _repository: TerritoriesRepository,
|
||||
private readonly _territoryMessager: TerritoryMessager,
|
||||
private readonly _loggingMessager: LoggingMessager,
|
||||
@InjectMapper() private readonly _mapper: Mapper,
|
||||
) {}
|
||||
|
||||
async execute(command: CreateTerritoryCommand): Promise<Territory> {
|
||||
const entity = this._mapper.map(
|
||||
command.createTerritoryRequest,
|
||||
CreateTerritoryRequest,
|
||||
Territory,
|
||||
);
|
||||
|
||||
try {
|
||||
const territory = await this._repository.create(entity);
|
||||
this._territoryMessager.publish('create', JSON.stringify(territory));
|
||||
this._loggingMessager.publish(
|
||||
'territory.create.info',
|
||||
JSON.stringify(territory),
|
||||
);
|
||||
return territory;
|
||||
} catch (error) {
|
||||
let key = 'territory.create.crit';
|
||||
if (error.message.includes('Already exists')) {
|
||||
key = 'territory.create.warning';
|
||||
}
|
||||
this._loggingMessager.publish(
|
||||
key,
|
||||
JSON.stringify({
|
||||
command,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import { CommandHandler } from '@nestjs/cqrs';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { TerritoryMessager } from '../../adapters/secondaries/territory.messager';
|
||||
import { DeleteTerritoryCommand } from '../../commands/delete-territory.command';
|
||||
import { Territory } from '../entities/territory';
|
||||
|
||||
@CommandHandler(DeleteTerritoryCommand)
|
||||
export class DeleteTerritoryUseCase {
|
||||
constructor(
|
||||
private readonly _repository: TerritoriesRepository,
|
||||
private readonly _territoryMessager: TerritoryMessager,
|
||||
private readonly _loggingMessager: LoggingMessager,
|
||||
) {}
|
||||
|
||||
async execute(command: DeleteTerritoryCommand): Promise<Territory> {
|
||||
try {
|
||||
const territory = await this._repository.delete(command.uuid);
|
||||
this._territoryMessager.publish(
|
||||
'delete',
|
||||
JSON.stringify({ uuid: territory.uuid }),
|
||||
);
|
||||
this._loggingMessager.publish(
|
||||
'territory.delete.info',
|
||||
JSON.stringify({ uuid: territory.uuid }),
|
||||
);
|
||||
return territory;
|
||||
} catch (error) {
|
||||
this._loggingMessager.publish(
|
||||
'territory.delete.crit',
|
||||
JSON.stringify({
|
||||
command,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,22 @@
|
|||
import { QueryHandler } from '@nestjs/cqrs';
|
||||
import { ICollection } from 'src/modules/database/src/interfaces/collection.interface';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { FindForPointQuery } from '../../queries/find-for-point.query';
|
||||
import { FindAllTerritoriesForPointQuery } from '../../queries/find-all-territories-for-point.query';
|
||||
import { Territory } from '../entities/territory';
|
||||
import { Point } from '../entities/point';
|
||||
|
||||
@QueryHandler(FindForPointQuery)
|
||||
export class FindForPointUseCase {
|
||||
@QueryHandler(FindAllTerritoriesForPointQuery)
|
||||
export class FindAllTerritoriesForPointUseCase {
|
||||
constructor(private readonly _repository: TerritoriesRepository) {}
|
||||
|
||||
async execute(
|
||||
findForPointQuery: FindForPointQuery,
|
||||
findAllTerritoriesForPointQuery: FindAllTerritoriesForPointQuery,
|
||||
): Promise<ICollection<Territory>> {
|
||||
return this._repository.findForPoint(
|
||||
new Point(findForPointQuery.point.lon, findForPointQuery.point.lat),
|
||||
new Point(
|
||||
findAllTerritoriesForPointQuery.point.lon,
|
||||
findAllTerritoriesForPointQuery.point.lat,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { QueryHandler } from '@nestjs/cqrs';
|
||||
import { ICollection } from 'src/modules/database/src/interfaces/collection.interface';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { FindAllTerritoriesQuery } from '../../queries/find-all-territories.query';
|
||||
import { Territory } from '../entities/territory';
|
||||
|
||||
@QueryHandler(FindAllTerritoriesQuery)
|
||||
export class FindAllTerritoriesUseCase {
|
||||
constructor(private readonly _repository: TerritoriesRepository) {}
|
||||
|
||||
async execute(
|
||||
findAllTerritoriesQuery: FindAllTerritoriesQuery,
|
||||
): Promise<ICollection<Territory>> {
|
||||
return this._repository.findAll(
|
||||
findAllTerritoriesQuery.page,
|
||||
findAllTerritoriesQuery.perPage,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
import { NotFoundException } from '@nestjs/common';
|
||||
import { QueryHandler } from '@nestjs/cqrs';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { FindTerritoryByUuidQuery } from '../../queries/find-territory-by-uuid.query';
|
||||
import { Territory } from '../entities/territory';
|
||||
|
||||
@QueryHandler(FindTerritoryByUuidQuery)
|
||||
export class FindTerritoryByUuidUseCase {
|
||||
constructor(
|
||||
private readonly _repository: TerritoriesRepository,
|
||||
private readonly _loggingMessager: LoggingMessager,
|
||||
) {}
|
||||
|
||||
async execute(
|
||||
findTerritoryByUuidQuery: FindTerritoryByUuidQuery,
|
||||
): Promise<Territory> {
|
||||
try {
|
||||
const territory = await this._repository.findOneByUuid(
|
||||
findTerritoryByUuidQuery.uuid,
|
||||
);
|
||||
if (!territory) throw new NotFoundException();
|
||||
return territory;
|
||||
} catch (error) {
|
||||
this._loggingMessager.publish(
|
||||
'territory.read.warning',
|
||||
JSON.stringify({
|
||||
query: findTerritoryByUuidQuery,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import { Mapper } from '@automapper/core';
|
||||
import { InjectMapper } from '@automapper/nestjs';
|
||||
import { CommandHandler } from '@nestjs/cqrs';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { TerritoryMessager } from '../../adapters/secondaries/territory.messager';
|
||||
import { UpdateTerritoryCommand } from '../../commands/update-territory.command';
|
||||
import { UpdateTerritoryRequest } from '../dtos/update-territory.request';
|
||||
import { Territory } from '../entities/territory';
|
||||
|
||||
@CommandHandler(UpdateTerritoryCommand)
|
||||
export class UpdateTerritoryUseCase {
|
||||
constructor(
|
||||
private readonly _repository: TerritoriesRepository,
|
||||
private readonly _territoryMessager: TerritoryMessager,
|
||||
private readonly _loggingMessager: LoggingMessager,
|
||||
@InjectMapper() private readonly _mapper: Mapper,
|
||||
) {}
|
||||
|
||||
async execute(command: UpdateTerritoryCommand): Promise<Territory> {
|
||||
const entity = this._mapper.map(
|
||||
command.updateTerritoryRequest,
|
||||
UpdateTerritoryRequest,
|
||||
Territory,
|
||||
);
|
||||
|
||||
try {
|
||||
const territory = await this._repository.update(
|
||||
command.updateTerritoryRequest.uuid,
|
||||
entity,
|
||||
);
|
||||
this._territoryMessager.publish(
|
||||
'update',
|
||||
JSON.stringify(command.updateTerritoryRequest),
|
||||
);
|
||||
this._loggingMessager.publish(
|
||||
'territory.update.info',
|
||||
JSON.stringify(command.updateTerritoryRequest),
|
||||
);
|
||||
return territory;
|
||||
} catch (error) {
|
||||
this._loggingMessager.publish(
|
||||
'territory.update.crit',
|
||||
JSON.stringify({
|
||||
command,
|
||||
error,
|
||||
}),
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
import { createMap, Mapper } from '@automapper/core';
|
||||
import { createMap, forMember, ignore, Mapper } from '@automapper/core';
|
||||
import { AutomapperProfile, InjectMapper } from '@automapper/nestjs';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { TerritoryPresenter } from '../adapters/primaries/territory.presenter';
|
||||
import { CreateTerritoryRequest } from '../domain/dtos/create-territory.request';
|
||||
import { UpdateTerritoryRequest } from '../domain/dtos/update-territory.request';
|
||||
import { Territory } from '../domain/entities/territory';
|
||||
|
||||
@Injectable()
|
||||
|
@ -13,6 +15,15 @@ export class TerritoryProfile extends AutomapperProfile {
|
|||
override get profile() {
|
||||
return (mapper) => {
|
||||
createMap(mapper, Territory, TerritoryPresenter);
|
||||
|
||||
createMap(mapper, CreateTerritoryRequest, Territory);
|
||||
|
||||
createMap(
|
||||
mapper,
|
||||
UpdateTerritoryRequest,
|
||||
Territory,
|
||||
forMember((dest) => dest.uuid, ignore()),
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import { FindAllTerritoriesForPointRequest } from '../domain/dtos/find-all-territories-for-point.request';
|
||||
import { Point } from '../domain/entities/point';
|
||||
|
||||
export class FindAllTerritoriesForPointQuery {
|
||||
point: Point;
|
||||
|
||||
constructor(
|
||||
findAllTerritoriesForPointRequest?: FindAllTerritoriesForPointRequest,
|
||||
) {
|
||||
this.point = new Point(
|
||||
findAllTerritoriesForPointRequest.lon,
|
||||
findAllTerritoriesForPointRequest.lat,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import { FindAllTerritoriesRequest } from '../domain/dtos/find-all-territories.request';
|
||||
|
||||
export class FindAllTerritoriesQuery {
|
||||
page: number;
|
||||
perPage: number;
|
||||
|
||||
constructor(findAllTerritoriesRequest?: FindAllTerritoriesRequest) {
|
||||
this.page = findAllTerritoriesRequest?.page ?? 1;
|
||||
this.perPage = findAllTerritoriesRequest?.perPage ?? 10;
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import { FindForPointRequest } from '../domain/dtos/find-for-point.request';
|
||||
import { Point } from '../domain/entities/point';
|
||||
|
||||
export class FindForPointQuery {
|
||||
point: Point;
|
||||
|
||||
constructor(findForPointRequest?: FindForPointRequest) {
|
||||
this.point = new Point(findForPointRequest.lon, findForPointRequest.lat);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { FindTerritoryByUuidRequest } from '../domain/dtos/find-territory-by-uuid.request';
|
||||
|
||||
export class FindTerritoryByUuidQuery {
|
||||
readonly uuid: string;
|
||||
|
||||
constructor(findTerritoryByUuidRequest: FindTerritoryByUuidRequest) {
|
||||
this.uuid = findTerritoryByUuidRequest.uuid;
|
||||
}
|
||||
}
|
|
@ -9,7 +9,12 @@ import { TerritoriesController } from './adapters/primaries/territories.controll
|
|||
import { LoggingMessager } from './adapters/secondaries/logging.messager';
|
||||
import { TerritoriesRepository } from './adapters/secondaries/territories.repository';
|
||||
import { TerritoryMessager } from './adapters/secondaries/territory.messager';
|
||||
import { FindForPointUseCase } from './domain/usecases/find-for-point.usecase';
|
||||
import { CreateTerritoryUseCase } from './domain/usecases/create-territory.usecase';
|
||||
import { DeleteTerritoryUseCase } from './domain/usecases/delete-territory.usecase';
|
||||
import { FindAllTerritoriesForPointUseCase } from './domain/usecases/find-all-territories-for-point.usecase';
|
||||
import { FindAllTerritoriesUseCase } from './domain/usecases/find-all-territories.usecase';
|
||||
import { FindTerritoryByUuidUseCase } from './domain/usecases/find-territory-by-uuid.usecase';
|
||||
import { UpdateTerritoryUseCase } from './domain/usecases/update-territory.usecase';
|
||||
import { TerritoryProfile } from './mappers/territory.profile';
|
||||
|
||||
@Module({
|
||||
|
@ -52,7 +57,12 @@ import { TerritoryProfile } from './mappers/territory.profile';
|
|||
TerritoriesRepository,
|
||||
TerritoryMessager,
|
||||
LoggingMessager,
|
||||
FindForPointUseCase,
|
||||
FindAllTerritoriesForPointUseCase,
|
||||
FindAllTerritoriesUseCase,
|
||||
FindTerritoryByUuidUseCase,
|
||||
CreateTerritoryUseCase,
|
||||
UpdateTerritoryUseCase,
|
||||
DeleteTerritoryUseCase,
|
||||
],
|
||||
exports: [],
|
||||
})
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
import { classes } from '@automapper/classes';
|
||||
import { AutomapperModule } from '@automapper/nestjs';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { TerritoryMessager } from '../../adapters/secondaries/territory.messager';
|
||||
import { CreateTerritoryCommand } from '../../commands/create-territory.command';
|
||||
import { CreateTerritoryRequest } from '../../domain/dtos/create-territory.request';
|
||||
import { Territory } from '../../domain/entities/territory';
|
||||
import { CreateTerritoryUseCase } from '../../domain/usecases/create-territory.usecase';
|
||||
import { TerritoryProfile } from '../../mappers/territory.profile';
|
||||
|
||||
const newTerritoryRequest: CreateTerritoryRequest = {
|
||||
name: 'Grand Est',
|
||||
shape: 'grand-est-binary-shape',
|
||||
};
|
||||
const newTerritoryCommand: CreateTerritoryCommand = new CreateTerritoryCommand(
|
||||
newTerritoryRequest,
|
||||
);
|
||||
|
||||
const mockTerritoriesRepository = {
|
||||
create: jest
|
||||
.fn()
|
||||
.mockImplementationOnce(() => {
|
||||
return Promise.resolve({
|
||||
...newTerritoryRequest,
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
});
|
||||
})
|
||||
.mockImplementation(() => {
|
||||
throw new Error('Already exists');
|
||||
}),
|
||||
};
|
||||
|
||||
const mockMessager = {
|
||||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('CreateTerritoryUseCase', () => {
|
||||
let createTerritoryUseCase: CreateTerritoryUseCase;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
imports: [AutomapperModule.forRoot({ strategyInitializer: classes() })],
|
||||
providers: [
|
||||
{
|
||||
provide: TerritoriesRepository,
|
||||
useValue: mockTerritoriesRepository,
|
||||
},
|
||||
CreateTerritoryUseCase,
|
||||
TerritoryProfile,
|
||||
{
|
||||
provide: TerritoryMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
{
|
||||
provide: LoggingMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
createTerritoryUseCase = module.get<CreateTerritoryUseCase>(
|
||||
CreateTerritoryUseCase,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(createTerritoryUseCase).toBeDefined();
|
||||
});
|
||||
|
||||
describe('execute', () => {
|
||||
it('should create and return a new territory', async () => {
|
||||
const newTerritory: Territory = await createTerritoryUseCase.execute(
|
||||
newTerritoryCommand,
|
||||
);
|
||||
|
||||
expect(newTerritory.name).toBe(newTerritoryRequest.name);
|
||||
expect(newTerritory.uuid).toBeDefined();
|
||||
});
|
||||
|
||||
it('should throw an error if territory already exists', async () => {
|
||||
await expect(
|
||||
createTerritoryUseCase.execute(newTerritoryCommand),
|
||||
).rejects.toBeInstanceOf(Error);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,98 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { TerritoryMessager } from '../../adapters/secondaries/territory.messager';
|
||||
import { DeleteTerritoryCommand } from '../../commands/delete-territory.command';
|
||||
import { DeleteTerritoryUseCase } from '../../domain/usecases/delete-territory.usecase';
|
||||
|
||||
const mockTerritories = [
|
||||
{
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
name: 'Grand Est',
|
||||
shape: 'grand-est-binary-shape',
|
||||
},
|
||||
{
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a92',
|
||||
name: 'Nouvelle Aquitaine',
|
||||
shape: 'nouvelle-aquitaine-binary-shape',
|
||||
},
|
||||
{
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a93',
|
||||
name: 'Occitanie',
|
||||
shape: 'occitanie-binary-shape',
|
||||
},
|
||||
];
|
||||
|
||||
const mockTerritoriesRepository = {
|
||||
delete: jest
|
||||
.fn()
|
||||
.mockImplementationOnce((uuid: string) => {
|
||||
let savedTerritory = {};
|
||||
mockTerritories.forEach((territory, index) => {
|
||||
if (territory.uuid === uuid) {
|
||||
savedTerritory = { ...territory };
|
||||
mockTerritories.splice(index, 1);
|
||||
}
|
||||
});
|
||||
return savedTerritory;
|
||||
})
|
||||
.mockImplementation(() => {
|
||||
throw new Error('Error');
|
||||
}),
|
||||
};
|
||||
|
||||
const mockMessager = {
|
||||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('DeleteTerritoryUseCase', () => {
|
||||
let deleteTerritoryUseCase: DeleteTerritoryUseCase;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
{
|
||||
provide: TerritoriesRepository,
|
||||
useValue: mockTerritoriesRepository,
|
||||
},
|
||||
DeleteTerritoryUseCase,
|
||||
{
|
||||
provide: TerritoryMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
{
|
||||
provide: LoggingMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
deleteTerritoryUseCase = module.get<DeleteTerritoryUseCase>(
|
||||
DeleteTerritoryUseCase,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(deleteTerritoryUseCase).toBeDefined();
|
||||
});
|
||||
|
||||
describe('execute', () => {
|
||||
it('should delete a territory', async () => {
|
||||
const savedUuid = mockTerritories[0].uuid;
|
||||
const deleteTerritoryCommand = new DeleteTerritoryCommand(savedUuid);
|
||||
await deleteTerritoryUseCase.execute(deleteTerritoryCommand);
|
||||
|
||||
const deletedTerritory = mockTerritories.find(
|
||||
(territory) => territory.uuid === savedUuid,
|
||||
);
|
||||
expect(deletedTerritory).toBeUndefined();
|
||||
});
|
||||
it('should throw an error if territory does not exist', async () => {
|
||||
await expect(
|
||||
deleteTerritoryUseCase.execute(
|
||||
new DeleteTerritoryCommand('wrong uuid'),
|
||||
),
|
||||
).rejects.toBeInstanceOf(Error);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,68 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { FindAllTerritoriesForPointRequest } from '../../domain/dtos/find-all-territories-for-point.request';
|
||||
import { FindAllTerritoriesForPointUseCase } from '../../domain/usecases/find-all-territories-for-point.usecase';
|
||||
import { FindAllTerritoriesForPointQuery } from '../../queries/find-all-territories-for-point.query';
|
||||
|
||||
const findAllTerritoriesForPointRequest: FindAllTerritoriesForPointRequest =
|
||||
new FindAllTerritoriesForPointRequest();
|
||||
findAllTerritoriesForPointRequest.lon = 6.181455;
|
||||
findAllTerritoriesForPointRequest.lat = 48.685689;
|
||||
|
||||
const findforPointQuery: FindAllTerritoriesForPointQuery =
|
||||
new FindAllTerritoriesForPointQuery(findAllTerritoriesForPointRequest);
|
||||
|
||||
const mockTerritories = [
|
||||
{
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
name: 'Nancy',
|
||||
},
|
||||
{
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a92',
|
||||
name: 'Meurthe-et-Moselle',
|
||||
},
|
||||
];
|
||||
|
||||
const mockTerritoriesRepository = {
|
||||
findForPoint: jest
|
||||
.fn()
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
.mockImplementation((query?: FindAllTerritoriesForPointQuery) => {
|
||||
return Promise.resolve(mockTerritories);
|
||||
}),
|
||||
};
|
||||
|
||||
describe('FindAllTerritoriesforPointUseCase', () => {
|
||||
let findAllTerritoriesForPointUseCase: FindAllTerritoriesForPointUseCase;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
{
|
||||
provide: TerritoriesRepository,
|
||||
useValue: mockTerritoriesRepository,
|
||||
},
|
||||
FindAllTerritoriesForPointUseCase,
|
||||
],
|
||||
}).compile();
|
||||
|
||||
findAllTerritoriesForPointUseCase =
|
||||
module.get<FindAllTerritoriesForPointUseCase>(
|
||||
FindAllTerritoriesForPointUseCase,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(findAllTerritoriesForPointUseCase).toBeDefined();
|
||||
});
|
||||
|
||||
describe('execute', () => {
|
||||
it('should return an array filled with territories', async () => {
|
||||
const territories = await findAllTerritoriesForPointUseCase.execute(
|
||||
findforPointQuery,
|
||||
);
|
||||
|
||||
expect(territories).toBe(mockTerritories);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,72 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { FindAllTerritoriesRequest } from '../../domain/dtos/find-all-territories.request';
|
||||
import { FindAllTerritoriesUseCase } from '../../domain/usecases/find-all-territories.usecase';
|
||||
import { FindAllTerritoriesQuery } from '../../queries/find-all-territories.query';
|
||||
|
||||
const findAllTerritoriesRequest: FindAllTerritoriesRequest =
|
||||
new FindAllTerritoriesRequest();
|
||||
findAllTerritoriesRequest.page = 1;
|
||||
findAllTerritoriesRequest.perPage = 10;
|
||||
|
||||
const findAllTerritoriesQuery: FindAllTerritoriesQuery =
|
||||
new FindAllTerritoriesQuery(findAllTerritoriesRequest);
|
||||
|
||||
const mockTerritories = [
|
||||
{
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
name: 'Grand Est',
|
||||
shape: 'grand-est-binary-shape',
|
||||
},
|
||||
{
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a92',
|
||||
name: 'Nouvelle Aquitaine',
|
||||
shape: 'nouvelle-aquitaine-binary-shape',
|
||||
},
|
||||
{
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a93',
|
||||
name: 'Occitanie',
|
||||
shape: 'occitanie-binary-shape',
|
||||
},
|
||||
];
|
||||
|
||||
const mockTerritoriesRepository = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
findAll: jest.fn().mockImplementation((query?: FindAllTerritoriesQuery) => {
|
||||
return Promise.resolve(mockTerritories);
|
||||
}),
|
||||
};
|
||||
|
||||
describe('FindAllTerritoriesUseCase', () => {
|
||||
let findAllTerritoriesUseCase: FindAllTerritoriesUseCase;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
{
|
||||
provide: TerritoriesRepository,
|
||||
useValue: mockTerritoriesRepository,
|
||||
},
|
||||
FindAllTerritoriesUseCase,
|
||||
],
|
||||
}).compile();
|
||||
|
||||
findAllTerritoriesUseCase = module.get<FindAllTerritoriesUseCase>(
|
||||
FindAllTerritoriesUseCase,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(findAllTerritoriesUseCase).toBeDefined();
|
||||
});
|
||||
|
||||
describe('execute', () => {
|
||||
it('should return an array filled with territories', async () => {
|
||||
const territories = await findAllTerritoriesUseCase.execute(
|
||||
findAllTerritoriesQuery,
|
||||
);
|
||||
|
||||
expect(territories).toBe(mockTerritories);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,61 +0,0 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { FindForPointRequest } from '../../domain/dtos/find-for-point.request';
|
||||
import { FindForPointUseCase } from '../../domain/usecases/find-for-point.usecase';
|
||||
import { FindForPointQuery } from '../../queries/find-for-point.query';
|
||||
|
||||
const findForPointRequest: FindForPointRequest = new FindForPointRequest();
|
||||
findForPointRequest.lon = 6.181455;
|
||||
findForPointRequest.lat = 48.685689;
|
||||
|
||||
const findforPointQuery: FindForPointQuery = new FindForPointQuery(
|
||||
findForPointRequest,
|
||||
);
|
||||
|
||||
const mockTerritories = [
|
||||
{
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
name: 'Nancy',
|
||||
},
|
||||
{
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a92',
|
||||
name: 'Meurthe-et-Moselle',
|
||||
},
|
||||
];
|
||||
|
||||
const mockTerritoriesRepository = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
findForPoint: jest.fn().mockImplementation((query?: FindForPointQuery) => {
|
||||
return Promise.resolve(mockTerritories);
|
||||
}),
|
||||
};
|
||||
|
||||
describe('FindforPointUseCase', () => {
|
||||
let findForPointUseCase: FindForPointUseCase;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
{
|
||||
provide: TerritoriesRepository,
|
||||
useValue: mockTerritoriesRepository,
|
||||
},
|
||||
FindForPointUseCase,
|
||||
],
|
||||
}).compile();
|
||||
|
||||
findForPointUseCase = module.get<FindForPointUseCase>(FindForPointUseCase);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(findForPointUseCase).toBeDefined();
|
||||
});
|
||||
|
||||
describe('execute', () => {
|
||||
it('should return an array filled with territories', async () => {
|
||||
const territories = await findForPointUseCase.execute(findforPointQuery);
|
||||
|
||||
expect(territories).toBe(mockTerritories);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,80 @@
|
|||
import { NotFoundException } from '@nestjs/common';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { FindTerritoryByUuidRequest } from '../../domain/dtos/find-territory-by-uuid.request';
|
||||
import { FindTerritoryByUuidUseCase } from '../../domain/usecases/find-territory-by-uuid.usecase';
|
||||
import { FindTerritoryByUuidQuery } from '../../queries/find-territory-by-uuid.query';
|
||||
|
||||
const mockTerritory = {
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
name: 'Grand Est',
|
||||
shape: 'grand-est-binary-shape',
|
||||
};
|
||||
|
||||
const mockTerritoriesRepository = {
|
||||
findOneByUuid: jest
|
||||
.fn()
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
.mockImplementationOnce((query?: FindTerritoryByUuidQuery) => {
|
||||
return Promise.resolve(mockTerritory);
|
||||
})
|
||||
.mockImplementation(() => {
|
||||
return Promise.resolve(undefined);
|
||||
}),
|
||||
};
|
||||
|
||||
const mockMessager = {
|
||||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('FindTerritoryByUuidUseCase', () => {
|
||||
let findTerritoryByUuidUseCase: FindTerritoryByUuidUseCase;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
imports: [],
|
||||
providers: [
|
||||
{
|
||||
provide: TerritoriesRepository,
|
||||
useValue: mockTerritoriesRepository,
|
||||
},
|
||||
{
|
||||
provide: LoggingMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
FindTerritoryByUuidUseCase,
|
||||
],
|
||||
}).compile();
|
||||
|
||||
findTerritoryByUuidUseCase = module.get<FindTerritoryByUuidUseCase>(
|
||||
FindTerritoryByUuidUseCase,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(findTerritoryByUuidUseCase).toBeDefined();
|
||||
});
|
||||
|
||||
describe('execute', () => {
|
||||
it('should return a territory', async () => {
|
||||
const findTerritoryByUuidRequest: FindTerritoryByUuidRequest =
|
||||
new FindTerritoryByUuidRequest();
|
||||
findTerritoryByUuidRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91';
|
||||
const territory = await findTerritoryByUuidUseCase.execute(
|
||||
new FindTerritoryByUuidQuery(findTerritoryByUuidRequest),
|
||||
);
|
||||
expect(territory).toBe(mockTerritory);
|
||||
});
|
||||
it('should throw an error if territory does not exist', async () => {
|
||||
const findTerritoryByUuidRequest: FindTerritoryByUuidRequest =
|
||||
new FindTerritoryByUuidRequest();
|
||||
findTerritoryByUuidRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a90';
|
||||
await expect(
|
||||
findTerritoryByUuidUseCase.execute(
|
||||
new FindTerritoryByUuidQuery(findTerritoryByUuidRequest),
|
||||
),
|
||||
).rejects.toBeInstanceOf(NotFoundException);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,90 @@
|
|||
import { classes } from '@automapper/classes';
|
||||
import { AutomapperModule } from '@automapper/nestjs';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
|
||||
import { TerritoriesRepository } from '../../adapters/secondaries/territories.repository';
|
||||
import { TerritoryMessager } from '../../adapters/secondaries/territory.messager';
|
||||
import { UpdateTerritoryCommand } from '../../commands/update-territory.command';
|
||||
import { UpdateTerritoryRequest } from '../../domain/dtos/update-territory.request';
|
||||
import { Territory } from '../../domain/entities/territory';
|
||||
import { UpdateTerritoryUseCase } from '../../domain/usecases/update-territory.usecase';
|
||||
import { TerritoryProfile } from '../../mappers/territory.profile';
|
||||
|
||||
const originalTerritory: Territory = new Territory();
|
||||
originalTerritory.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91';
|
||||
originalTerritory.name = 'Grand Est';
|
||||
|
||||
const updateTerritoryRequest: UpdateTerritoryRequest = {
|
||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||
name: 'Grand-Est',
|
||||
};
|
||||
|
||||
const updateTerritoryCommand: UpdateTerritoryCommand =
|
||||
new UpdateTerritoryCommand(updateTerritoryRequest);
|
||||
|
||||
const mockTerritoriesRepository = {
|
||||
update: jest
|
||||
.fn()
|
||||
.mockImplementationOnce((uuid: string, params: any) => {
|
||||
originalTerritory.name = params.name;
|
||||
|
||||
return Promise.resolve(originalTerritory);
|
||||
})
|
||||
.mockImplementation(() => {
|
||||
throw new Error('Error');
|
||||
}),
|
||||
};
|
||||
|
||||
const mockMessager = {
|
||||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('UpdateTerritoryUseCase', () => {
|
||||
let updateTerritoryUseCase: UpdateTerritoryUseCase;
|
||||
|
||||
beforeAll(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
imports: [AutomapperModule.forRoot({ strategyInitializer: classes() })],
|
||||
|
||||
providers: [
|
||||
{
|
||||
provide: TerritoriesRepository,
|
||||
useValue: mockTerritoriesRepository,
|
||||
},
|
||||
UpdateTerritoryUseCase,
|
||||
TerritoryProfile,
|
||||
{
|
||||
provide: TerritoryMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
{
|
||||
provide: LoggingMessager,
|
||||
useValue: mockMessager,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
updateTerritoryUseCase = module.get<UpdateTerritoryUseCase>(
|
||||
UpdateTerritoryUseCase,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(updateTerritoryUseCase).toBeDefined();
|
||||
});
|
||||
|
||||
describe('execute', () => {
|
||||
it('should update a territory', async () => {
|
||||
const updatedTerritory: Territory = await updateTerritoryUseCase.execute(
|
||||
updateTerritoryCommand,
|
||||
);
|
||||
|
||||
expect(updatedTerritory.name).toBe(updateTerritoryRequest.name);
|
||||
});
|
||||
it('should throw an error if territory does not exist', async () => {
|
||||
await expect(
|
||||
updateTerritoryUseCase.execute(updateTerritoryCommand),
|
||||
).rejects.toBeInstanceOf(Error);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
import { ArgumentMetadata } from '@nestjs/common';
|
||||
import { UpdateTerritoryRequest } from '../../../modules/territories/domain/dtos/update-territory.request';
|
||||
import { RpcValidationPipe } from '../../pipes/rpc.validation-pipe';
|
||||
|
||||
describe('RpcValidationPipe', () => {
|
||||
it('should not validate request', async () => {
|
||||
const target: RpcValidationPipe = new RpcValidationPipe({
|
||||
whitelist: true,
|
||||
forbidUnknownValues: false,
|
||||
});
|
||||
const metadata: ArgumentMetadata = {
|
||||
type: 'body',
|
||||
metatype: UpdateTerritoryRequest,
|
||||
data: '',
|
||||
};
|
||||
await target
|
||||
.transform(<UpdateTerritoryRequest>{}, metadata)
|
||||
.catch((err) => {
|
||||
expect(err.message).toEqual('Rpc Exception');
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue