Skip to content

Commit 778ce79

Browse files
committed
Merge branch 'vs2017' into web-monolithic
2 parents 0994411 + a07bb18 commit 778ce79

5 files changed

Lines changed: 105 additions & 63 deletions

File tree

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

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,57 @@
11
using System;
22
using MediatR;
33
using System.Collections.Generic;
4+
using System.Runtime.Serialization;
45

56
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
67
{
7-
8-
8+
// DDD and CQRS patterns comment: Note that it is recommened to implement immutable Commands
9+
// In this case, its immutability is achieved by having all the setters as private
10+
// plus only being able to update the data just once, when creating the object through its constructor.
11+
// References on Immutable Commands:
12+
// http://cqrs.nu/Faq
13+
// https://docs.spine3.org/motivation/immutability.html
14+
// http://blog.gauffin.org/2012/06/griffin-container-introducing-command-support/
15+
// https://msdn.microsoft.com/en-us/library/bb383979.aspx
16+
17+
[DataContract]
918
public class CreateOrderCommand
1019
:IAsyncRequest<bool>
1120
{
21+
[DataMember]
1222
private readonly List<OrderItemDTO> _orderItems;
1323

14-
public string City { get; set; }
15-
16-
public string Street { get; set; }
24+
[DataMember]
25+
public string City { get; private set; }
1726

18-
public string State { get; set; }
27+
[DataMember]
28+
public string Street { get; private set; }
1929

20-
public string Country { get; set; }
30+
[DataMember]
31+
public string State { get; private set; }
2132

22-
public string ZipCode { get; set; }
33+
[DataMember]
34+
public string Country { get; private set; }
2335

24-
public string CardNumber { get; set; }
36+
[DataMember]
37+
public string ZipCode { get; private set; }
2538

26-
public string CardHolderName { get; set; }
39+
[DataMember]
40+
public string CardNumber { get; private set; }
2741

28-
public DateTime CardExpiration { get; set; }
42+
[DataMember]
43+
public string CardHolderName { get; private set; }
2944

30-
public string CardSecurityNumber { get; set; }
45+
[DataMember]
46+
public DateTime CardExpiration { get; private set; }
3147

32-
public int CardTypeId { get; set; }
48+
[DataMember]
49+
public string CardSecurityNumber { get; private set; }
3350

34-
public string BuyerIdentityGuid { get; set; }
51+
[DataMember]
52+
public int CardTypeId { get; private set; }
3553

54+
[DataMember]
3655
public IEnumerable<OrderItemDTO> OrderItems => _orderItems;
3756

3857
public void AddOrderItem(OrderItemDTO item)
@@ -45,6 +64,21 @@ public CreateOrderCommand()
4564
_orderItems = new List<OrderItemDTO>();
4665
}
4766

67+
public CreateOrderCommand(string city, string street, string state, string country, string zipcode,
68+
string cardNumber, string cardHolderName, DateTime cardExpiration,
69+
string cardSecurityNumber, int cardTypeId) : this()
70+
{
71+
City = city;
72+
Street = street;
73+
State = state;
74+
Country = country;
75+
ZipCode = zipcode;
76+
CardNumber = cardNumber;
77+
CardHolderName = cardHolderName;
78+
CardSecurityNumber = cardSecurityNumber;
79+
CardTypeId = cardTypeId;
80+
}
81+
4882

4983
public class OrderItemDTO
5084
{

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)