Change SPA app to call basket for order checkout

This commit is contained in:
Ramón Tomás 2017-05-16 09:23:35 +02:00
parent e104da9f85
commit b2b01bae06
20 changed files with 347 additions and 151 deletions

View File

@ -52,10 +52,13 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
}
[Route("checkout")]
[HttpPut]
public async Task<IActionResult> Checkout([FromBody]BasketCheckout value)
[HttpPost]
public async Task<IActionResult> Checkout([FromBody]BasketCheckout value, [FromHeader(Name = "x-requestid")] string requestId)
{
var userId = _identitySvc.GetUserIdentity();
value.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ?
guid : value.RequestId;
var basket = await _repository.GetBasketAsync(userId);
var eventMessage = new UserCheckoutAcceptedIntegrationEvent(userId, value.City, value.Street,
value.State, value.Country, value.ZipCode, value.CardNumber, value.CardHolderName,

View File

@ -3,12 +3,11 @@
using AspNetCore.Http;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using global::Ordering.API.Application.IntegrationCommands.Commands;
using global::Ordering.API.Application.IntegrationEvents;
using global::Ordering.API.Application.IntegrationEvents.Events;
using global::Ordering.API.Infrastructure.Middlewares;
using global::Ordering.API.Application.IntegrationCommands.Commands;
using global::Ordering.API.Application.IntegrationEvents.Events;
using global::Ordering.API.Application.Sagas;
using global::Ordering.API.Infrastructure.Middlewares;
using Infrastructure;
using Infrastructure.Auth;
using Infrastructure.AutofacModules;
@ -31,7 +30,6 @@
using System;
using System.Data.Common;
using System.Reflection;
using global::Ordering.API.Application.IntegrationEvents.EventHandling;
public class Startup
{

View File

@ -60,7 +60,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
var token = await GetUserTokenAsync();
var updateBasketUri = API.Basket.CheckoutBasket(_remoteServiceBaseUrl);
var response = await _apiClient.PutAsync(updateBasketUri, basket, token);
var response = await _apiClient.PostAsync(updateBasketUri, basket, token);
response.EnsureSuccessStatusCode();
}

View File

@ -4,7 +4,9 @@ import { Router } from '@angular/router';
import { DataService } from '../shared/services/data.service';
import { SecurityService } from '../shared/services/security.service';
import { IBasket } from '../shared/models/basket.model';
import { IBasket } from '../shared/models/basket.model';
import { IOrder } from '../shared/models/order.model';
import { IBasketCheckout } from '../shared/models/basketCheckout.model';
import { IBasketItem } from '../shared/models/basketItem.model';
import { BasketWrapperService } from '../shared/services/basket.wrapper.service';
import { ConfigurationService } from '../shared/services/configuration.service';
@ -67,6 +69,12 @@ export class BasketService {
});
}
setBasketCheckout(basketCheckout): Observable<boolean> {
return this.service.postWithId(this.basketUrl + '/checkout', basketCheckout).map((response: Response) => {
return true;
});
}
getBasket(): Observable<IBasket> {
return this.service.get(this.basketUrl + '/' + this.basket.buyerId).map((response: Response) => {
if (response.status === 204) {
@ -83,6 +91,25 @@ export class BasketService {
this.basketDropedSource.next();
}
mapBasketInfoCheckout(order: IOrder): IBasketCheckout {
let basketCheckout = <IBasketCheckout>{};
basketCheckout.street = order.street
basketCheckout.city = order.city;
basketCheckout.country = order.country;
basketCheckout.state = order.state;
basketCheckout.zipcode = order.zipcode;
basketCheckout.cardexpiration = order.cardexpiration;
basketCheckout.cardnumber = order.cardnumber;
basketCheckout.cardsecuritynumber = order.cardsecuritynumber;
basketCheckout.cardtypeid = order.cardtypeid;
basketCheckout.cardholdername = order.cardholdername;
basketCheckout.total = 0;
basketCheckout.expiration = order.expiration;
return basketCheckout;
}
private loadData() {
this.getBasket().subscribe(basket => {
if (basket != null)

View File

@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { OrdersService } from '../orders.service';
import { OrdersService } from '../orders.service';
import { BasketService } from '../../basket/basket.service';
import { IOrder } from '../../shared/models/order.model';
import { BasketWrapperService } from '../../shared/services/basket.wrapper.service';
@ -18,9 +19,9 @@ export class OrdersNewComponent implements OnInit {
errorReceived: boolean;
order: IOrder;
constructor(private service: OrdersService, fb: FormBuilder, private router: Router) {
constructor(private orderService: OrdersService, private basketService: BasketService, fb: FormBuilder, private router: Router) {
// Obtain user profile information
this.order = service.mapBasketAndIdentityInfoNewOrder();
this.order = orderService.mapOrderAndIdentityInfoNewOrder();
this.newOrderForm = fb.group({
'street': [this.order.street, Validators.required],
'city': [this.order.city, Validators.required],
@ -36,7 +37,7 @@ export class OrdersNewComponent implements OnInit {
ngOnInit() {
}
submitForm(value: any) {
submitForm(value: any) {
this.order.street = this.newOrderForm.controls['street'].value;
this.order.city = this.newOrderForm.controls['city'].value;
this.order.state = this.newOrderForm.controls['state'].value;
@ -46,8 +47,8 @@ export class OrdersNewComponent implements OnInit {
this.order.cardholdername = this.newOrderForm.controls['cardholdername'].value;
this.order.cardexpiration = new Date(20 + this.newOrderForm.controls['expirationdate'].value.split('/')[1], this.newOrderForm.controls['expirationdate'].value.split('/')[0]);
this.order.cardsecuritynumber = this.newOrderForm.controls['securitycode'].value;
this.service.postOrder(this.order)
let basketCheckout = this.basketService.mapBasketInfoCheckout(this.order);
this.basketService.setBasketCheckout(basketCheckout)
.catch((errMessage) => {
this.errorReceived = true;
this.isOrderProcessing = false;

View File

@ -5,12 +5,13 @@ import { SharedModule } from '../shared/shared.module';
import { OrdersComponent } from './orders.component';
import { OrdersDetailComponent } from './orders-detail/orders-detail.component';
import { OrdersNewComponent } from './orders-new/orders-new.component';
import { OrdersService } from './orders.service';
import { OrdersService } from './orders.service';
import { BasketService } from '../basket/basket.service';
import { Header } from '../shared/components/header/header';
@NgModule({
imports: [BrowserModule, SharedModule],
declarations: [OrdersComponent, OrdersDetailComponent, OrdersNewComponent],
providers: [OrdersService]
providers: [OrdersService, BasketService]
})
export class OrdersModule { }

View File

@ -44,13 +44,7 @@ export class OrdersService {
});
}
postOrder(item): Observable<boolean> {
return this.service.postWithId(this.ordersUrl + '/api/v1/orders/new', item).map((response: Response) => {
return true;
});
}
mapBasketAndIdentityInfoNewOrder(): IOrder {
mapOrderAndIdentityInfoNewOrder(): IOrder {
let order = <IOrder>{};
let basket = this.basketService.basket;
let identityInfo = this.identityService.UserData;

View File

@ -0,0 +1,16 @@
export interface IBasketCheckout {
city: number;
street: string;
state: string;
country: number;
zipcode: string;
cardnumber: string;
cardexpiration: Date;
expiration: string;
cardsecuritynumber: string;
cardholdername: string;
cardtypeid: number;
buyer: string;
ordernumber: string;
total: number;
}

View File

@ -39,6 +39,10 @@ export class DataService {
return this.doPost(url, data, false, params);
}
putWithId(url: string, data: any, params?: any): Observable<Response> {
return this.doPut(url, data, true, params);
}
private doPost(url: string, data: any, needId: boolean, params?: any): Observable<Response> {
let options: RequestOptionsArgs = {};
@ -57,6 +61,24 @@ export class DataService {
}).catch(this.handleError);
}
private doPut(url: string, data: any, needId: boolean, params?: any): Observable<Response> {
let options: RequestOptionsArgs = {};
options.headers = new Headers();
if (this.securityService) {
options.headers.append('Authorization', 'Bearer ' + this.securityService.GetToken());
}
if (needId) {
let guid = Guid.newGuid();
options.headers.append('x-requestid', guid);
}
return this.http.put(url, data, options).map(
(res: Response) => {
return res;
}).catch(this.handleError);
}
delete(url: string, params?: any) {
let options: RequestOptionsArgs = {};

View File

@ -72,12 +72,12 @@
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0-msbuild3-final" />
</ItemGroup>
<!-- workaround for https://github.com/aspnet/websdk/issues/114 -->
<!-- workaround for https://github.com/aspnet/websdk/issues/114 --><!--
<Target Name="AddGeneratedContentItems" BeforeTargets="AssignTargetPaths" DependsOnTargets="PrepareForPublish">
<ItemGroup>
<Content Include="wwwroot/**" CopyToPublishDirectory="PreserveNewest" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);@(Content)" />
</ItemGroup>
</Target>
</Target>-->
<ItemGroup>
<ProjectReference Include="..\..\BuildingBlocks\HealthChecks\src\Microsoft.AspNetCore.HealthChecks\Microsoft.AspNetCore.HealthChecks.csproj" />

View File

@ -1,10 +1,7 @@
using Microsoft.eShopOnContainers.Services.Basket.API;
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Hosting;
using FunctionalTests.Middleware;
using Microsoft.AspNetCore.Builder;
using FunctionalTests.Middleware;
using Microsoft.AspNetCore.Hosting;
using Microsoft.eShopOnContainers.Services.Basket.API;
namespace FunctionalTests.Services.Basket
{

View File

@ -18,6 +18,9 @@
<ItemGroup>
<!--<Content Include="settings.json;web.config">-->
<Content Include="Services\Basket\appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Services\Catalog\settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -30,6 +33,7 @@
<ProjectReference Include="..\..\..\src\Services\Basket\Basket.API\Basket.API.csproj" />
<ProjectReference Include="..\..\..\src\Services\Catalog\Catalog.API\Catalog.API.csproj" />
<ProjectReference Include="..\..\..\src\Services\Ordering\Ordering.API\Ordering.API.csproj" />
<ProjectReference Include="..\..\..\src\Web\WebMVC\WebMVC.csproj" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,36 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.eShopOnContainers.Services.Basket.API;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace IntegrationTests.Services.Basket
{
public class BasketScenarioBase
{
public TestServer CreateServer()
{
var webHostBuilder = new WebHostBuilder();
webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory() + "\\Services\\basket");
webHostBuilder.UseStartup<BasketTestsStartup>();
return new TestServer(webHostBuilder);
}
public static class Get
{
public static string GetBasket(int id)
{
return $"api/v1/basket/{id}";
}
}
public static class Post
{
public static string Basket = "api/v1/basket";
public static string CheckoutOrder = "api/v1/basket/checkout";
}
}
}

View File

@ -0,0 +1,80 @@
using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using WebMVC.Models;
using Xunit;
namespace IntegrationTests.Services.Basket
{
public class BasketScenarios
: BasketScenarioBase
{
[Fact]
public async Task Post_basket_and_response_ok_status_code()
{
using (var server = CreateServer())
{
var content = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json");
var response = await server.CreateClient()
.PostAsync(Post.Basket, content);
response.EnsureSuccessStatusCode();
}
}
[Fact]
public async Task Get_basket_and_response_ok_status_code()
{
using (var server = CreateServer())
{
var response = await server.CreateClient()
.GetAsync(Get.GetBasket(1));
response.EnsureSuccessStatusCode();
}
}
[Fact]
public async Task Send_Checkout_basket_and_response_ok_status_code()
{
using (var server = CreateServer())
{
var content = new StringContent(BuildCheckout(), UTF8Encoding.UTF8, "application/json");
var response = await server.CreateClient()
.PostAsync(Post.CheckoutOrder, content);
response.EnsureSuccessStatusCode();
}
}
string BuildBasket()
{
var order = new CustomerBasket("1");
return JsonConvert.SerializeObject(order);
}
string BuildCheckout()
{
var checkoutBasket = new BasketDTO()
{
City = "city",
Street = "street",
State = "state",
Country = "coutry",
ZipCode = "zipcode",
CardNumber = "CardNumber",
CardHolderName = "CardHolderName",
CardExpiration = DateTime.UtcNow,
CardSecurityNumber = "1234",
CardTypeId = 1,
Buyer = "Buyer",
RequestId = Guid.NewGuid()
};
return JsonConvert.SerializeObject(checkoutBasket);
}
}
}

View File

@ -0,0 +1,26 @@
using IntegrationTests.Middleware;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.eShopOnContainers.Services.Basket.API;
namespace IntegrationTests.Services.Basket
{
public class BasketTestsStartup : Startup
{
public BasketTestsStartup(IHostingEnvironment env) : base(env)
{
}
protected override void ConfigureAuth(IApplicationBuilder app)
{
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
{
app.UseMiddleware<AutoAuthorizeMiddleware>();
}
else
{
base.ConfigureAuth(app);
}
}
}
}

View File

@ -0,0 +1,8 @@
{
"ConnectionString": "127.0.0.1",
"IdentityUrl": "http://localhost:5105",
"isTest": "true",
"EventBusConnection": "localhost"
}

View File

@ -26,9 +26,10 @@
}
}
public static class Post
public static class Put
{
public static string AddNewOrder = "api/v1/orders/new";
public static string CancelOrder = "api/v1/orders/cancel";
public static string ShipOrder = "api/v1/orders/ship";
}
}
}

View File

@ -1,112 +1,61 @@
namespace IntegrationTests.Services.Ordering
{
using IntegrationTests.Services.Extensions;
using Microsoft.AspNetCore.TestHost;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using WebMVC.Models;
using Xunit;
using System.Collections;
using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand;
using System.Collections.Generic;
public class OrderingScenarios
: OrderingScenarioBase
{
// [Fact]
// public async Task Get_get_all_stored_orders_and_response_ok_status_code()
// {
// using (var server = CreateServer())
// {
// var response = await server.CreateClient()
// .GetAsync(Get.Orders);
[Fact]
public async Task Get_get_all_stored_orders_and_response_ok_status_code()
{
using (var server = CreateServer())
{
var response = await server.CreateClient()
.GetAsync(Get.Orders);
// response.EnsureSuccessStatusCode();
// }
// }
response.EnsureSuccessStatusCode();
}
}
// [Fact]
// public async Task AddNewOrder_add_new_order_and_response_ok_status_code()
// {
// using (var server = CreateServer())
// {
// var content = new StringContent(BuildOrder(), UTF8Encoding.UTF8, "application/json");
// var response = await server.CreateIdempotentClient()
// .PostAsync(Post.AddNewOrder, content);
[Fact]
public async Task Cancel_order_and_response_ok_status_code()
{
using (var server = CreateServer())
{
var content = new StringContent(BuildOrder(), UTF8Encoding.UTF8, "application/json");
var response = await server.CreateIdempotentClient()
.PutAsync(Put.CancelOrder, content);
// response.EnsureSuccessStatusCode();
// }
// }
response.EnsureSuccessStatusCode();
}
}
// [Fact]
// public async Task AddNewOrder_response_bad_request_if_card_expiration_is_invalid()
// {
// using (var server = CreateServer())
// {
// var content = new StringContent(BuildOrderWithInvalidExperationTime(), UTF8Encoding.UTF8, "application/json");
[Fact]
public async Task Ship_order_and_response_bad_status_code()
{
using (var server = CreateServer())
{
var content = new StringContent(BuildOrder(), UTF8Encoding.UTF8, "application/json");
var response = await server.CreateIdempotentClient()
.PutAsync(Put.ShipOrder, content);
// var response = await server.CreateIdempotentClient()
// .PostAsync(Post.AddNewOrder, content);
response.EnsureSuccessStatusCode();
}
}
// Assert.True(response.StatusCode == System.Net.HttpStatusCode.BadRequest);
// }
// }
// //public CreateOrderCommand(string city, string street, string state, string country, string zipcode,
// // string cardNumber, string cardHolderName, DateTime cardExpiration,
// // string cardSecurityNumber, int cardTypeId, int paymentId, int buyerId) : this()
// string BuildOrder()
// {
// List<OrderItemDTO> orderItemsList = new List<OrderItemDTO>();
// orderItemsList.Add(new OrderItemDTO()
// {
// ProductId = 1,
// Discount = 10M,
// UnitPrice = 10,
// Units = 1,
// ProductName = "Some name"
// }
// );
// var order = new CreateOrderCommand(
// orderItemsList,
// 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);
// }
// string BuildOrderWithInvalidExperationTime()
// {
// var order = new CreateOrderCommand(
// null,
// 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",
// buyerId: 1,
// paymentId:1
// );
// return JsonConvert.SerializeObject(order);
// }
string BuildOrder()
{
var order = new OrderDTO()
{
OrderNumber = "1"
};
return JsonConvert.SerializeObject(order);
}
}
}

View File

@ -5,6 +5,7 @@ using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Basket.API.Controllers;
using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Moq;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit;
@ -80,7 +81,7 @@ namespace UnitTest.Basket.Application
var basketController = new BasketController(
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
var result = await basketController.Checkout(new BasketCheckout()) as BadRequestResult;
var result = await basketController.Checkout(new BasketCheckout(), Guid.NewGuid().ToString()) as BadRequestResult;
Assert.NotNull(result);
}
@ -96,7 +97,7 @@ namespace UnitTest.Basket.Application
var basketController = new BasketController(
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object);
var result = await basketController.Checkout(new BasketCheckout()) as AcceptedResult;
var result = await basketController.Checkout(new BasketCheckout(), Guid.NewGuid().ToString()) as AcceptedResult;
_serviceBusMock.Verify(mock => mock.Publish(It.IsAny<UserCheckoutAcceptedIntegrationEvent>()), Times.Once);
Assert.NotNull(result);
}

View File

@ -5,6 +5,7 @@ using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries;
using Microsoft.eShopOnContainers.Services.Ordering.API.Controllers;
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services;
using Moq;
using Ordering.API.Application.Commands;
using System;
using System.Linq;
using System.Threading.Tasks;
@ -25,36 +26,67 @@ namespace UnitTest.Ordering.Application
_identityServiceMock = new Mock<IIdentityService>();
}
//[Fact]
//public async Task Create_order_with_requestId_success()
//{
// //Arrange
// _mediatorMock.Setup(x => x.SendAsync(It.IsAny<IdentifiedCommand<CreateOrderCommand, bool>>()))
// .Returns(Task.FromResult(true));
[Fact]
public async Task Create_order_with_requestId_success()
{
//Arrange
_mediatorMock.Setup(x => x.SendAsync(It.IsAny<IdentifiedCommand<CancelOrderCommand, bool>>()))
.Returns(Task.FromResult(true));
// //Act
// var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
// var actionResult = await orderController.CreateOrder(new CreateOrderCommand(), Guid.NewGuid().ToString()) as OkResult;
//Act
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
var actionResult = await orderController.CancelOrder(new CancelOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
// //Assert
// Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
//Assert
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
//}
}
//[Fact]
//public async Task Create_order_bad_request()
//{
// //Arrange
// _mediatorMock.Setup(x => x.SendAsync(It.IsAny<IdentifiedCommand<CreateOrderCommand, bool>>()))
// .Returns(Task.FromResult(true));
[Fact]
public async Task Cancel_order_bad_request()
{
//Arrange
_mediatorMock.Setup(x => x.SendAsync(It.IsAny<IdentifiedCommand<CancelOrderCommand, bool>>()))
.Returns(Task.FromResult(true));
// //Act
// var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
// var actionResult = await orderController.CreateOrder(new CreateOrderCommand(), String.Empty) as BadRequestResult;
//Act
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
var actionResult = await orderController.CancelOrder(new CancelOrderCommand(1), String.Empty) as BadRequestResult;
// //Assert
// Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest);
//}
//Assert
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest);
}
[Fact]
public async Task Ship_order_with_requestId_success()
{
//Arrange
_mediatorMock.Setup(x => x.SendAsync(It.IsAny<IdentifiedCommand<ShipOrderCommand, bool>>()))
.Returns(Task.FromResult(true));
//Act
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
var actionResult = await orderController.ShipOrder(new ShipOrderCommand(1), Guid.NewGuid().ToString()) as OkResult;
//Assert
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK);
}
[Fact]
public async Task Ship_order_bad_request()
{
//Arrange
_mediatorMock.Setup(x => x.SendAsync(It.IsAny<IdentifiedCommand<ShipOrderCommand, bool>>()))
.Returns(Task.FromResult(true));
//Act
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object);
var actionResult = await orderController.ShipOrder(new ShipOrderCommand(1), String.Empty) as BadRequestResult;
//Assert
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest);
}
[Fact]
public async Task Get_orders_success()