public async Task <IStatusGeneric <Order> > //#A CreateOrderAndSaveAsync(PlaceOrderInDto dto) //#B { var status = new StatusGenericHandler <Order>(); //#C if (!dto.AcceptTAndCs) //#D { return(status.AddError("You must accept the T&Cs to place an order.")); } if (!dto.LineItems.Any()) //#D { return(status.AddError("No items in your basket.")); } var booksDict = await _dbAccess //#E .FindBooksByIdsAsync //#E (dto.LineItems.Select(x => x.BookId)); //#E var linesStatus = FormLineItemsWithErrorChecking //#F (dto.LineItems, booksDict); //#F if (status.CombineStatuses(linesStatus).HasErrors) //#G { return(status); //#G } var orderStatus = Order.CreateOrder( //#H dto.UserId, linesStatus.Result); //#H if (status.CombineStatuses(orderStatus).HasErrors) //#I { return(status); //#I } await _dbAccess.AddAndSave(orderStatus.Result); //#J return(status.SetResult(orderStatus.Result)); //#K }
public async Task TestCreateOrderOneBookOk() { //SETUP var userId = Guid.NewGuid(); var options = SqliteInMemory.CreateOptions <OrderDbContext>(); options.StopNextDispose(); using var context = new OrderDbContext(options, new FakeUserIdService(userId)); context.Database.EnsureCreated(); var bookIds = context.SeedFourBookDdPartWithOptionalDbSchemaAdd(true); var service = new PlaceOrderBizLogic(new PlaceOrderDbAccess(context)); //ATTEMPT var lineItems = new List <OrderLineItem> { new OrderLineItem { BookId = 1, NumBooks = 4 }, }; var dto = new PlaceOrderInDto(true, userId, lineItems.ToImmutableList()); var status = await service.CreateOrderAndSaveAsync(dto); //VERIFY status.IsValid.ShouldBeTrue(status.GetAllErrors()); context.ChangeTracker.Clear(); var order = context.Orders.Include(x => x.LineItems).Single(); var lineItem = order.LineItems.Single(); lineItem.BookId.ShouldEqual(1); lineItem.NumBooks.ShouldEqual((short)4); lineItem.BookPrice.ShouldEqual(40); }
public async Task TestCreateOrderTAndCsBad() { //SETUP var userId = Guid.NewGuid(); var options = SqliteInMemory.CreateOptions <OrderDbContext>(); using var context = new OrderDbContext(options, new FakeUserIdService(userId)); context.Database.EnsureCreated(); var service = new PlaceOrderBizLogic(new PlaceOrderDbAccess(context)); //ATTEMPT var lineItems = new List <OrderLineItem> { new OrderLineItem { BookId = 1, NumBooks = 4 }, }; var dto = new PlaceOrderInDto(false, userId, lineItems.ToImmutableList()); var status = await service.CreateOrderAndSaveAsync(dto); //VERIFY status.IsValid.ShouldBeFalse(); status.GetAllErrors().ShouldEqual("You must accept the T&Cs to place an order."); }
/// <summary> /// This validates the input and if OK creates /// an order and calls the _dbAccess to add to orders /// </summary> /// <param name="dto"></param> /// <returns>returns an Order. Will be null if there are errors</returns> public Order BizAction(PlaceOrderInDto dto) { if (!dto.AcceptTAndCs) { AddError("You must accept the T&Cs to place an order."); return(null); } if (!dto.LineItems.Any()) { AddError("No items in your basket."); return(null); } var booksDict = _dbAccess.FindBooksByIdsWithPriceOffers (dto.LineItems.Select(x => x.BookId)); var order = new Order { CustomerName = dto.UserId, ExpectedDeliveryDate = DateTime.Today.AddDays(5), LineItems = FormLineItemsWithErrorChecking(dto.LineItems, booksDict) }; if (!HasErrors) { _dbAccess.Add(order); } return(HasErrors ? null : order); }
public IActionResult PlaceOrder(PlaceOrderInDto dto, [FromServices] IActionService <IRepository, IPlaceOrderAction> service) { if (!ModelState.IsValid) { //model errors so return to checkout page, showing the basket return(View("Index", FormCheckoutDtoFromCookie(HttpContext))); } //This runs my business logic using the service injected into the Action's parameters var orderDto = service.RunBizAction <OrderIdDto>(dto); if (!service.Status.HasErrors) { //If successful I need to clear the line items from the basket cookie ClearCheckoutCookie(HttpContext); SetupTraceInfo(); //Used to update the logs return(RedirectToAction("ConfirmOrder", "Orders", new { orderDto.OrderId, Message = "Your order is confirmed" })); } //Otherwise errors, so I need to redisplay the basket from the cookie var checkoutDto = FormCheckoutDtoFromCookie(HttpContext); //This copies the errors to the ModelState service.Status.CopyErrorsToModelState(ModelState, checkoutDto); SetupTraceInfo(); //Used to update the logs return(View("Index", checkoutDto)); }
public void TestAddOrderViaBizLogicOk() { //SETUP var options = SqliteInMemory.CreateOptions <EfCoreContext>(); using (var context = new EfCoreContext(options)) { context.Database.EnsureCreated(); context.SeedDatabaseFourBooks(); var service = new PlaceOrderAction(new PlaceOrderDbAccess(context)); var dto = new PlaceOrderInDto { AcceptTAndCs = true, CheckoutLineItems = new List <OrderLineItem> { new OrderLineItem { BookId = 1, NumBooks = 2 } } }; //ATTEMPT var order = service.BizAction(dto); //VERIFY service.HasErrors.ShouldBeFalse(); order.LineItems.Count().ShouldEqual(1); order.LineItems.Single().BookPrice.ShouldEqual(context.Books.Find(1).ActualPrice); } }
public Order Action(PlaceOrderInDto dto) { if (!dto.AcceptTAndCs) { AddError("You must accept the T&Cs to place an order."); return(null); } if (dto.LineItems.Count == 0) { AddError("No items in your basket."); return(null); } var bookIds = dto.LineItems.Select(lineItem => lineItem.BookId); //to present the data as an in-memory set(in this case, a dictionary) var booksDict = dbAccess.FindBooksByIdsWithPriceOffers(bookIds); var order = new Order { CustomerName = dto.UserId, LineItems = FormLineItemsWithErrorChecking(dto.LineItems, booksDict) }; if (!HasErrors) { dbAccess.Add(order); } return(HasErrors ? null : order); }
public int PlaceOrder(bool acceptTAndCs) { var checkoutService = new CheckoutCookieService(checkoutCookie.GetValue()); var placeOrderInDto = new PlaceOrderInDto(acceptTAndCs, checkoutService.UserId, checkoutService.LineItems); var order = runner.RunAction(placeOrderInDto); if (runner.HasErrors) { return(0); } checkoutService.ClearAllLineItems(); checkoutCookie.AddOrUpdateCookie(checkoutService.EncodeForCookie()); return(order.OrderId); }
public async Task TestCreateOrderEmptyBasketBad() { //SETUP var userId = Guid.NewGuid(); var options = SqliteInMemory.CreateOptions <OrderDbContext>(); using var context = new OrderDbContext(options, new FakeUserIdService(userId)); context.Database.EnsureCreated(); var service = new PlaceOrderBizLogic(new PlaceOrderDbAccess(context)); //ATTEMPT var dto = new PlaceOrderInDto(true, userId, (new List <OrderLineItem>()).ToImmutableList()); var status = await service.CreateOrderAndSaveAsync(dto); //VERIFY status.IsValid.ShouldBeFalse(); status.GetAllErrors().ShouldEqual("No items in your basket."); }
/// <summary> /// This validates the input and if OK creates /// an order and calls the _dbAccess to add to orders /// </summary> /// <param name="dto"></param> /// <returns>returns an Order. Will be null if there are errors</returns> public Order BizAction(PlaceOrderInDto dto) { if (!dto.AcceptTAndCs) { AddError("You must accept the T&Cs to place an order."); return(null); } var bookOrders = dto.CheckoutLineItems.Select(x => _dbAccess.BuildBooksDto(x.BookId, x.NumBooks)); var orderStatus = Order.CreateOrderFactory(dto.UserId, DateTime.Today.AddDays(5), bookOrders); CombineErrors(orderStatus); if (!HasErrors) { _dbAccess.Add(orderStatus.Result); } return(orderStatus.Result); }
public Part1ToPart2Dto Action(PlaceOrderInDto dto) { if (!dto.AcceptTAndCs) { AddError("You must accept the T&Cs to place an order."); } if (dto.LineItems.Count == 0) { AddError("No items in your basket."); } Order order = new Order { CustomerName = dto.UserId }; if (!HasErrors) { dbAccess.Add(order); } return(new Part1ToPart2Dto(dto.LineItems, order)); }
public void ExampleOfMockingOk() { //SETUP //#A var lineItems = new List <OrderLineItem> //#A { //#A new OrderLineItem { BookId = 1, NumBooks = 4 }, //#A }; //#A var userId = Guid.NewGuid(); //#A var input = new PlaceOrderInDto(true, userId, //#A lineItems.ToImmutableList()); //#A var mockDbA = new MockPlaceOrderDbAccess(); //#B var service = new PlaceOrderAction(mockDbA); //#C //ATTEMPT service.Action(input); //#D //VERIFY service.Errors.Any().ShouldEqual(false); //# mockDbA.AddedOrder.CustomerId //#F .ShouldEqual(userId); //#F }
public Part1ToPart2Dto BizAction(PlaceOrderInDto dto) { if (!dto.AcceptTAndCs) { AddError("You must accept the T&Cs to place an order."); } if (!dto.LineItems.Any()) { AddError("No items in your basket."); } var order = new Order { CustomerName = dto.UserId }; if (!HasErrors) { _dbAccess.Add(order); } return(new Part1ToPart2Dto(dto.LineItems.ToImmutableList(), order)); }
public void TestAddOrderNoAcceptBad() { //SETUP var options = SqliteInMemory.CreateOptions <EfCoreContext>(); using (var context = new EfCoreContext(options)) { context.Database.EnsureCreated(); context.SeedDatabaseFourBooks(); var service = new PlaceOrderAction(new PlaceOrderDbAccess(context)); var dto = new PlaceOrderInDto { AcceptTAndCs = false, }; //ATTEMPT var order = service.BizAction(dto); //VERIFY service.HasErrors.ShouldBeTrue(); service.Errors.Single().ErrorResult.ErrorMessage.ShouldEqual("You must accept the T&Cs to place an order."); } }