Skip to content

Commit 90d1810

Browse files
committed
test: create first tests
1 parent 41c722d commit 90d1810

File tree

13 files changed

+148
-46
lines changed

13 files changed

+148
-46
lines changed

jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module.exports = {
1414
collectCoverageFrom: [
1515
"**/*.(t|j)s"
1616
],
17-
coverageDirectory: "../coverage",
17+
coverageDirectory: "./coverage",
1818
"moduleNameMapper": {
1919
"^src/(.*)$": "<rootDir>/$1"
2020
}

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
"start:debug": "nest start --debug --watch",
1212
"start:prod": "node dist/main",
1313
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
14-
"test": "cross-env NODE_ENV=test jest",
15-
"test:coverage": "cross-env NODE_ENV=test jest --coverage"
14+
"test": "cross-env NODE_ENV=test jest"
1615
},
1716
"engines": {
1817
"node": ">=18.16.0",
Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,37 @@
11
import { Controller, Post, Body, Get, Param, Query } from '@nestjs/common';
2-
import { OrdersService } from './order.service';
2+
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
3+
import { responseError } from 'src/external/infra/errors/reponse.error';
4+
import {
5+
CreateOrderSwagger,
6+
CreatedOrderSwagger,
7+
} from 'src/internal/application/docs/swagger/checkout/create-order.dto';
38
import { CreateOrderDto } from 'src/internal/domain/checkout/dto/create-order.dto';
9+
410
import { ProductsService } from '../product/product.service';
5-
import { responseError } from 'src/external/infra/errors/reponse.error';
6-
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
7-
import { CreateOrderSwagger, CreatedOrderSwagger } from 'src/internal/application/docs/swagger/checkout/create-order.dto';
11+
import { OrdersService } from './order.service';
812

913
@ApiTags('Order')
1014
@Controller('orders')
1115
export class OrderController {
12-
1316
constructor(
1417
private readonly ordersService: OrdersService,
1518
private readonly productsService: ProductsService,
1619
) {}
1720

1821
@ApiOperation({ summary: 'Create Order' })
1922
@ApiBody({ type: CreateOrderSwagger })
20-
@ApiResponse({ status: 201, description: 'Order successfully created.', type: CreatedOrderSwagger })
23+
@ApiResponse({
24+
status: 201,
25+
description: 'Order successfully created.',
26+
type: CreatedOrderSwagger,
27+
})
2128
@Post()
2229
async create(@Body() createOrderDto: CreateOrderDto) {
2330
try {
2431
await this.productsService.verifyProductQuantity(createOrderDto.products);
2532
return this.ordersService.create(createOrderDto);
26-
} catch (err: any) {
27-
responseError(err);
33+
} catch (err) {
34+
return responseError(err);
2835
}
2936
}
3037

@@ -34,8 +41,8 @@ export class OrderController {
3441
prepare(@Param('orderId') orderId: string) {
3542
try {
3643
return this.ordersService.prepare(orderId);
37-
} catch (err: any) {
38-
responseError(err);
44+
} catch (err) {
45+
return responseError(err);
3946
}
4047
}
4148

@@ -45,8 +52,8 @@ export class OrderController {
4552
withdrawn(@Param('orderId') orderId: string) {
4653
try {
4754
return this.ordersService.withdrawn(orderId);
48-
} catch (err: any) {
49-
responseError(err);
55+
} catch (err) {
56+
return responseError(err);
5057
}
5158
}
5259

@@ -59,8 +66,8 @@ export class OrderController {
5966
) {
6067
try {
6168
return this.ordersService.findAll(customerId, status);
62-
} catch (err: any) {
63-
responseError(err);
69+
} catch (err) {
70+
return responseError(err);
6471
}
6572
}
6673
}

src/external/adapters/checkout/order.module.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
import { Module } from '@nestjs/common';
2-
import { SequelizeModule } from '@nestjs/sequelize';
31
import { BullModule } from '@nestjs/bull';
4-
import { OrderController } from './order.controller';
5-
import { OrdersService } from './order.service';
2+
import { Module } from '@nestjs/common';
63
import { EventEmitter2 } from '@nestjs/event-emitter';
4+
import { SequelizeModule } from '@nestjs/sequelize';
75
import { Uuid } from 'src/external/infra/tokens/uuid/uuid';
8-
import { PublishOrderRequestListener } from './bullmq/listeners/publish-order-request.listener';
6+
7+
import { ProductsService } from '../product/product.service';
8+
import { ProductSequelizeRepository } from '../product/sequelize/product-sequelize.repository';
9+
import { ProductModel } from '../product/sequelize/product.model';
910
import { OrderConsumer } from './bullmq/consumers/order.consumer';
1011
import { ChangeOrderStatusListener } from './bullmq/listeners/change-order-status.listener';
11-
import { OrderSequelizeRepository } from './sequelize/order-sequelize.repository';
12+
import { PublishOrderRequestListener } from './bullmq/listeners/publish-order-request.listener';
13+
import { OrderController } from './order.controller';
14+
import { OrdersService } from './order.service';
1215
import { OrderItemModel } from './sequelize/order-item-model';
1316
import { OrderModel } from './sequelize/order-model';
14-
import { ProductsService } from '../product/product.service';
15-
import { ProductSequelizeRepository } from '../product/sequelize/product-sequelize.repository';
16-
import { ProductModel } from '../product/sequelize/product.model';
17+
import { OrderSequelizeRepository } from './sequelize/order-sequelize.repository';
1718

1819
@Module({
1920
imports: [

src/external/adapters/checkout/order.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ export class OrdersService {
2323
) {}
2424

2525
async create(createOrderDto: CreateOrderDto) {
26-
const products = createOrderDto.products;
26+
const { products } = createOrderDto;
2727

28-
const orderItems = products.map((product) => {
28+
const orderItems = products.map(product => {
2929
return new OrderItem({
3030
id: this.idGenerator.generate(),
3131
productId: product.id,
Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,41 @@
1-
import { Controller, Post, Body } from '@nestjs/common';
2-
import { CustomersService } from './customer.service';
3-
import { CreateCustomerDto } from 'src/internal/domain/customers/dto/create-customer.dto';
4-
import { responseError } from 'src/external/infra/errors/reponse.error';
1+
import { Controller, Post, Body, Get, Param } from '@nestjs/common';
52
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
6-
import { CreatedCustomerSwagger, CreateCustomerSwagger } from 'src/internal/application/docs/swagger/customers/create-customer.dto';
3+
import { responseError } from 'src/external/infra/errors/reponse.error';
4+
import {
5+
CreatedCustomerSwagger,
6+
CreateCustomerSwagger,
7+
} from 'src/internal/application/docs/swagger/customers/create-customer.dto';
8+
import { CreateCustomerDto } from 'src/internal/domain/customers/dto/create-customer.dto';
9+
10+
import { CustomersService } from './customer.service';
711

812
@ApiTags('Customers')
913
@Controller('customers')
1014
export class CustomerController {
11-
constructor(private readonly customersService: CustomersService) { }
15+
constructor(private readonly customersService: CustomersService) {}
1216

1317
@ApiOperation({ summary: 'Create Customer' })
1418
@ApiBody({ type: CreateCustomerSwagger })
15-
@ApiResponse({ status: 201, description: 'Customer successfully created.', type: CreatedCustomerSwagger })
19+
@ApiResponse({
20+
status: 201,
21+
description: 'Customer successfully created.',
22+
type: CreatedCustomerSwagger,
23+
})
1624
@Post()
1725
create(@Body() createCustomerDto: CreateCustomerDto) {
1826
try {
1927
return this.customersService.create(createCustomerDto);
20-
} catch (err: any) {
21-
responseError(err);
28+
} catch (err) {
29+
return responseError(err);
30+
}
31+
}
32+
33+
@Get(':cpf')
34+
async getCustomer(@Param('cpf') cpf: string) {
35+
try {
36+
return await this.customersService.findByCpf(cpf);
37+
} catch (err) {
38+
return responseError(err);
2239
}
2340
}
2441
}

src/external/adapters/customer/customer.service.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Inject, Injectable } from '@nestjs/common';
2+
import { NotFoundException } from 'src/internal/application/errors';
23
import { IIdentifierGenerator } from 'src/internal/application/ports/tokens/id-generator';
34
import { CreateCustomerDto } from 'src/internal/domain/customers/dto/create-customer.dto';
45
import { Customer } from 'src/internal/domain/customers/entities/customer.entity';
@@ -52,4 +53,10 @@ export class CustomersService {
5253
async findById(id: string) {
5354
return this.customerRepository.findOne(id);
5455
}
56+
57+
async findByCpf(cpf: string): Promise<Customer> {
58+
const customer = await this.customerRepository.findByCpf(cpf);
59+
if (!customer) throw new NotFoundException('Customer not exists.');
60+
return customer;
61+
}
5562
}

src/external/adapters/product/product.module.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { Module } from '@nestjs/common';
2-
import { SequelizeModule } from '@nestjs/sequelize';
32
import { EventEmitter2 } from '@nestjs/event-emitter';
4-
import { ProductsService } from './product.service';
3+
import { SequelizeModule } from '@nestjs/sequelize';
4+
import { Uuid } from 'src/external/infra/tokens/uuid/uuid';
5+
6+
import { DecrementProductListener } from './listeners/decrement-product.listener';
57
import { ProductController } from './product.controller';
8+
import { ProductsService } from './product.service';
69
import { ProductSequelizeRepository } from './sequelize/product-sequelize.repository';
710
import { ProductModel } from './sequelize/product.model';
8-
import { Uuid } from 'src/external/infra/tokens/uuid/uuid';
9-
import { DecrementProductListener } from './listeners/decrement-product.listener';
1011

1112
@Module({
1213
imports: [SequelizeModule.forFeature([ProductModel])],
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {
2+
closeDatabase,
3+
initDatabase,
4+
} from 'src/external/infra/database/sequelize';
5+
import { IProductRepository } from 'src/internal/domain/product/repositories/product.repository';
6+
7+
import { ProductSequelizeRepository } from './product-sequelize.repository';
8+
import { ProductModel } from './product.model';
9+
10+
let model: typeof ProductModel;
11+
let repository: IProductRepository;
12+
13+
describe('Product Sequelize Repository', () => {
14+
beforeAll(async () => {
15+
await initDatabase();
16+
model = ProductModel;
17+
repository = new ProductSequelizeRepository(model);
18+
});
19+
afterAll(async () => closeDatabase());
20+
21+
describe('updateQuantity', () => {
22+
it('should update product quantity by id', async () => {
23+
// arrange
24+
const productId = 'abcd-efgh-ijkl';
25+
const quantity = 1;
26+
await model.create({
27+
id: productId,
28+
name: 'product-name-test',
29+
category: 'category-name-test',
30+
description: 'description-name-test',
31+
price: 140,
32+
quantity,
33+
});
34+
// act
35+
const newQuantity = await repository.updateQuantity(productId, 2);
36+
const productModel = await model.findOne({ where: { id: productId } });
37+
// assert
38+
expect(newQuantity).toBe(2);
39+
expect(newQuantity).not.toBe(quantity);
40+
expect(productModel.quantity).toBe(newQuantity);
41+
});
42+
});
43+
});

src/external/adapters/product/sequelize/product-sequelize.repository.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
import { NotFoundException } from '@nestjs/common';
12
import { InjectModel } from '@nestjs/sequelize';
3+
import { Op } from 'sequelize';
24
import { Product } from 'src/internal/domain/product/entities/product.entity';
35
import { IProductRepository } from 'src/internal/domain/product/repositories/product.repository';
6+
47
import { ProductModel } from './product.model';
5-
import { NotFoundException } from '@nestjs/common';
6-
import { Op } from 'sequelize';
78

89
export class ProductSequelizeRepository implements IProductRepository {
910
constructor(
@@ -23,7 +24,7 @@ export class ProductSequelizeRepository implements IProductRepository {
2324
if (!productModel)
2425
throw new NotFoundException('product category not exists.');
2526

26-
return productModel.map((pm) => {
27+
return productModel.map(pm => {
2728
return new Product({
2829
id: pm.id,
2930
category: pm.category,
@@ -52,7 +53,7 @@ export class ProductSequelizeRepository implements IProductRepository {
5253
async findAll(): Promise<Product[]> {
5354
const productsModel = await this.model.findAll();
5455

55-
return productsModel.map((p) => {
56+
return productsModel.map(p => {
5657
return new Product({
5758
id: p.id,
5859
name: p.name,

0 commit comments

Comments
 (0)