Skip to content

Commit 67ab115

Browse files
committed
Immutable commands - wip
1 parent b416203 commit 67ab115

5 files changed

Lines changed: 82 additions & 61 deletions

File tree

src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,25 @@ public class CreateOrderCommand
1111
{
1212
private readonly List<OrderItemDTO> _orderItems;
1313

14-
public string City { get; set; }
14+
public string City { get; private set; }
1515

16-
public string Street { get; set; }
16+
public string Street { get; private set; }
1717

18-
public string State { get; set; }
18+
public string State { get; private set; }
1919

20-
public string Country { get; set; }
20+
public string Country { get; private set; }
2121

22-
public string ZipCode { get; set; }
22+
public string ZipCode { get; private set; }
2323

24-
public string CardNumber { get; set; }
24+
public string CardNumber { get; private set; }
2525

26-
public string CardHolderName { get; set; }
26+
public string CardHolderName { get; private set; }
2727

28-
public DateTime CardExpiration { get; set; }
28+
public DateTime CardExpiration { get; private set; }
2929

30-
public string CardSecurityNumber { get; set; }
30+
public string CardSecurityNumber { get; private set; }
3131

32-
public int CardTypeId { get; set; }
33-
34-
public string BuyerIdentityGuid { get; set; }
32+
public int CardTypeId { get; private set; }
3533

3634
public IEnumerable<OrderItemDTO> OrderItems => _orderItems;
3735

@@ -45,6 +43,21 @@ public CreateOrderCommand()
4543
_orderItems = new List<OrderItemDTO>();
4644
}
4745

46+
public CreateOrderCommand(string city, string street, string state, string country, string zipcode,
47+
string cardNumber, string cardHolderName, DateTime cardExpiration,
48+
string cardSecurityNumber, int cardTypeId) : this()
49+
{
50+
City = city;
51+
Street = street;
52+
State = state;
53+
Country = country;
54+
ZipCode = zipcode;
55+
CardNumber = cardNumber;
56+
CardHolderName = cardHolderName;
57+
CardSecurityNumber = cardSecurityNumber;
58+
CardTypeId = cardTypeId;
59+
}
60+
4861

