Browse Source

Immutable commands - wip

pull/68/head
etomas 8 years ago
parent
commit
67ab1159df
5 changed files with 82 additions and 61 deletions
  1. +25
    -12
      src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs
  2. +10
    -4
      src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
  3. +0
    -7
      src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
  4. +24
    -26
      test/Services/FunctionalTests/Services/Ordering/OrderingScenarios.cs
  5. +23
    -12
      test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs

+ 25
- 12
src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs View File

@ -11,27 +11,25 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
{
private readonly List<OrderItemDTO> _orderItems;
public string City { get; set; }
public string City { get; private set; }
public string Street { get; set; }
public string Street { get; private set; }
public string State { get; set; }
public string State { get; private set; }
public string Country { get; set; }
public string Country { get; private set; }
public string ZipCode { get; set; }
public string ZipCode { get; private set; }
public string CardNumber { get; set; }
public string CardNumber { get; private set; }
public string CardHolderName { get; set; }
public string CardHolderName { get; private set; }
public DateTime CardExpiration { get; set; }
public DateTime CardExpiration { get; private set; }
public string CardSecurityNumber { get; set; }
public string CardSecurityNumber { get; private set; }
public int CardTypeId { get; set; }
public string BuyerIdentityGuid { get; set; }
public int CardTypeId { get; private set; }
public IEnumerable<OrderItemDTO> OrderItems => _orderItems;
@ -45,6 +43,21 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands
_orderItems = new List<OrderItemDTO>();
}
public CreateOrderCommand(string city, string street, string state, string country, string zipcode,
string cardNumber, string cardHolderName, DateTime cardExpiration,
string cardSecurityNumber, int cardTypeId) : this()
{
City = city;
Street = street;
State = state;
Country = country;
ZipCode = zipcode;
CardNumber = cardNumber;
CardHolderName = cardHolderName;
CardSecurityNumber = cardSecurityNumber;
CardTypeId = cardTypeId;
}
public class OrderItemDTO
{


+ 10
- 4
src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs View File

@ -3,6 +3,7 @@
using Domain.AggregatesModel.BuyerAggregate;
using Domain.AggregatesModel.OrderAggregate;
using MediatR;
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
using System;
using System.Threading.Tasks;
@ -11,12 +12,14 @@
{
private readonly IBuyerRepository<Buyer> _buyerRepository;
private readonly IOrderRepository<Order> _orderRepository;
private readonly IIdentityService _identityService;
// Using DI to inject infrastructure persistence Repositories
public CreateOrderCommandHandler(IBuyerRepository<Buyer> buyerRepository, IOrderRepository<Order> orderRepository)
public CreateOrderCommandHandler(IBuyerRepository<Buyer> buyerRepository, IOrderRepository<Order> orderRepository, IIdentityService identityService)
{
_buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository));
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
_identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
}
public async Task<bool> Handle(CreateOrderCommand message)
@ -26,14 +29,17 @@
// methods and constructor so validations, invariants and business logic
// make sure that consistency is preserved across the whole aggregate
var buyer = await _buyerRepository.FindAsync(message.BuyerIdentityGuid);
var cardTypeId = message.CardTypeId != 0 ? message.CardTypeId : 1;
var buyerGuid = _identityService.GetUserIdentity();
var buyer = await _buyerRepository.FindAsync(buyerGuid);
if (buyer == null)
{
buyer = new Buyer(message.BuyerIdentityGuid);
buyer = new Buyer(buyerGuid);
}
var payment = buyer.AddPaymentMethod(message.CardTypeId,
var payment = buyer.AddPaymentMethod(cardTypeId,
$"Payment Method on {DateTime.UtcNow}",
message.CardNumber,
message.CardSecurityNumber,


+ 0
- 7
src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs View File

@ -30,13 +30,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
[HttpPost]
public async Task<IActionResult> CreateOrder([FromBody]CreateOrderCommand createOrderCommand)
{
if (createOrderCommand.CardTypeId == 0)
{
createOrderCommand.CardTypeId = 1;
}
createOrderCommand.BuyerIdentityGuid = _identityService.GetUserIdentity();
var result = await _mediator.SendAsync(createOrderCommand);
if (result)
{


+ 24
- 26
test/Services/FunctionalTests/Services/Ordering/OrderingScenarios.cs View File

@ -65,19 +65,18 @@
string BuildOrder()
{
var order = new CreateOrderCommand()
{
CardExpiration = DateTime.UtcNow.AddYears(1),
CardNumber = "5145-555-5555",
CardHolderName = "Jhon Senna",
CardSecurityNumber = "232",
CardTypeId = 1,
City = "Redmon",
Country = "USA",
State = "WA",
Street = "One way",
ZipCode = "zipcode",
};
var order = new CreateOrderCommand(
cardExpiration: DateTime.UtcNow.AddYears(1),
cardNumber: "5145-555-5555",
cardHolderName: "Jhon Senna",
cardSecurityNumber: "232",
cardTypeId: 1,
city: "Redmon",
country: "USA",
state: "WA",
street: "One way",
zipcode: "zipcode"
);
order.AddOrderItem(new OrderItemDTO()
{
@ -92,19 +91,18 @@
}
string BuildOrderWithInvalidExperationTime()
{
var order = new CreateOrderCommand()
{
CardExpiration = DateTime.UtcNow.AddYears(-1),
CardNumber = "5145-555-5555",
CardHolderName = "Jhon Senna",
CardSecurityNumber = "232",
CardTypeId = 1,
City = "Redmon",
Country = "USA",
State = "WA",
Street = "One way",
ZipCode = "zipcode"
};
var order = new CreateOrderCommand(
cardExpiration: DateTime.UtcNow.AddYears(-1),
cardNumber: "5145-555-5555",
cardHolderName: "Jhon Senna",
cardSecurityNumber: "232",
cardTypeId: 1,
city: "Redmon",
country: "USA",
state: "WA",
street: "One way",
zipcode: "zipcode"
);
return JsonConvert.SerializeObject(order);
}


+ 23
- 12
test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs View File

@ -1,4 +1,5 @@
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Moq;
@ -13,19 +14,23 @@ namespace UnitTest.Ordering.Application
{
private readonly Mock<IBuyerRepository<Buyer>> _buyerRepositoryMock;
private readonly Mock<IOrderRepository<Order>> _orderRepositoryMock;
private readonly Mock<IIdentityService> _identityServiceMock;
public NewOrderRequestHandlerTest()
{
_buyerRepositoryMock = new Mock<IBuyerRepository<Buyer>>();
_orderRepositoryMock = new Mock<IOrderRepository<Order>>();
_identityServiceMock = new Mock<IIdentityService>();
}
[Fact]
public async Task Handle_returns_true_when_order_is_persisted_succesfully()
{
var buyerId = "1234";
// Arrange
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid))
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(buyerId))
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
@ -37,8 +42,9 @@ namespace UnitTest.Ordering.Application
_orderRepositoryMock.Setup(or => or.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
.Returns(Task.FromResult(1));
_identityServiceMock.Setup(svc => svc.GetUserIdentity()).Returns(buyerId);
//Act
var handler = new CreateOrderCommandHandler(_buyerRepositoryMock.Object, _orderRepositoryMock.Object);
var handler = new CreateOrderCommandHandler(_buyerRepositoryMock.Object, _orderRepositoryMock.Object, _identityServiceMock.Object);
var result = await handler.Handle(FakeOrderRequestWithBuyer());
//Assert
@ -48,7 +54,8 @@ namespace UnitTest.Ordering.Application
[Fact]
public async Task Handle_return_false_if_order_is_not_persisted()
{
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(FakeOrderRequestWithBuyer().BuyerIdentityGuid))
var buyerId = "1234";
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.FindAsync(buyerId))
.Returns(Task.FromResult<Buyer>(FakeBuyer()));
_buyerRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
@ -57,9 +64,10 @@ namespace UnitTest.Ordering.Application
_orderRepositoryMock.Setup(or => or.Add(FakeOrder())).Returns(FakeOrder());
_orderRepositoryMock.Setup(or => or.UnitOfWork.SaveChangesAsync(default(CancellationToken)))
.Returns(Task.FromResult(0));
_identityServiceMock.Setup(svc => svc.GetUserIdentity()).Returns(buyerId);
//Act
var handler = new CreateOrderCommandHandler(_buyerRepositoryMock.Object, _orderRepositoryMock.Object);
var handler = new CreateOrderCommandHandler(_buyerRepositoryMock.Object, _orderRepositoryMock.Object, _identityServiceMock.Object);
var result = await handler.Handle(FakeOrderRequestWithBuyer());
//Assert
@ -78,14 +86,17 @@ namespace UnitTest.Ordering.Application
private CreateOrderCommand FakeOrderRequestWithBuyer()
{
return new CreateOrderCommand
{
BuyerIdentityGuid = "1234",
CardNumber = "1234",
CardExpiration = DateTime.Now.AddYears(1),
CardSecurityNumber = "123",
CardHolderName = "XXX"
};
return new CreateOrderCommand(
city: null,
street: null,
state: null,
country: null,
zipcode: null,
cardNumber: "1234",
cardExpiration: DateTime.Now.AddYears(1),
cardSecurityNumber: "123",
cardHolderName: "XXX",
cardTypeId: 0);
}
}
}

Loading…
Cancel
Save