Skip to content

Commit

Permalink
feat: product weight (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmarchois authored May 30, 2021
1 parent 8559ebc commit 809b5e8
Show file tree
Hide file tree
Showing 47 changed files with 163 additions and 85 deletions.
16 changes: 16 additions & 0 deletions api/migrations/1622379534005-ProductWeight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {MigrationInterface, QueryRunner} from "typeorm";

export class ProductWeight1622379534005 implements MigrationInterface {
name = 'ProductWeight1622379534005'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "shipping_cost" RENAME COLUMN "grams" TO "weight"`);
await queryRunner.query(`ALTER TABLE "product" ADD "weight" integer NOT NULL DEFAULT 0`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "product" DROP COLUMN "weight"`);
await queryRunner.query(`ALTER TABLE "shipping_cost" RENAME COLUMN "weight" TO "grams"`);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ICommand } from 'src/Application/ICommand';

export class CreateShippingCostCommand implements ICommand {
constructor(
public readonly grams: number,
public readonly weight: number,
public readonly price: number
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ export class CreateShippingCostCommandHandler {
) {}

public async execute(command: CreateShippingCostCommand): Promise<string> {
const { grams, price } = command;
const { weight, price } = command;

if (true === (await this.isShippingCostAlreadyExist.isSatisfiedBy(grams))) {
if (true === (await this.isShippingCostAlreadyExist.isSatisfiedBy(weight))) {
throw new ShippingCostAlreadyExistException();
}

const shippingCost = await this.shippingcostRepository.save(
new ShippingCost(grams, Math.round(price * 100))
new ShippingCost(weight, Math.round(price * 100))
);

return shippingCost.getId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ICommand } from 'src/Application/ICommand';
export class UpdateShippingCostCommand implements ICommand {
constructor(
public readonly id: string,
public readonly grams: number,
public readonly weight: number,
public readonly price: number
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('UpdateShippingCostCommandHandler', () => {
});

it('testShippingCostAlreadyExist', async () => {
when(shippingcost.getGrams()).thenReturn(100);
when(shippingcost.getWeight()).thenReturn(100);
when(
shippingcostRepository.findOneById('8a9df044-94a7-4e6c-abd1-ecdd69d788d5')
).thenResolve(instance(shippingcost));
Expand All @@ -77,7 +77,7 @@ describe('UpdateShippingCostCommandHandler', () => {

it('testSuccessfullyUpdated', async () => {
when(shippingcost.getId()).thenReturn('8a9df044-94a7-4e6c-abd1-ecdd69d788d5');
when(shippingcost.getGrams()).thenReturn(1000);
when(shippingcost.getWeight()).thenReturn(1000);
when(
shippingcostRepository.findOneById('8a9df044-94a7-4e6c-abd1-ecdd69d788d5')
).thenResolve(instance(shippingcost));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ export class UpdateShippingCostCommandHandler {
) {}

public async execute(command: UpdateShippingCostCommand): Promise<string> {
const { id, grams, price } = command;
const { id, weight, price } = command;

const shippingCost = await this.shippingcostRepository.findOneById(id);
if (!shippingCost) {
throw new ShippingCostNotFoundException();
}

if (
grams !== shippingCost.getGrams() &&
true === (await this.isShippingCostAlreadyExist.isSatisfiedBy(grams))
weight !== shippingCost.getWeight() &&
true === (await this.isShippingCostAlreadyExist.isSatisfiedBy(weight))
) {
throw new ShippingCostAlreadyExistException();
}

shippingCost.update(grams, Math.round(price * 100));
shippingCost.update(weight, Math.round(price * 100));

await this.shippingcostRepository.save(shippingCost);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('GetShippingCostByIdQueryHandler', () => {

const shippingcost = mock(ShippingCost);
when(shippingcost.getId()).thenReturn('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2');
when(shippingcost.getGrams()).thenReturn(1000);
when(shippingcost.getWeight()).thenReturn(1000);
when(shippingcost.getPriceFromCents()).thenReturn(9.99);
when(
shippingcostRepository.findOneById('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class GetShippingCostByIdQueryHandler {

return new ShippingCostView(
shippingCost.getId(),
shippingCost.getGrams(),
shippingCost.getWeight(),
shippingCost.getPriceFromCents(),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ describe('GetShippingCostsQueryHandler', () => {
const shippingcost1 = mock(ShippingCost);
when(shippingcost1.getId()).thenReturn('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2');
when(shippingcost1.getPriceFromCents()).thenReturn(9.99);
when(shippingcost1.getGrams()).thenReturn(1000);
when(shippingcost1.getWeight()).thenReturn(1000);

const shippingcost2 = mock(ShippingCost);
when(shippingcost2.getId()).thenReturn('d54f15d6-1a1d-47e8-8672-9f46018f9960');
when(shippingcost2.getPriceFromCents()).thenReturn(3.99);
when(shippingcost2.getGrams()).thenReturn(500);
when(shippingcost2.getWeight()).thenReturn(500);

when(shippingcostRepository.findShippingCosts()).thenResolve([
instance(shippingcost2), instance(shippingcost1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class GetShippingCostsQueryHandler {
shippingcostViews.push(
new ShippingCostView(
shippingCost.getId(),
shippingCost.getGrams(),
shippingCost.getWeight(),
shippingCost.getPriceFromCents(),
)
);
Expand Down
2 changes: 1 addition & 1 deletion api/src/Application/Order/View/ShippingCostView.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export class ShippingCostView {
constructor(
public readonly id: string,
public readonly grams: number,
public readonly weight: number,
public readonly price: number,
) {}
}
3 changes: 2 additions & 1 deletion api/src/Application/Product/Command/CreateProductCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export class CreateProductCommand implements ICommand {
constructor(
public readonly title: string,
public readonly description: string,
public readonly unitPrice: number
public readonly unitPrice: number,
public readonly weight: number
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('CreateProductCommandHandler', () => {
'Mug',
'Mug portrait enfant',
9.99,
1000
);

beforeEach(() => {
Expand All @@ -41,6 +42,7 @@ describe('CreateProductCommandHandler', () => {
'Mug',
'Mug portrait enfant',
999,
1000
)
)
)
Expand All @@ -58,6 +60,7 @@ describe('CreateProductCommandHandler', () => {
'Mug',
'Mug portrait enfant',
999,
1000
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ export class CreateProductCommandHandler {
) {}

public async execute(command: CreateProductCommand): Promise<string> {
const { title, description, unitPrice } = command;
const { title, description, unitPrice, weight } = command;

if (true === (await this.isProductAlreadyExist.isSatisfiedBy(title))) {
throw new ProductAlreadyExistException();
}

const product = await this.productRepository.save(
new Product(title, description, Math.round(unitPrice * 100))
new Product(title, description, Math.round(unitPrice * 100), weight)
);

return product.getId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export class UpdateProductCommand implements ICommand {
public readonly id: string,
public readonly title: string,
public readonly unitPrice: number,
public readonly weight: number,
public readonly description?: string
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('UpdateProductCommandHandler', () => {
'8a9df044-94a7-4e6c-abd1-ecdd69d788d5',
'Mug',
9.99,
1000,
'Mug portrait'
);

Expand Down Expand Up @@ -46,7 +47,7 @@ describe('UpdateProductCommandHandler', () => {
verify(isProductAlreadyExist.isSatisfiedBy(anything())).never();
verify(productRepository.save(anything())).never();
verify(
product.update(anything(), anything(), anything())
product.update(anything(), anything(), anything(), anything())
).never();
}
});
Expand All @@ -70,7 +71,7 @@ describe('UpdateProductCommandHandler', () => {
isProductAlreadyExist.isSatisfiedBy('Mug')
).once();
verify(
product.update(anything(), anything(), anything())
product.update(anything(), anything(), anything(), anything())
).never();
verify(productRepository.save(anything())).never();
}
Expand All @@ -92,7 +93,8 @@ describe('UpdateProductCommandHandler', () => {
product.update(
'Mug',
'Mug portrait',
999
999,
1000
)
).calledBefore(productRepository.save(instance(product)));
verify(productRepository.save(instance(product))).once();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class UpdateProductCommandHandler {
) {}

public async execute(command: UpdateProductCommand): Promise<string> {
const { id, title, description, unitPrice } = command;
const { id, title, description, unitPrice, weight } = command;

const product = await this.productRepository.findOneById(id);
if (!product) {
Expand All @@ -29,7 +29,7 @@ export class UpdateProductCommandHandler {
throw new ProductAlreadyExistException();
}

product.update(title, description, Math.round(unitPrice * 100));
product.update(title, description, Math.round(unitPrice * 100), weight);

await this.productRepository.save(product);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ describe('GetProductByIdQueryHandler', () => {
'eb9e1d9b-dce2-48a9-b64f-f0872f3157d2',
'Mug',
9.99,
1000,
'Mug portrait enfant'
);

const product = mock(Product);
when(product.getId()).thenReturn('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2');
when(product.getTitle()).thenReturn('Mug');
when(product.getDescription()).thenReturn('Mug portrait enfant');
when(product.getWeight()).thenReturn(1000);
when(product.getPriceFromCents()).thenReturn(9.99);
when(
productRepository.findOneById('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class GetProductByIdQueryHandler {
product.getId(),
product.getTitle(),
product.getPriceFromCents(),
product.getWeight(),
product.getDescription()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ describe('GetProductsQueryHandler', () => {
when(product1.getId()).thenReturn('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2');
when(product1.getTitle()).thenReturn('Mug');
when(product1.getDescription()).thenReturn('Mug portrait enfant');
when(product1.getWeight()).thenReturn(1000);
when(product1.getPriceFromCents()).thenReturn(9.99);

const product2 = mock(Product);
when(product2.getId()).thenReturn('d54f15d6-1a1d-47e8-8672-9f46018f9960');
when(product2.getTitle()).thenReturn('Porte clef');
when(product2.getWeight()).thenReturn(200);
when(product2.getPriceFromCents()).thenReturn(10);

when(productRepository.findProducts(1)).thenResolve([
Expand All @@ -34,12 +36,14 @@ describe('GetProductsQueryHandler', () => {
'd54f15d6-1a1d-47e8-8672-9f46018f9960',
'Porte clef',
10,
200,
null
),
new ProductView(
'eb9e1d9b-dce2-48a9-b64f-f0872f3157d2',
'Mug',
9.99,
1000,
'Mug portrait enfant'
)
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class GetProductsQueryHandler {
product.getId(),
product.getTitle(),
product.getPriceFromCents(),
product.getWeight(),
product.getDescription(),
)
);
Expand Down
1 change: 1 addition & 0 deletions api/src/Application/Product/View/ProductView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export class ProductView {
public readonly id: string,
public readonly title: string,
public readonly unitPrice: number,
public readonly weight: number,
public readonly description?: string
) {}
}
2 changes: 1 addition & 1 deletion api/src/Domain/Order/Repository/IShippingCostRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ShippingCost } from '../ShippingCost.entity';
export interface IShippingCostRepository {
save(shippingcost: ShippingCost): Promise<ShippingCost>;
remove(shippingcost: ShippingCost): void;
findOneByGrams(grams: number): Promise<ShippingCost | undefined>;
findOneByWeight(weight: number): Promise<ShippingCost | undefined>;
findShippingCosts(): Promise<ShippingCost[]>;
findOneById(id: string): Promise<ShippingCost | undefined>;
}
6 changes: 3 additions & 3 deletions api/src/Domain/Order/ShippingCost.entity.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('ShippingCost', () => {
999
);
expect(shippingcost.getId()).toBeUndefined();
expect(shippingcost.getGrams()).toBe(1000);
expect(shippingcost.getWeight()).toBe(1000);
expect(shippingcost.getPrice()).toBe(999);
expect(shippingcost.getPriceFromCents()).toBe(9.99);
});
Expand All @@ -18,12 +18,12 @@ describe('ShippingCost', () => {
999
);
expect(shippingcost.getId()).toBeUndefined();
expect(shippingcost.getGrams()).toBe(1000);
expect(shippingcost.getWeight()).toBe(1000);
expect(shippingcost.getPrice()).toBe(999);
expect(shippingcost.getPriceFromCents()).toBe(9.99);

shippingcost.update(100, 399);
expect(shippingcost.getGrams()).toBe(100);
expect(shippingcost.getWeight()).toBe(100);
expect(shippingcost.getPrice()).toBe(399);
expect(shippingcost.getPriceFromCents()).toBe(3.99);
});
Expand Down
Loading

0 comments on commit 809b5e8

Please sign in to comment.