4962
public class OrderItemDTO
5063
{

src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Domain.AggregatesModel.BuyerAggregate;
44
using Domain.AggregatesModel.OrderAggregate;
55
using MediatR;
6+
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
67
using System;
78
using System.Threading.Tasks;
89

@@ -11,12 +12,14 @@ public class CreateOrderCommandHandler
1112
{
1213
private readonly IBuyerRepository<Buyer> _buyerRepository;
1314
private readonly IOrderRepository<Order> _orderRepository;
15+
private readonly IIdentityService _identityService;
1416

1517
// Using DI to inject infrastructure persistence Repositories
16-
public CreateOrderCommandHandler(IBuyerRepository<Buyer> buyerRepository, IOrderRepository<Order> orderRepository)
18+
public CreateOrderCommandHandler(IBuyerRepository<Buyer> buyerRepository, IOrderRepository<Order> orderRepository, IIdentityService identityService)
1719
{
1820
_buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
1921
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
22+
_identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
2023
}
2124

2225
public async Task<bool> Handle(CreateOrderCommand message)
@@ -26,14 +29,17 @@ public async Task<bool> Handle(CreateOrderCommand message)
2629
// methods and constructor so validations, invariants and business logic
2730
// make sure that consistency is preserved across the whole aggregate
2831

29-
var buyer = await _buyerRepository.FindAsync(message.BuyerIdentityGuid);
32+
var cardTypeId = message.CardTypeId != 0 ? message.CardTypeId : 1;
33+
34+
var buyerGuid = _identityService.GetUserIdentity();
35+
var buyer = await _buyerRepository.FindAsync(buyerGuid);
3036

3137
if (buyer == null)
3238
{
33-
buyer = new Buyer(message.BuyerIdentityGuid);
39+
buyer = new Buyer(buyerGuid);
3440
}
3541

36-
var payment = buyer.AddPaymentMethod(message.CardTypeId,
42+
var payment = buyer.AddPaymentMethod(cardTypeId,
3743
$"Payment Method on {DateTime.UtcNow}",
3844
message.CardNumber,
3945
message.CardSecurityNumber,

src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,6 @@ public OrdersController(IMediator mediator, IOrderQueries orderQueries, IIdentit
3030
[HttpPost]
3131
public async Task<IActionResult> CreateOrder([FromBody]CreateOrderCommand createOrderCommand)
3232
{
33-
if (createOrderCommand.CardTypeId == 0)
34-
{
35-
createOrderCommand.CardTypeId = 1;
36-
}
37-
38-
createOrderCommand.BuyerIdentityGuid = _identityService.GetUserIdentity();
39-
4033
var result = await _mediator.SendAsync(createOrderCommand);
4134
if (result)
4235
{

test/Services/FunctionalTests/Services/Ordering/OrderingScenarios.cs

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,18 @@ public async Task AddNewOrder_response_bad_request_if_card_expiration_is_invalid
6565

6666
string BuildOrder()
6767
{
68-
var order = new CreateOrderCommand()
69-
{
70-
CardExpiration = DateTime.UtcNow.AddYears(1),
71-
CardNumber = "5145-555-5555",
72-
CardHolderName = "Jhon Senna",
73-
CardSecurityNumber = "232",
74-
CardTypeId = 1,
75-
City = "Redmon",
76-
Country = "USA",
77-
State = "WA",
78-
Street = "One way",
79-
ZipCode = "zipcode",
80-
};
68+
var order = new CreateOrderCommand(
69+
cardExpiration: DateTime.UtcNow.AddYears(1),
70+
cardNumber: "5145-555-5555",
71+
cardHolderName: "Jhon Senna",
72+
cardSecurityNumber: "232",
73+
cardTypeId: 1,
74+
city: "Redmon",
75+
country: "USA",
76+
state: "WA",
77+
street: "One way",
78+
zipcode: "zipcode"
79+
);
8180

8281
order.AddOrderItem(new OrderItemDTO()
8382
{
@@ -92,19 +91,18 @@ string BuildOrder()
9291
}
9392
string BuildOrderWithInvalidExperationTime()
9493
{
95-
var order = new CreateOrderCommand()
96-
{
97-
CardExpiration = DateTime.UtcNow.AddYears(-1),
98-
CardNumber = "5145-555-5555",
99-
CardHolderName = "Jhon Senna",
100-
CardSecurityNumber = "232",
101-
CardTypeId = 1,
102-
City = "Redmon",
103-
Country = "USA",
104-
State = "WA",
105-
Street = "One way",
106-
ZipCode = "zipcode"
107-
};
94+
var order = new CreateOrderCommand(
95+
cardExpiration: DateTime.UtcNow.AddYears(-1),
96+
cardNumber: "5145-555-5555",
97+
cardHolderName: "Jhon Senna",
98+
cardSecurityNumber: "232",
99+
cardTypeId: 1,
100+
city: "Redmon",
101+
country: "USA",
102+
state: "WA",
103+
street: "One way",
104+
zipcode: "zipcode"
105+
);
108106

109107
return JsonConvert.SerializeObject(order);
110108
}

test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
2+
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
23
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
34
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
45
using Moq;
@@ -13,19 +14,23 @@ public class NewOrderRequestHandlerTest
1314
{
1415
private readonly Mock<IBuyerRepository<Buyer>> _buyerRepositoryMock;
1516
private readonly Mock<IOrderRepository<Order>> _orderRepositoryMock;
17+
private readonly Mock<IIdentityService> _identityServiceMock;
1618

1719
public NewOrderRequestHandlerTest()
1820
{
1921

2022
_buyerRepositoryMock = new Mock<IBuyerRepository<Buyer>>();
2123
_orderRepositoryMock = new Mock<IOrderRepository<Order>>();
24+
_identityServiceMock = new Mock<IIdentityService>();
2225
}
2326

2427
[Fact]
2528
public async Task Handle_returns_true_when_order_is_persisted_succesfully()
2629
{
30+
31+
var buyerId = "1234";
2732
// Arrange
28-
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid))
33+
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(buyerId))
2934
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
3035

3136
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
@@ -37,8 +42,9 @@ public async Task Handle_returns_true_when_order_is_persisted_succesfully()
3742
_orderRepositoryMock.Setup(or => or.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
3843
.Returns(Task.FromResult(1));
3944

45+
_identityServiceMock.Setup(svc => svc.GetUserIdentity()).Returns(buyerId);
4046
//Act
41-
var handler = new CreateOrderCommandHandler(_buyerRepositoryMock.Object, _orderRepositoryMock.Object);
47+
var handler = new CreateOrderCommandHandler(_buyerRepositoryMock.Object, _orderRepositoryMock.Object, _identityServiceMock.Object);
4248
var result = await handler.Handle(FakeOrderRequestWithBuyer());
4349

4450
//Assert
@@ -48,7 +54,8 @@ public async Task Handle_returns_true_when_order_is_persisted_succesfully()
4854
[Fact]
4955
public async Task Handle_return_false_if_order_is_not_persisted()
5056
{
51-
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid))
57+
var buyerId = "1234";
58+
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(buyerId))
5259
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
5360

5461
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
@@ -57,9 +64,10 @@ public async Task Handle_return_false_if_order_is_not_persisted()
5764
_orderRepositoryMock.Setup(or => or.Add(FakeOrder())).Returns(FakeOrder());
5865
_orderRepositoryMock.Setup(or => or.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
5966
.Returns(Task.FromResult(0));
67+
_identityServiceMock.Setup(svc => svc.GetUserIdentity()).Returns(buyerId);
6068

6169
//Act
62-
var handler = new CreateOrderCommandHandler(_buyerRepositoryMock.Object, _orderRepositoryMock.Object);
70+
var handler = new CreateOrderCommandHandler(_buyerRepositoryMock.Object, _orderRepositoryMock.Object, _identityServiceMock.Object);
6371
var result = await handler.Handle(FakeOrderRequestWithBuyer());
6472

6573
//Assert
@@ -78,14 +86,17 @@ private Order FakeOrder()
7886

7987
private CreateOrderCommand FakeOrderRequestWithBuyer()
8088
{
81-
return new CreateOrderCommand
82-
{
83-
BuyerIdentityGuid = "1234",
84-
CardNumber = "1234",
85-
CardExpiration = DateTime.Now.AddYears(1),
86-
CardSecurityNumber = "123",
87-
CardHolderName = "XXX"
88-
};
89+
return new CreateOrderCommand(
90+
city: null,
91+
street: null,
92+
state: null,
93+
country: null,
94+
zipcode: null,
95+
cardNumber: "1234",
96+
cardExpiration: DateTime.Now.AddYears(1),
97+
cardSecurityNumber: "123",
98+
cardHolderName: "XXX",
99+
cardTypeId: 0);
89100
}
90101
}
91102
}

0 commit comments

Comments
 (0)