@ -0,0 +1,26 @@ | |||
using Microsoft.AspNetCore.Http; | |||
using System.Security.Claims; | |||
using System.Threading.Tasks; | |||
namespace Basket.FunctionalTests.Base | |||
{ | |||
class AutoAuthorizeMiddleware | |||
{ | |||
private readonly RequestDelegate _next; | |||
public AutoAuthorizeMiddleware(RequestDelegate rd) | |||
{ | |||
_next = rd; | |||
} | |||
public async Task Invoke(HttpContext httpContext) | |||
{ | |||
var identity = new ClaimsIdentity("cookies"); | |||
identity.AddClaim(new Claim("sub", "9e3163b9-1ae6-4652-9dc6-7898ab7b7a00")); | |||
httpContext.User.AddIdentity(identity); | |||
await _next.Invoke(httpContext); | |||
} | |||
} | |||
} |
@ -0,0 +1,38 @@ | |||
using Microsoft.AspNetCore; | |||
using Microsoft.AspNetCore.Hosting; | |||
using Microsoft.AspNetCore.TestHost; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Text; | |||
namespace Basket.FunctionalTests.Base | |||
{ | |||
public class BasketScenarioBase | |||
{ | |||
private const string ApiUrlBase = "api/v1/basket"; | |||
public TestServer CreateServer() | |||
{ | |||
var webHostBuilder = WebHost.CreateDefaultBuilder(); | |||
webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory() + "\\Services\\basket"); | |||
webHostBuilder.UseStartup<BasketTestsStartup>(); | |||
return new TestServer(webHostBuilder); | |||
} | |||
public static class Get | |||
{ | |||
public static string GetBasket(int id) | |||
{ | |||
return $"{ApiUrlBase}/{id}"; | |||
} | |||
} | |||
public static class Post | |||
{ | |||
public static string Basket = $"{ApiUrlBase}/"; | |||
public static string CheckoutOrder = $"{ApiUrlBase}/checkout"; | |||
} | |||
} | |||
} |
@ -0,0 +1,25 @@ | |||
using Microsoft.AspNetCore.Builder; | |||
using Microsoft.eShopOnContainers.Services.Basket.API; | |||
using Microsoft.Extensions.Configuration; | |||
namespace Basket.FunctionalTests.Base | |||
{ | |||
class BasketTestsStartup : Startup | |||
{ | |||
public BasketTestsStartup(IConfiguration env) : base(env) | |||
{ | |||
} | |||
protected override void ConfigureAuth(IApplicationBuilder app) | |||
{ | |||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant()) | |||
{ | |||
app.UseMiddleware<AutoAuthorizeMiddleware>(); | |||
} | |||
else | |||
{ | |||
base.ConfigureAuth(app); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,18 @@ | |||
using Microsoft.AspNetCore.TestHost; | |||
using System; | |||
using System.Net.Http; | |||
namespace Basket.FunctionalTests.Base | |||
{ | |||
static class HttpClientExtensions | |||
{ | |||
public static HttpClient CreateIdempotentClient(this TestServer server) | |||
{ | |||
var client = server.CreateClient(); | |||
client.DefaultRequestHeaders.Add("x-requestid", Guid.NewGuid().ToString()); | |||
return client; | |||
} | |||
} | |||
} |
@ -0,0 +1,22 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> | |||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.1.0" /> | |||
<PackageReference Include="xunit" Version="2.3.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | |||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> | |||
<PackageReference Include="Moq" Version="4.8.1" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\src\Web\WebMVC\WebMVC.csproj" /> | |||
<ProjectReference Include="..\..\src\Services\Basket\Basket.API\Basket.API.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,94 @@ | |||
using Basket.FunctionalTests.Base; | |||
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 Basket.FunctionalTests | |||
{ | |||
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 contentBasket = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json"); | |||
await server.CreateClient() | |||
.PostAsync(Post.Basket, contentBasket); | |||
var contentCheckout = new StringContent(BuildCheckout(), UTF8Encoding.UTF8, "application/json"); | |||
var response = await server.CreateIdempotentClient() | |||
.PostAsync(Post.CheckoutOrder, contentCheckout); | |||
response.EnsureSuccessStatusCode(); | |||
} | |||
} | |||
string BuildBasket() | |||
{ | |||
var order = new CustomerBasket("1234"); | |||
order.Items.Add(new BasketItem | |||
{ | |||
ProductId = "1", | |||
ProductName = ".NET Bot Black Hoodie", | |||
UnitPrice = 10, | |||
Quantity = 1 | |||
}); | |||
return JsonConvert.SerializeObject(order); | |||
} | |||
string BuildCheckout() | |||
{ | |||
var checkoutBasket = new BasketDTO() | |||
{ | |||
City = "city", | |||
Street = "street", | |||
State = "state", | |||
Country = "coutry", | |||
ZipCode = "zipcode", | |||
CardNumber = "1234567890123456", | |||
CardHolderName = "CardHolderName", | |||
CardExpiration = DateTime.UtcNow.AddDays(1), | |||
CardSecurityNumber = "123", | |||
CardTypeId = 1, | |||
Buyer = "Buyer", | |||
RequestId = Guid.NewGuid() | |||
}; | |||
return JsonConvert.SerializeObject(checkoutBasket); | |||
} | |||
} | |||
} |
@ -0,0 +1,78 @@ | |||
using Microsoft.eShopOnContainers.Services.Basket.API; | |||
using Microsoft.Extensions.Options; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using Xunit; | |||
namespace Basket.FunctionalTests | |||
{ | |||
//public class RedisBasketRepositoryTests | |||
//{ | |||
// private Mock<IOptionsSnapshot<BasketSettings>> _optionsMock; | |||
// public RedisBasketRepositoryTests() | |||
// { | |||
// _optionsMock = new Mock<IOptionsSnapshot<BasketSettings>>(); | |||
// } | |||
// [Fact] | |||
// public async Task UpdateBasket_return_and_add_basket() | |||
// { | |||
// var redisBasketRepository = BuildBasketRepository(); | |||
// var basket = await redisBasketRepository.UpdateBasketAsync(new CustomerBasket("customerId") | |||
// { | |||
// BuyerId = "buyerId", | |||
// Items = BuildBasketItems() | |||
// }); | |||
// Assert.NotNull(basket); | |||
// Assert.Single(basket.Items); | |||
// } | |||
// [Fact] | |||
// public async Task Delete_Basket_return_null() | |||
// { | |||
// var redisBasketRepository = BuildBasketRepository(); | |||
// var basket = await redisBasketRepository.UpdateBasketAsync(new CustomerBasket("customerId") | |||
// { | |||
// BuyerId = "buyerId", | |||
// Items = BuildBasketItems() | |||
// }); | |||
// var deleteResult = await redisBasketRepository.DeleteBasketAsync("buyerId"); | |||
// var result = await redisBasketRepository.GetBasketAsync(basket.BuyerId); | |||
// Assert.True(deleteResult); | |||
// Assert.Null(result); | |||
// } | |||
// RedisBasketRepository BuildBasketRepository() | |||
// { | |||
// var loggerFactory = new LoggerFactory(); | |||
// var configuration = ConfigurationOptions.Parse("127.0.0.1", true); | |||
// configuration.ResolveDns = true; | |||
// return new RedisBasketRepository(loggerFactory, ConnectionMultiplexer.Connect(configuration)); | |||
// } | |||
// List<BasketItem> BuildBasketItems() | |||
// { | |||
// return new List<BasketItem>() | |||
// { | |||
// new BasketItem() | |||
// { | |||
// Id = "basketId", | |||
// PictureUrl = "pictureurl", | |||
// ProductId = "productId", | |||
// ProductName = "productName", | |||
// Quantity = 1, | |||
// UnitPrice = 1 | |||
// } | |||
// }; | |||
// } | |||
//} | |||
} |
@ -0,0 +1,15 @@ | |||
{ | |||
"Logging": { | |||
"IncludeScopes": false, | |||
"LogLevel": { | |||
"Default": "Debug", | |||
"System": "Information", | |||
"Microsoft": "Information" | |||
} | |||
}, | |||
"IdentityUrl": "http://localhost:5105", | |||
"ConnectionString": "127.0.0.1", | |||
"isTest": "true", | |||
"EventBusConnection": "localhost", | |||
"SubscriptionClientName": "Basket" | |||
} |
@ -0,0 +1,116 @@ | |||
using Basket.API.IntegrationEvents.Events; | |||
using Basket.API.Model; | |||
using Microsoft.AspNetCore.Mvc; | |||
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; | |||
using IBasketIdentityService = Microsoft.eShopOnContainers.Services.Basket.API.Services.IIdentityService; | |||
namespace UnitTest.Basket.Application | |||
{ | |||
public class BasketWebApiTest | |||
{ | |||
private readonly Mock<IBasketRepository> _basketRepositoryMock; | |||
private readonly Mock<IBasketIdentityService> _identityServiceMock; | |||
private readonly Mock<IEventBus> _serviceBusMock; | |||
public BasketWebApiTest() | |||
{ | |||
_basketRepositoryMock = new Mock<IBasketRepository>(); | |||
_identityServiceMock = new Mock<IBasketIdentityService>(); | |||
_serviceBusMock = new Mock<IEventBus>(); | |||
} | |||
[Fact] | |||
public async Task Get_customer_basket_success() | |||
{ | |||
//Arrange | |||
var fakeCustomerId = "1"; | |||
var fakeCustomerBasket = GetCustomerBasketFake(fakeCustomerId); | |||
_basketRepositoryMock.Setup(x => x.GetBasketAsync(It.IsAny<string>())) | |||
.Returns(Task.FromResult(fakeCustomerBasket)); | |||
_identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId); | |||
_serviceBusMock.Setup(x => x.Publish(It.IsAny<UserCheckoutAcceptedIntegrationEvent>())); | |||
//Act | |||
var basketController = new BasketController( | |||
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); | |||
var actionResult = await basketController.Get(fakeCustomerId) as OkObjectResult; | |||
//Assert | |||
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); | |||
Assert.Equal(((CustomerBasket)actionResult.Value).BuyerId, fakeCustomerId); | |||
} | |||
[Fact] | |||
public async Task Post_customer_basket_success() | |||
{ | |||
//Arrange | |||
var fakeCustomerId = "1"; | |||
var fakeCustomerBasket = GetCustomerBasketFake(fakeCustomerId); | |||
_basketRepositoryMock.Setup(x => x.UpdateBasketAsync(It.IsAny<CustomerBasket>())) | |||
.Returns(Task.FromResult(fakeCustomerBasket)); | |||
_identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId); | |||
_serviceBusMock.Setup(x => x.Publish(It.IsAny<UserCheckoutAcceptedIntegrationEvent>())); | |||
//Act | |||
var basketController = new BasketController( | |||
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); | |||
var actionResult = await basketController.Post(fakeCustomerBasket) as OkObjectResult; | |||
//Assert | |||
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); | |||
Assert.Equal(((CustomerBasket)actionResult.Value).BuyerId, fakeCustomerId); | |||
} | |||
[Fact] | |||
public async Task Doing_Checkout_Without_Basket_Should_Return_Bad_Request() | |||
{ | |||
var fakeCustomerId = "2"; | |||
_basketRepositoryMock.Setup(x => x.GetBasketAsync(It.IsAny<string>())) | |||
.Returns(Task.FromResult((CustomerBasket)null)); | |||
_identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId); | |||
//Act | |||
var basketController = new BasketController( | |||
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); | |||
var result = await basketController.Checkout(new BasketCheckout(), Guid.NewGuid().ToString()) as BadRequestResult; | |||
Assert.NotNull(result); | |||
} | |||
[Fact] | |||
public async Task Doing_Checkout_Wit_Basket_Should_Publish_UserCheckoutAccepted_Integration_Event() | |||
{ | |||
var fakeCustomerId = "1"; | |||
var fakeCustomerBasket = GetCustomerBasketFake(fakeCustomerId); | |||
_basketRepositoryMock.Setup(x => x.GetBasketAsync(It.IsAny<string>())) | |||
.Returns(Task.FromResult(fakeCustomerBasket)); | |||
_identityServiceMock.Setup(x => x.GetUserIdentity()).Returns(fakeCustomerId); | |||
//Act | |||
var basketController = new BasketController( | |||
_basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); | |||
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); | |||
} | |||
private CustomerBasket GetCustomerBasketFake(string fakeCustomerId) | |||
{ | |||
return new CustomerBasket(fakeCustomerId) | |||
{ | |||
Items = new List<BasketItem>() | |||
{ | |||
new BasketItem() | |||
} | |||
}; | |||
} | |||
} | |||
} |
@ -0,0 +1,130 @@ | |||
using Microsoft.AspNetCore.Http; | |||
using Microsoft.AspNetCore.Mvc; | |||
using Microsoft.eShopOnContainers.WebMVC.Controllers; | |||
using Microsoft.eShopOnContainers.WebMVC.Services; | |||
using Microsoft.eShopOnContainers.WebMVC.ViewModels; | |||
using Moq; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
using Xunit; | |||
using BasketModel = Microsoft.eShopOnContainers.WebMVC.ViewModels.Basket; | |||
namespace UnitTest.Basket.Application | |||
{ | |||
public class CartControllerTest | |||
{ | |||
private readonly Mock<ICatalogService> _catalogServiceMock; | |||
private readonly Mock<IBasketService> _basketServiceMock; | |||
private readonly Mock<IIdentityParser<ApplicationUser>> _identityParserMock; | |||
private readonly Mock<HttpContext> _contextMock; | |||
public CartControllerTest() | |||
{ | |||
_catalogServiceMock = new Mock<ICatalogService>(); | |||
_basketServiceMock = new Mock<IBasketService>(); | |||
_identityParserMock = new Mock<IIdentityParser<ApplicationUser>>(); | |||
_contextMock = new Mock<HttpContext>(); | |||
} | |||
[Fact] | |||
public async Task Post_cart_success() | |||
{ | |||
//Arrange | |||
var fakeBuyerId = "1"; | |||
var action = string.Empty; | |||
var fakeBasket = GetFakeBasket(fakeBuyerId); | |||
var fakeQuantities = new Dictionary<string, int>() | |||
{ | |||
["fakeProdA"] = 1, | |||
["fakeProdB"] = 2 | |||
}; | |||
_basketServiceMock.Setup(x => x.SetQuantities(It.IsAny<ApplicationUser>(), It.IsAny<Dictionary<string, int>>())) | |||
.Returns(Task.FromResult(fakeBasket)); | |||
_basketServiceMock.Setup(x => x.UpdateBasket(It.IsAny<BasketModel>())) | |||
.Returns(Task.FromResult(fakeBasket)); | |||
//Act | |||
var cartController = new CartController(_basketServiceMock.Object, _catalogServiceMock.Object, _identityParserMock.Object); | |||
cartController.ControllerContext.HttpContext = _contextMock.Object; | |||
var actionResult = await cartController.Index(fakeQuantities, action); | |||
//Assert | |||
var viewResult = Assert.IsType<ViewResult>(actionResult); | |||
} | |||
[Fact] | |||
public async Task Post_cart_checkout_success() | |||
{ | |||
//Arrange | |||
var fakeBuyerId = "1"; | |||
var action = "[ Checkout ]"; | |||
var fakeBasket = GetFakeBasket(fakeBuyerId); | |||
var fakeQuantities = new Dictionary<string, int>() | |||
{ | |||
["fakeProdA"] = 1, | |||
["fakeProdB"] = 2 | |||
}; | |||
_basketServiceMock.Setup(x => x.SetQuantities(It.IsAny<ApplicationUser>(), It.IsAny<Dictionary<string, int>>())) | |||
.Returns(Task.FromResult(fakeBasket)); | |||
_basketServiceMock.Setup(x => x.UpdateBasket(It.IsAny<BasketModel>())) | |||
.Returns(Task.FromResult(fakeBasket)); | |||
//Act | |||
var orderController = new CartController(_basketServiceMock.Object, _catalogServiceMock.Object, _identityParserMock.Object); | |||
orderController.ControllerContext.HttpContext = _contextMock.Object; | |||
var actionResult = await orderController.Index(fakeQuantities, action); | |||
//Assert | |||
var redirectToActionResult = Assert.IsType<RedirectToActionResult>(actionResult); | |||
Assert.Equal("Order", redirectToActionResult.ControllerName); | |||
Assert.Equal("Create", redirectToActionResult.ActionName); | |||
} | |||
[Fact] | |||
public async Task Add_to_cart_success() | |||
{ | |||
//Arrange | |||
var fakeCatalogItem = GetFakeCatalogItem(); | |||
_basketServiceMock.Setup(x => x.AddItemToBasket(It.IsAny<ApplicationUser>(), It.IsAny<Int32>())) | |||
.Returns(Task.FromResult(1)); | |||
//Act | |||
var orderController = new CartController(_basketServiceMock.Object, _catalogServiceMock.Object, _identityParserMock.Object); | |||
orderController.ControllerContext.HttpContext = _contextMock.Object; | |||
var actionResult = await orderController.AddToCart(fakeCatalogItem); | |||
//Assert | |||
var redirectToActionResult = Assert.IsType<RedirectToActionResult>(actionResult); | |||
Assert.Equal("Catalog", redirectToActionResult.ControllerName); | |||
Assert.Equal("Index", redirectToActionResult.ActionName); | |||
} | |||
private BasketModel GetFakeBasket(string buyerId) | |||
{ | |||
return new BasketModel() | |||
{ | |||
BuyerId = buyerId | |||
}; | |||
} | |||
private CatalogItem GetFakeCatalogItem() | |||
{ | |||
return new CatalogItem() | |||
{ | |||
Id = 1, | |||
Name = "fakeName", | |||
CatalogBrand = "fakeBrand", | |||
CatalogType = "fakeType", | |||
CatalogBrandId = 2, | |||
CatalogTypeId = 5, | |||
Price = 20 | |||
}; | |||
} | |||
} | |||
} |
@ -0,0 +1,23 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> | |||
<PackageReference Include="xunit" Version="2.3.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | |||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> | |||
<PackageReference Include="MediatR" Version="4.1.0" /> | |||
<PackageReference Include="Moq" Version="4.8.1" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\src\Services\Basket\Basket.API\Basket.API.csproj" /> | |||
<ProjectReference Include="..\..\src\Web\WebMVC\WebMVC.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,90 @@ | |||
using Microsoft.AspNetCore.Mvc; | |||
using Microsoft.eShopOnContainers.WebMVC.Controllers; | |||
using Microsoft.eShopOnContainers.WebMVC.Services; | |||
using Microsoft.eShopOnContainers.WebMVC.ViewModels; | |||
using Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels; | |||
using Moq; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
using Xunit; | |||
using CatalogModel = Microsoft.eShopOnContainers.WebMVC.ViewModels.Catalog; | |||
namespace UnitTest.Catalog.Application | |||
{ | |||
public class CatalogControllerTest | |||
{ | |||
private readonly Mock<ICatalogService> _catalogServiceMock; | |||
public CatalogControllerTest() | |||
{ | |||
_catalogServiceMock = new Mock<ICatalogService>(); | |||
} | |||
[Fact] | |||
public async Task Get_catalog_items_success() | |||
{ | |||
//Arrange | |||
var fakeBrandFilterApplied = 1; | |||
var fakeTypesFilterApplied = 2; | |||
var fakePage = 2; | |||
var fakeCatalog = GetFakeCatalog(); | |||
var expectedNumberOfPages = 5; | |||
var expectedTotalPages = 50; | |||
var expectedCurrentPage = 2; | |||
_catalogServiceMock.Setup(x => x.GetCatalogItems | |||
( | |||
It.Is<int>(y => y == fakePage), | |||
It.IsAny<int>(), | |||
It.Is<int?>(y => y == fakeBrandFilterApplied), | |||
It.Is<int?>(y => y == fakeTypesFilterApplied) | |||
)) | |||
.Returns(Task.FromResult(fakeCatalog)); | |||
//Act | |||
var orderController = new CatalogController(_catalogServiceMock.Object); | |||
var actionResult = await orderController.Index(fakeBrandFilterApplied, fakeTypesFilterApplied, fakePage, null); | |||
//Assert | |||
var viewResult = Assert.IsType<ViewResult>(actionResult); | |||
var model = Assert.IsAssignableFrom<IndexViewModel>(viewResult.ViewData.Model); | |||
Assert.Equal(model.PaginationInfo.TotalPages, expectedNumberOfPages); | |||
Assert.Equal(model.PaginationInfo.TotalItems, expectedTotalPages); | |||
Assert.Equal(model.PaginationInfo.ActualPage, expectedCurrentPage); | |||
Assert.Empty(model.PaginationInfo.Next); | |||
Assert.Empty(model.PaginationInfo.Previous); | |||
} | |||
private CatalogModel GetFakeCatalog() | |||
{ | |||
return new CatalogModel() | |||
{ | |||
PageSize = 10, | |||
Count = 50, | |||
PageIndex = 2, | |||
Data = new List<CatalogItem>() | |||
{ | |||
new CatalogItem() | |||
{ | |||
Id = 1, | |||
Name = "fakeItemA", | |||
CatalogTypeId = 1 | |||
}, | |||
new CatalogItem() | |||
{ | |||
Id = 2, | |||
Name = "fakeItemB", | |||
CatalogTypeId = 1 | |||
}, | |||
new CatalogItem() | |||
{ | |||
Id = 3, | |||
Name = "fakeItemC", | |||
CatalogTypeId = 1 | |||
} | |||
} | |||
}; | |||
} | |||
} | |||
} |
@ -0,0 +1,22 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> | |||
<PackageReference Include="xunit" Version="2.3.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | |||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> | |||
<PackageReference Include="Moq" Version="4.8.1" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\src\Services\Catalog\Catalog.API\Catalog.API.csproj" /> | |||
<ProjectReference Include="..\..\src\Web\WebMVC\WebMVC.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,26 @@ | |||
using Microsoft.AspNetCore.Http; | |||
using System.Security.Claims; | |||
using System.Threading.Tasks; | |||
namespace Marketing.FunctionalTests.Base | |||
{ | |||
class AutoAuthorizeMiddleware | |||
{ | |||
private readonly RequestDelegate _next; | |||
public AutoAuthorizeMiddleware(RequestDelegate rd) | |||
{ | |||
_next = rd; | |||
} | |||
public async Task Invoke(HttpContext httpContext) | |||
{ | |||
var identity = new ClaimsIdentity("cookies"); | |||
identity.AddClaim(new Claim("sub", "9e3163b9-1ae6-4652-9dc6-7898ab7b7a00")); | |||
httpContext.User.AddIdentity(identity); | |||
await _next.Invoke(httpContext); | |||
} | |||
} | |||
} |
@ -0,0 +1,37 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace Marketing.FunctionalTests.Base | |||
{ | |||
public class CampaignScenariosBase : MarketingScenariosBase | |||
{ | |||
public static class Get | |||
{ | |||
public static string Campaigns = CampaignsUrlBase; | |||
public static string CampaignBy(int id) | |||
=> $"{CampaignsUrlBase}/{id}"; | |||
public static string UserCampaignsByUserId() | |||
=> $"{CampaignsUrlBase}/user"; | |||
} | |||
public static class Post | |||
{ | |||
public static string AddNewCampaign = CampaignsUrlBase; | |||
} | |||
public static class Put | |||
{ | |||
public static string CampaignBy(int id) | |||
=> $"{CampaignsUrlBase}/{id}"; | |||
} | |||
public static class Delete | |||
{ | |||
public static string CampaignBy(int id) | |||
=> $"{CampaignsUrlBase}/{id}"; | |||
} | |||
} | |||
} |
@ -0,0 +1,37 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace Marketing.FunctionalTests.Base | |||
{ | |||
public class CampaignScenariosBase : MarketingScenariosBase | |||
{ | |||
public static class Get | |||
{ | |||
public static string Campaigns = CampaignsUrlBase; | |||
public static string CampaignBy(int id) | |||
=> $"{CampaignsUrlBase}/{id}"; | |||
public static string UserCampaignsByUserId() | |||
=> $"{CampaignsUrlBase}/user"; | |||
} | |||
public static class Post | |||
{ | |||
public static string AddNewCampaign = CampaignsUrlBase; | |||
} | |||
public static class Put | |||
{ | |||
public static string CampaignBy(int id) | |||
=> $"{CampaignsUrlBase}/{id}"; | |||
} | |||
public static class Delete | |||
{ | |||
public static string CampaignBy(int id) | |||
=> $"{CampaignsUrlBase}/{id}"; | |||
} | |||
} | |||
} |
@ -0,0 +1,40 @@ | |||
using Microsoft.AspNetCore; | |||
using Microsoft.AspNetCore.Hosting; | |||
using Microsoft.AspNetCore.TestHost; | |||
using System; | |||
using System.IO; | |||
namespace Marketing.FunctionalTests.Base | |||
{ | |||
public class LocationsScenariosBase | |||
{ | |||
public TestServer CreateServer() | |||
{ | |||
var webHostBuilder = WebHost.CreateDefaultBuilder(); | |||
webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory() + "\\Services\\Location"); | |||
webHostBuilder.UseStartup<LocationsTestsStartup>(); | |||
return new TestServer(webHostBuilder); | |||
} | |||
public static class Get | |||
{ | |||
public static string Locations = "api/v1/locations"; | |||
public static string LocationBy(string id) | |||
{ | |||
return $"api/v1/locations/{id}"; | |||
} | |||
public static string UserLocationBy(Guid id) | |||
{ | |||
return $"api/v1/locations/user/{id}"; | |||
} | |||
} | |||
public static class Post | |||
{ | |||
public static string AddNewLocation = "api/v1/locations/"; | |||
} | |||
} | |||
} |
@ -0,0 +1,44 @@ | |||
using Microsoft.AspNetCore.Builder; | |||
using Microsoft.eShopOnContainers.Services.Marketing.API; | |||
using Microsoft.Extensions.Configuration; | |||
namespace Marketing.FunctionalTests.Base | |||
{ | |||
public class LocationsTestsStartup : Startup | |||
{ | |||
public LocationsTestsStartup(IConfiguration configuration) : base(configuration) | |||
{ | |||
} | |||
protected override void ConfigureAuth(IApplicationBuilder app) | |||
{ | |||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant()) | |||
{ | |||
app.UseMiddleware<AutoAuthorizeMiddleware>(); | |||
} | |||
else | |||
{ | |||
base.ConfigureAuth(app); | |||
} | |||
} | |||
//class LocationAuthorizeMiddleware | |||
//{ | |||
// private readonly RequestDelegate _next; | |||
// public LocationAuthorizeMiddleware(RequestDelegate rd) | |||
// { | |||
// _next = rd; | |||
// } | |||
// public async Task Invoke(HttpContext httpContext) | |||
// { | |||
// var identity = new ClaimsIdentity("cookies"); | |||
// identity.AddClaim(new Claim("sub", "4611ce3f-380d-4db5-8d76-87a8689058ed")); | |||
// httpContext.User.AddIdentity(identity); | |||
// await _next.Invoke(httpContext); | |||
// } | |||
//} | |||
} | |||
} |
@ -0,0 +1,36 @@ | |||
using Microsoft.AspNetCore; | |||
using Microsoft.AspNetCore.Hosting; | |||
using Microsoft.AspNetCore.TestHost; | |||
using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Logging; | |||
using System.IO; | |||
namespace Marketing.FunctionalTests.Base | |||
{ | |||
public class MarketingScenariosBase | |||
{ | |||
public static string CampaignsUrlBase => "api/v1/campaigns"; | |||
public TestServer CreateServer() | |||
{ | |||
var webHostBuilder = WebHost.CreateDefaultBuilder(); | |||
webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory() + "\\Services\\Marketing"); | |||
webHostBuilder.UseStartup<MarketingTestsStartup>(); | |||
var testServer = new TestServer(webHostBuilder); | |||
testServer.Host | |||
.MigrateDbContext<MarketingContext>((context, services) => | |||
{ | |||
var logger = services.GetService<ILogger<MarketingContextSeed>>(); | |||
new MarketingContextSeed() | |||
.SeedAsync(context, logger) | |||
.Wait(); | |||
}); | |||
return testServer; | |||
} | |||
} | |||
} |
@ -0,0 +1,28 @@ | |||
using Microsoft.AspNetCore.Builder; | |||
using Microsoft.eShopOnContainers.Services.Marketing.API; | |||
using Microsoft.Extensions.Configuration; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace Marketing.FunctionalTests.Base | |||
{ | |||
public class MarketingTestsStartup : Startup | |||
{ | |||
public MarketingTestsStartup(IConfiguration configuration) : base(configuration) | |||
{ | |||
} | |||
protected override void ConfigureAuth(IApplicationBuilder app) | |||
{ | |||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant()) | |||
{ | |||
app.UseMiddleware<AutoAuthorizeMiddleware>(); | |||
} | |||
else | |||
{ | |||
base.ConfigureAuth(app); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,45 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace Marketing.FunctionalTests.Base | |||
{ | |||
public class UserLocationRoleScenariosBase : MarketingScenariosBase | |||
{ | |||
private const string EndpointLocationName = "locations"; | |||
public static class Get | |||
{ | |||
public static string UserLocationRulesByCampaignId(int campaignId) | |||
=> GetUserLocationRolesUrlBase(campaignId); | |||
public static string UserLocationRuleByCampaignAndUserLocationRuleId(int campaignId, | |||
int userLocationRuleId) | |||
=> $"{GetUserLocationRolesUrlBase(campaignId)}/{userLocationRuleId}"; | |||
} | |||
public static class Post | |||
{ | |||
public static string AddNewuserLocationRule(int campaignId) | |||
=> GetUserLocationRolesUrlBase(campaignId); | |||
} | |||
public static class Put | |||
{ | |||
public static string UserLocationRoleBy(int campaignId, | |||
int userLocationRuleId) | |||
=> $"{GetUserLocationRolesUrlBase(campaignId)}/{userLocationRuleId}"; | |||
} | |||
public static class Delete | |||
{ | |||
public static string UserLocationRoleBy(int campaignId, | |||
int userLocationRuleId) | |||
=> $"{GetUserLocationRolesUrlBase(campaignId)}/{userLocationRuleId}"; | |||
} | |||
private static string GetUserLocationRolesUrlBase(int campaignId) | |||
=> $"{CampaignsUrlBase}/{campaignId}/{EndpointLocationName}"; | |||
} | |||
} |
@ -0,0 +1,30 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Compile Remove="Base\CampaignScenarioBase.cs" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> | |||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.1.0" /> | |||
<PackageReference Include="xunit" Version="2.3.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | |||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="Base\CampaignScenarioBase.cs" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\src\Services\Location\Locations.API\Locations.API.csproj" /> | |||
<ProjectReference Include="..\..\src\Services\Marketing\Marketing.API\Marketing.API.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,46 @@ | |||
using Marketing.FunctionalTests.Base; | |||
using Microsoft.eShopOnContainers.Services.Locations.API.ViewModel; | |||
using Microsoft.eShopOnContainers.Services.Marketing.API.Dto; | |||
using Newtonsoft.Json; | |||
using System.Collections.Generic; | |||
using System.Net.Http; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using Xunit; | |||
namespace Marketing.FunctionalTests | |||
{ | |||
public class MarketingScenarios : MarketingScenariosBase | |||
{ | |||
[Fact] | |||
public async Task Set_new_user_location_and_get_location_campaign_by_user_id() | |||
{ | |||
using (var locationsServer = new LocationsScenariosBase().CreateServer()) | |||
using (var marketingServer = new MarketingScenariosBase().CreateServer()) | |||
{ | |||
var location = new LocationRequest | |||
{ | |||
Longitude = -122.315752, | |||
Latitude = 47.60461 | |||
}; | |||
var content = new StringContent(JsonConvert.SerializeObject(location), | |||
Encoding.UTF8, "application/json"); | |||
// GIVEN a new location of user is created | |||
await locationsServer.CreateClient() | |||
.PostAsync(LocationsScenariosBase.Post.AddNewLocation, content); | |||
await Task.Delay(300); | |||
//Get campaing from Marketing.API | |||
var campaignsResponse = await marketingServer.CreateClient() | |||
.GetAsync(CampaignScenariosBase.Get.Campaigns); | |||
var responseBody = await campaignsResponse.Content.ReadAsStringAsync(); | |||
var campaigns = JsonConvert.DeserializeObject<List<CampaignDTO>>(responseBody); | |||
Assert.True(campaigns.Count > 0); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,12 @@ | |||
{ | |||
"ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=Pass@word", | |||
"MongoConnectionString": "mongodb://localhost:27017", | |||
"MongoDatabase": "MarketingDb", | |||
"IdentityUrl": "http://localhost:5105", | |||
"isTest": "true", | |||
"EventBusConnection": "localhost", | |||
"AzureServiceBusEnabled": false, | |||
"SubscriptionClientName": "Marketing", | |||
"PicBaseUrl": "http://localhost:5110/api/v1/campaigns/[0]/pic/", | |||
"SubscriptionClientName": "Marketing" | |||
} |
@ -0,0 +1,26 @@ | |||
using Microsoft.AspNetCore.Http; | |||
using System.Security.Claims; | |||
using System.Threading.Tasks; | |||
namespace Ordering.FunctionalTests.Base | |||
{ | |||
class AutoAuthorizeMiddleware | |||
{ | |||
private readonly RequestDelegate _next; | |||
public AutoAuthorizeMiddleware(RequestDelegate rd) | |||
{ | |||
_next = rd; | |||
} | |||
public async Task Invoke(HttpContext httpContext) | |||
{ | |||
var identity = new ClaimsIdentity("cookies"); | |||
identity.AddClaim(new Claim("sub", "9e3163b9-1ae6-4652-9dc6-7898ab7b7a00")); | |||
httpContext.User.AddIdentity(identity); | |||
await _next.Invoke(httpContext); | |||
} | |||
} | |||
} |
@ -0,0 +1,35 @@ | |||
using Microsoft.AspNetCore; | |||
using Microsoft.AspNetCore.Hosting; | |||
using Microsoft.AspNetCore.TestHost; | |||
using System.IO; | |||
namespace Ordering.FunctionalTests.Base | |||
{ | |||
class BasketScenariosBase | |||
{ | |||
private const string ApiUrlBase = "api/v1/basket"; | |||
public TestServer CreateServer() | |||
{ | |||
var webHostBuilder = WebHost.CreateDefaultBuilder(); | |||
webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory() + "\\Services\\Basket"); | |||
webHostBuilder.UseStartup<BasketTestsStartup>(); | |||
return new TestServer(webHostBuilder); | |||
} | |||
public static class Get | |||
{ | |||
public static string GetBasketByCustomer(string customerId) | |||
{ | |||
return $"{ApiUrlBase}/{customerId}"; | |||
} | |||
} | |||
public static class Post | |||
{ | |||
public static string CreateBasket = $"{ApiUrlBase}/"; | |||
public static string Checkout = $"{ApiUrlBase}/checkout"; | |||
} | |||
} | |||
} |
@ -0,0 +1,25 @@ | |||
using Microsoft.AspNetCore.Builder; | |||
using Microsoft.eShopOnContainers.Services.Basket.API; | |||
using Microsoft.Extensions.Configuration; | |||
namespace Ordering.FunctionalTests.Base | |||
{ | |||
class BasketTestsStartup : Startup | |||
{ | |||
public BasketTestsStartup(IConfiguration configuration) : base(configuration) | |||
{ | |||
} | |||
protected override void ConfigureAuth(IApplicationBuilder app) | |||
{ | |||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant()) | |||
{ | |||
app.UseMiddleware<AutoAuthorizeMiddleware>(); | |||
} | |||
else | |||
{ | |||
base.ConfigureAuth(app); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,18 @@ | |||
using Microsoft.AspNetCore.TestHost; | |||
using System; | |||
using System.Net.Http; | |||
namespace Ordering.FunctionalTests.Base | |||
{ | |||
static class HttpClientExtensions | |||
{ | |||
public static HttpClient CreateIdempotentClient(this TestServer server) | |||
{ | |||
var client = server.CreateClient(); | |||
client.DefaultRequestHeaders.Add("x-requestid", Guid.NewGuid().ToString()); | |||
return client; | |||
} | |||
} | |||
} |
@ -0,0 +1,75 @@ | |||
using Microsoft.AspNetCore; | |||
using Microsoft.AspNetCore.Hosting; | |||
using Microsoft.AspNetCore.TestHost; | |||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; | |||
using Microsoft.eShopOnContainers.Services.Ordering.API; | |||
using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; | |||
using Microsoft.Extensions.Configuration; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using Microsoft.Extensions.Logging; | |||
using Microsoft.Extensions.Options; | |||
using System.IO; | |||
namespace Ordering.FunctionalTests.Base | |||
{ | |||
public class OrderingScenariosBase | |||
{ | |||
public TestServer CreateServer() | |||
{ | |||
var webHostBuilder = WebHost.CreateDefaultBuilder(); | |||
webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory() + "\\Services\\Ordering"); | |||
webHostBuilder.UseStartup<OrderingTestsStartup>(); | |||
webHostBuilder.ConfigureAppConfiguration((builderContext, config) => | |||
{ | |||
config.AddJsonFile("settings.json"); | |||
}); | |||
var testServer = new TestServer(webHostBuilder); | |||
testServer.Host | |||
.MigrateDbContext<OrderingContext>((context, services) => | |||
{ | |||
var env = services.GetService<IHostingEnvironment>(); | |||
var settings = services.GetService<IOptions<OrderingSettings>>(); | |||
var logger = services.GetService<ILogger<OrderingContextSeed>>(); | |||
new OrderingContextSeed() | |||
.SeedAsync(context, env, settings, logger) | |||
.Wait(); | |||
}) | |||
.MigrateDbContext<IntegrationEventLogContext>((_, __) => { }); | |||
return testServer; | |||
} | |||
public static class Get | |||
{ | |||
public static string Orders = "api/v1/orders"; | |||
public static string OrderBy(int id) | |||
{ | |||
return $"api/v1/orders/{id}"; | |||
} | |||
} | |||
public static class Post | |||
{ | |||
public static string AddNewOrder = "api/v1/orders/new"; | |||
} | |||
public static class Put | |||
{ | |||
public static string CancelOrder = "api/v1/orders/cancel"; | |||
public static string ShipOrder = "api/v1/orders/ship"; | |||
} | |||
public static class Delete | |||
{ | |||
public static string OrderBy(int id) | |||
{ | |||
return $"api/v1/orders/{id}"; | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,25 @@ | |||
using Microsoft.AspNetCore.Builder; | |||
using Microsoft.eShopOnContainers.Services.Ordering.API; | |||
using Microsoft.Extensions.Configuration; | |||
namespace Ordering.FunctionalTests.Base | |||
{ | |||
public class OrderingTestsStartup : Startup | |||
{ | |||
public OrderingTestsStartup(IConfiguration env) : base(env) | |||
{ | |||
} | |||
protected override void ConfigureAuth(IApplicationBuilder app) | |||
{ | |||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant()) | |||
{ | |||
app.UseMiddleware<AutoAuthorizeMiddleware>(); | |||
} | |||
else | |||
{ | |||
base.ConfigureAuth(app); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,29 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> | |||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.1.0" /> | |||
<PackageReference Include="xunit" Version="2.3.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | |||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\src\Services\Basket\Basket.API\Basket.API.csproj" /> | |||
<ProjectReference Include="..\..\src\Services\Ordering\Ordering.API\Ordering.API.csproj" /> | |||
<ProjectReference Include="..\..\src\Web\WebMVC\WebMVC.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Update="settings.json"> | |||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
</None> | |||
</ItemGroup> | |||
</Project> |
@ -0,0 +1,185 @@ | |||
using Microsoft.eShopOnContainers.Services.Basket.API.Model; | |||
//using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries; | |||
using Microsoft.eShopOnContainers.WebMVC.ViewModels; | |||
using Newtonsoft.Json; | |||
using Ordering.FunctionalTests.Base; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Net; | |||
using System.Net.Http; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using WebMVC.Models; | |||
using Xunit; | |||
namespace Ordering.FunctionalTests | |||
{ | |||
public class OrderingScenarios : OrderingScenariosBase | |||
{ | |||
[Fact] | |||
public async Task Cancel_basket_and_check_order_status_cancelled() | |||
{ | |||
using (var orderServer = new OrderingScenariosBase().CreateServer()) | |||
using (var basketServer = new BasketScenariosBase().CreateServer()) | |||
{ | |||
// Expected data | |||
var cityExpected = $"city-{Guid.NewGuid()}"; | |||
var orderStatusExpected = "cancelled"; | |||
var basketClient = basketServer.CreateIdempotentClient(); | |||
var orderClient = orderServer.CreateIdempotentClient(); | |||
// GIVEN a basket is created | |||
var contentBasket = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json"); | |||
await basketClient.PostAsync(BasketScenariosBase.Post.CreateBasket, contentBasket); | |||
// AND basket checkout is sent | |||
await basketClient.PostAsync(BasketScenariosBase.Post.Checkout, new StringContent(BuildCheckout(cityExpected), UTF8Encoding.UTF8, "application/json")); | |||
// WHEN Order is created in Ordering.api | |||
var newOrder = await TryGetNewOrderCreated(cityExpected, orderClient); | |||
// AND Order is cancelled in Ordering.api | |||
await orderClient.PutAsync(OrderingScenariosBase.Put.CancelOrder, new StringContent(BuildCancelOrder(newOrder.OrderNumber), UTF8Encoding.UTF8, "application/json")); | |||
// AND the requested order is retrieved | |||
var order = await TryGetNewOrderCreated(cityExpected, orderClient); | |||
// THEN check status | |||
Assert.Equal(orderStatusExpected, order.Status); | |||
} | |||
} | |||
[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(); | |||
} | |||
} | |||
[Fact] | |||
public async Task Cancel_order_no_order_created_bad_request_response() | |||
{ | |||
using (var server = CreateServer()) | |||
{ | |||
var content = new StringContent(BuildOrder(), UTF8Encoding.UTF8, "application/json"); | |||
var response = await server.CreateIdempotentClient() | |||
.PutAsync(Put.CancelOrder, content); | |||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); | |||
} | |||
} | |||
[Fact] | |||
public async Task Ship_order_no_order_created_bad_request_response() | |||
{ | |||
using (var server = CreateServer()) | |||
{ | |||
var content = new StringContent(BuildOrder(), UTF8Encoding.UTF8, "application/json"); | |||
var response = await server.CreateIdempotentClient() | |||
.PutAsync(Put.ShipOrder, content); | |||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); | |||
} | |||
} | |||
string BuildOrder() | |||
{ | |||
var order = new OrderDTO() | |||
{ | |||
OrderNumber = "-1" | |||
}; | |||
return JsonConvert.SerializeObject(order); | |||
} | |||
private async Task<Order> TryGetNewOrderCreated(string city, HttpClient orderClient) | |||
{ | |||
var counter = 0; | |||
Order order = null; | |||
while (counter < 20) | |||
{ | |||
//get the orders and verify that the new order has been created | |||
var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenariosBase.Get.Orders); | |||
var orders = JsonConvert.DeserializeObject<List<Order>>(ordersGetResponse); | |||
if (orders == null || orders.Count == 0) | |||
{ | |||
counter++; | |||
await Task.Delay(100); | |||
continue; | |||
} | |||
var lastOrder = orders.OrderByDescending(o => o.Date).First(); | |||
int.TryParse(lastOrder.OrderNumber, out int id); | |||
var orderDetails = await orderClient.GetStringAsync(OrderingScenariosBase.Get.OrderBy(id)); | |||
order = JsonConvert.DeserializeObject<Order>(orderDetails); | |||
if (IsOrderCreated(order, city)) | |||
{ | |||
break; | |||
} | |||
} | |||
return order; | |||
} | |||
private bool IsOrderCreated(Order order, string city) | |||
{ | |||
return order.City == city; | |||
} | |||
string BuildBasket() | |||
{ | |||
var order = new CustomerBasket("9e3163b9-1ae6-4652-9dc6-7898ab7b7a00"); | |||
order.Items = new List<Microsoft.eShopOnContainers.Services.Basket.API.Model.BasketItem>() | |||
{ | |||
new Microsoft.eShopOnContainers.Services.Basket.API.Model.BasketItem() | |||
{ | |||
Id = "1", | |||
ProductName = "ProductName", | |||
ProductId = "1", | |||
UnitPrice = 10, | |||
Quantity = 1 | |||
} | |||
}; | |||
return JsonConvert.SerializeObject(order); | |||
} | |||
string BuildCancelOrder(string orderId) | |||
{ | |||
var order = new OrderDTO() | |||
{ | |||
OrderNumber = orderId | |||
}; | |||
return JsonConvert.SerializeObject(order); | |||
} | |||
string BuildCheckout(string cityExpected) | |||
{ | |||
var checkoutBasket = new BasketDTO() | |||
{ | |||
City = cityExpected, | |||
Street = "street", | |||
State = "state", | |||
Country = "coutry", | |||
ZipCode = "zipcode", | |||
CardNumber = "1111111111111", | |||
CardHolderName = "CardHolderName", | |||
CardExpiration = DateTime.Now.AddYears(1), | |||
CardSecurityNumber = "123", | |||
CardTypeId = 1, | |||
Buyer = "Buyer", | |||
RequestId = Guid.NewGuid() | |||
}; | |||
return JsonConvert.SerializeObject(checkoutBasket); | |||
} | |||
} | |||
} |
@ -0,0 +1,10 @@ | |||
{ | |||
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", | |||
"ExternalCatalogBaseUrl": "http://localhost:5101", | |||
"IdentityUrl": "http://localhost:5105", | |||
"isTest": "true", | |||
"EventBusConnection": "localhost", | |||
"CheckUpdateTime": "30000", | |||
"GracePeriodTime": "1", | |||
"SubscriptionClientName": "Ordering" | |||
} |
@ -0,0 +1,91 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace UnitTest.Ordering.Application | |||
{ | |||
using global::Ordering.API.Application.Models; | |||
using MediatR; | |||
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency; | |||
using Moq; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
using Xunit; | |||
public class IdentifiedCommandHandlerTest | |||
{ | |||
private readonly Mock<IRequestManager> _requestManager; | |||
private readonly Mock<IMediator> _mediator; | |||
public IdentifiedCommandHandlerTest() | |||
{ | |||
_requestManager = new Mock<IRequestManager>(); | |||
_mediator = new Mock<IMediator>(); | |||
} | |||
[Fact] | |||
public async Task Handler_sends_command_when_order_no_exists() | |||
{ | |||
// Arrange | |||
var fakeGuid = Guid.NewGuid(); | |||
var fakeOrderCmd = new IdentifiedCommand<CreateOrderCommand, bool>(FakeOrderRequest(), fakeGuid); | |||
_requestManager.Setup(x => x.ExistAsync(It.IsAny<Guid>())) | |||
.Returns(Task.FromResult(false)); | |||
_mediator.Setup(x => x.Send(It.IsAny<IRequest<bool>>(),default(System.Threading.CancellationToken))) | |||
.Returns(Task.FromResult(true)); | |||
//Act | |||
var handler = new IdentifiedCommandHandler<CreateOrderCommand, bool>(_mediator.Object, _requestManager.Object); | |||
var cltToken = new System.Threading.CancellationToken(); | |||
var result = await handler.Handle(fakeOrderCmd, cltToken); | |||
//Assert | |||
Assert.True(result); | |||
_mediator.Verify(x => x.Send(It.IsAny<IRequest<bool>>(), default(System.Threading.CancellationToken)), Times.Once()); | |||
} | |||
[Fact] | |||
public async Task Handler_sends_no_command_when_order_already_exists() | |||
{ | |||
// Arrange | |||
var fakeGuid = Guid.NewGuid(); | |||
var fakeOrderCmd = new IdentifiedCommand<CreateOrderCommand, bool>(FakeOrderRequest(), fakeGuid); | |||
_requestManager.Setup(x => x.ExistAsync(It.IsAny<Guid>())) | |||
.Returns(Task.FromResult(true)); | |||
_mediator.Setup(x => x.Send(It.IsAny<IRequest<bool>>(), default(System.Threading.CancellationToken))) | |||
.Returns(Task.FromResult(true)); | |||
//Act | |||
var handler = new IdentifiedCommandHandler<CreateOrderCommand, bool>(_mediator.Object, _requestManager.Object); | |||
var cltToken = new System.Threading.CancellationToken(); | |||
var result = await handler.Handle(fakeOrderCmd, cltToken); | |||
//Assert | |||
Assert.False(result); | |||
_mediator.Verify(x => x.Send(It.IsAny<IRequest<bool>>(), default(System.Threading.CancellationToken)), Times.Never()); | |||
} | |||
private CreateOrderCommand FakeOrderRequest(Dictionary<string, object> args = null) | |||
{ | |||
return new CreateOrderCommand( | |||
new List<BasketItem>(), | |||
userId: args != null && args.ContainsKey("userId") ? (string)args["userId"] : null, | |||
userName: args != null && args.ContainsKey("userName") ? (string)args["userName"] : null, | |||
city: args != null && args.ContainsKey("city") ? (string)args["city"] : null, | |||
street: args != null && args.ContainsKey("street") ? (string)args["street"] : null, | |||
state: args != null && args.ContainsKey("state") ? (string)args["state"] : null, | |||
country: args != null && args.ContainsKey("country") ? (string)args["country"] : null, | |||
zipcode: args != null && args.ContainsKey("zipcode") ? (string)args["zipcode"] : null, | |||
cardNumber: args != null && args.ContainsKey("cardNumber") ? (string)args["cardNumber"] : "1234", | |||
cardExpiration: args != null && args.ContainsKey("cardExpiration") ? (DateTime)args["cardExpiration"] : DateTime.MinValue, | |||
cardSecurityNumber: args != null && args.ContainsKey("cardSecurityNumber") ? (string)args["cardSecurityNumber"] : "123", | |||
cardHolderName: args != null && args.ContainsKey("cardHolderName") ? (string)args["cardHolderName"] : "XXX", | |||
cardTypeId: args != null && args.ContainsKey("cardTypeId") ? (int)args["cardTypeId"] : 0); | |||
} | |||
} | |||
} |
@ -0,0 +1,94 @@ | |||
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; | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace UnitTest.Ordering.Application | |||
{ | |||
using global::Ordering.API.Application.Models; | |||
using MediatR; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
using Xunit; | |||
using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand; | |||
public class NewOrderRequestHandlerTest | |||
{ | |||
private readonly Mock<IOrderRepository> _orderRepositoryMock; | |||
private readonly Mock<IIdentityService> _identityServiceMock; | |||
private readonly Mock<IMediator> _mediator; | |||
public NewOrderRequestHandlerTest() | |||
{ | |||
_orderRepositoryMock = new Mock<IOrderRepository>(); | |||
_identityServiceMock = new Mock<IIdentityService>(); | |||
_mediator = new Mock<IMediator>(); | |||
} | |||
[Fact] | |||
public async Task Handle_return_false_if_order_is_not_persisted() | |||
{ | |||
var buyerId = "1234"; | |||
var fakeOrderCmd = FakeOrderRequestWithBuyer(new Dictionary<string, object> | |||
{ ["cardExpiration"] = DateTime.Now.AddYears(1) }); | |||
_orderRepositoryMock.Setup(orderRepo => orderRepo.GetAsync(It.IsAny<int>())) | |||
.Returns(Task.FromResult<Order>(FakeOrder())); | |||
_orderRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken))) | |||
.Returns(Task.FromResult(1)); | |||
_identityServiceMock.Setup(svc => svc.GetUserIdentity()).Returns(buyerId); | |||
//Act | |||
var handler = new CreateOrderCommandHandler(_mediator.Object, _orderRepositoryMock.Object, _identityServiceMock.Object); | |||
var cltToken = new System.Threading.CancellationToken(); | |||
var result = await handler.Handle(fakeOrderCmd, cltToken); | |||
//Assert | |||
Assert.False(result); | |||
} | |||
[Fact] | |||
public void Handle_throws_exception_when_no_buyerId() | |||
{ | |||
//Assert | |||
Assert.Throws<ArgumentNullException>(() => new Buyer(string.Empty, string.Empty)); | |||
} | |||
private Buyer FakeBuyer() | |||
{ | |||
return new Buyer(Guid.NewGuid().ToString(), "1"); | |||
} | |||
private Order FakeOrder() | |||
{ | |||
return new Order("1", "fakeName", new Address("street", "city", "state", "country", "zipcode"), 1, "12", "111", "fakeName", DateTime.Now.AddYears(1)); | |||
} | |||
private CreateOrderCommand FakeOrderRequestWithBuyer(Dictionary<string, object> args = null) | |||
{ | |||
return new CreateOrderCommand( | |||
new List<BasketItem>(), | |||
userId: args != null && args.ContainsKey("userId") ? (string)args["userId"] : null, | |||
userName: args != null && args.ContainsKey("userName") ? (string)args["userName"] : null, | |||
city: args != null && args.ContainsKey("city") ? (string)args["city"] : null, | |||
street: args != null && args.ContainsKey("street") ? (string)args["street"] : null, | |||
state: args != null && args.ContainsKey("state") ? (string)args["state"] : null, | |||
country: args != null && args.ContainsKey("country") ? (string)args["country"] : null, | |||
zipcode: args != null && args.ContainsKey("zipcode") ? (string)args["zipcode"] : null, | |||
cardNumber: args != null && args.ContainsKey("cardNumber") ? (string)args["cardNumber"] : "1234", | |||
cardExpiration: args != null && args.ContainsKey("cardExpiration") ? (DateTime)args["cardExpiration"] : DateTime.MinValue, | |||
cardSecurityNumber: args != null && args.ContainsKey("cardSecurityNumber") ? (string)args["cardSecurityNumber"] : "123", | |||
cardHolderName: args != null && args.ContainsKey("cardHolderName") ? (string)args["cardHolderName"] : "XXX", | |||
cardTypeId: args != null && args.ContainsKey("cardTypeId") ? (int)args["cardTypeId"] : 0); | |||
} | |||
} | |||
} |
@ -0,0 +1,86 @@ | |||
using Microsoft.AspNetCore.Http; | |||
using Microsoft.AspNetCore.Mvc; | |||
using Microsoft.eShopOnContainers.WebMVC.Controllers; | |||
using Microsoft.eShopOnContainers.WebMVC.Services; | |||
using Microsoft.eShopOnContainers.WebMVC.ViewModels; | |||
using Moq; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
using Xunit; | |||
using BasketModel = Microsoft.eShopOnContainers.WebMVC.ViewModels.Basket; | |||
namespace UnitTest.Ordering.Application | |||
{ | |||
public class OrderControllerTest | |||
{ | |||
private readonly Mock<IOrderingService> _orderServiceMock; | |||
private readonly Mock<IBasketService> _basketServiceMock; | |||
private readonly Mock<IIdentityParser<ApplicationUser>> _identityParserMock; | |||
private readonly Mock<HttpContext> _contextMock; | |||
public OrderControllerTest() | |||
{ | |||
_orderServiceMock = new Mock<IOrderingService>(); | |||
_basketServiceMock = new Mock<IBasketService>(); | |||
_identityParserMock = new Mock<IIdentityParser<ApplicationUser>>(); | |||
_contextMock = new Mock<HttpContext>(); | |||
} | |||
[Fact] | |||
public async Task Get_order_list_success() | |||
{ | |||
//Arrange | |||
var expectedTotalResults = 1; | |||
var fakeOrder = GetFakeOrder(); | |||
_orderServiceMock.Setup(x => x.GetMyOrders(It.IsAny<ApplicationUser>())) | |||
.Returns(Task.FromResult(new List<Order>() { fakeOrder })); | |||
//Act | |||
var orderController = new OrderController(_orderServiceMock.Object, _basketServiceMock.Object, _identityParserMock.Object); | |||
orderController.ControllerContext.HttpContext = _contextMock.Object; | |||
var actionResult = await orderController.Index(fakeOrder); | |||
//Assert | |||
var viewResult = Assert.IsType<ViewResult>(actionResult); | |||
var model = Assert.IsAssignableFrom<List<Order>>(viewResult.ViewData.Model); | |||
Assert.Equal(model.Count, expectedTotalResults); | |||
} | |||
[Fact] | |||
public async Task Get_order_detail_success() | |||
{ | |||
//Arrange | |||
var fakeOrderId = "12"; | |||
var fakeOrder = GetFakeOrder(); | |||
_orderServiceMock.Setup(x => x.GetOrder(It.IsAny<ApplicationUser>(), It.IsAny<string>())) | |||
.Returns(Task.FromResult(fakeOrder)); | |||
//Act | |||
var orderController = new OrderController(_orderServiceMock.Object, _basketServiceMock.Object, _identityParserMock.Object); | |||
orderController.ControllerContext.HttpContext = _contextMock.Object; | |||
var actionResult = await orderController.Detail(fakeOrderId); | |||
//Assert | |||
var viewResult = Assert.IsType<ViewResult>(actionResult); | |||
Assert.IsAssignableFrom<Order>(viewResult.ViewData.Model); | |||
} | |||
private Order GetFakeOrder() | |||
{ | |||
return new Order() | |||
{ | |||
OrderNumber = "1", | |||
CardNumber = "12", | |||
CardSecurityNumber = "1212", | |||
Status = "Pending", | |||
RequestId = Guid.NewGuid(), | |||
CardExpiration = DateTime.Now.AddYears(1), | |||
}; | |||
} | |||
} | |||
} |
@ -0,0 +1,141 @@ | |||
using MediatR; | |||
using Microsoft.AspNetCore.Mvc; | |||
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; | |||
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; | |||
using System.Threading.Tasks; | |||
using Xunit; | |||
namespace UnitTest.Ordering.Application | |||
{ | |||
public class OrdersWebApiTest | |||
{ | |||
private readonly Mock<IMediator> _mediatorMock; | |||
private readonly Mock<IOrderQueries> _orderQueriesMock; | |||
private readonly Mock<IIdentityService> _identityServiceMock; | |||
public OrdersWebApiTest() | |||
{ | |||
_mediatorMock = new Mock<IMediator>(); | |||
_orderQueriesMock = new Mock<IOrderQueries>(); | |||
_identityServiceMock = new Mock<IIdentityService>(); | |||
} | |||
[Fact] | |||
public async Task Create_order_with_requestId_success() | |||
{ | |||
//Arrange | |||
_mediatorMock.Setup(x => x.Send(It.IsAny<IdentifiedCommand<CancelOrderCommand, bool>>(), default(CancellationToken))) | |||
.Returns(Task.FromResult(true)); | |||
//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); | |||
} | |||
[Fact] | |||
public async Task Cancel_order_bad_request() | |||
{ | |||
//Arrange | |||
_mediatorMock.Setup(x => x.Send(It.IsAny<IdentifiedCommand<CancelOrderCommand, bool>>(), default(CancellationToken))) | |||
.Returns(Task.FromResult(true)); | |||
//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); | |||
} | |||
[Fact] | |||
public async Task Ship_order_with_requestId_success() | |||
{ | |||
//Arrange | |||
_mediatorMock.Setup(x => x.Send(It.IsAny<IdentifiedCommand<ShipOrderCommand, bool>>(), default(System.Threading.CancellationToken))) | |||
.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.Send(It.IsAny<IdentifiedCommand<CreateOrderCommand, bool>>(), default(System.Threading.CancellationToken))) | |||
.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() | |||
{ | |||
//Arrange | |||
var fakeDynamicResult = Enumerable.Empty<OrderSummary>(); | |||
_orderQueriesMock.Setup(x => x.GetOrdersFromUserAsync(Guid.NewGuid())) | |||
.Returns(Task.FromResult(fakeDynamicResult)); | |||
//Act | |||
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); | |||
var actionResult = await orderController.GetOrders() as OkObjectResult; | |||
//Assert | |||
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); | |||
} | |||
[Fact] | |||
public async Task Get_order_success() | |||
{ | |||
//Arrange | |||
var fakeOrderId = 123; | |||
var fakeDynamicResult = new Order(); | |||
_orderQueriesMock.Setup(x => x.GetOrderAsync(It.IsAny<int>())) | |||
.Returns(Task.FromResult(fakeDynamicResult)); | |||
//Act | |||
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); | |||
var actionResult = await orderController.GetOrder(fakeOrderId) as OkObjectResult; | |||
//Assert | |||
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); | |||
} | |||
[Fact] | |||
public async Task Get_cardTypes_success() | |||
{ | |||
//Arrange | |||
var fakeDynamicResult = Enumerable.Empty<CardType>(); | |||
_orderQueriesMock.Setup(x => x.GetCardTypesAsync()) | |||
.Returns(Task.FromResult(fakeDynamicResult)); | |||
//Act | |||
var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); | |||
var actionResult = await orderController.GetCardTypes() as OkObjectResult; | |||
//Assert | |||
Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); | |||
} | |||
} | |||
} |
@ -0,0 +1,48 @@ | |||
using System; | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; | |||
namespace UnitTest.Ordering | |||
{ | |||
public class AddressBuilder | |||
{ | |||
public Address Build() | |||
{ | |||
return new Address("street", "city", "state", "country", "zipcode"); | |||
} | |||
} | |||
public class OrderBuilder | |||
{ | |||
private readonly Order order; | |||
public OrderBuilder(Address address) | |||
{ | |||
order = new Order( | |||
"userId", | |||
"fakeName", | |||
address, | |||
cardTypeId:5, | |||
cardNumber:"12", | |||
cardSecurityNumber:"123", | |||
cardHolderName:"name", | |||
cardExpiration:DateTime.UtcNow); | |||
} | |||
public OrderBuilder AddOne( | |||
int productId, | |||
string productName, | |||
decimal unitPrice, | |||
decimal discount, | |||
string pictureUrl, | |||
int units = 1) | |||
{ | |||
order.AddOrderItem(productId, productName, unitPrice, discount, pictureUrl, units); | |||
return this; | |||
} | |||
public Order Build() | |||
{ | |||
return order; | |||
} | |||
} | |||
} |
@ -0,0 +1,132 @@ | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; | |||
using Ordering.Domain.Exceptions; | |||
using System; | |||
using Xunit; | |||
public class BuyerAggregateTest | |||
{ | |||
public BuyerAggregateTest() | |||
{ } | |||
[Fact] | |||
public void Create_buyer_item_success() | |||
{ | |||
//Arrange | |||
var identity = new Guid().ToString(); | |||
var name = "fakeUser"; | |||
//Act | |||
var fakeBuyerItem = new Buyer(identity, name); | |||
//Assert | |||
Assert.NotNull(fakeBuyerItem); | |||
} | |||
[Fact] | |||
public void Create_buyer_item_fail() | |||
{ | |||
//Arrange | |||
var identity = string.Empty; | |||
var name = "fakeUser"; | |||
//Act - Assert | |||
Assert.Throws<ArgumentNullException>(() => new Buyer(identity, name)); | |||
} | |||
[Fact] | |||
public void add_payment_success() | |||
{ | |||
//Arrange | |||
var cardTypeId = 1; | |||
var alias = "fakeAlias"; | |||
var cardNumber = "124"; | |||
var securityNumber = "1234"; | |||
var cardHolderName = "FakeHolderNAme"; | |||
var expiration = DateTime.Now.AddYears(1); | |||
var orderId = 1; | |||
var name = "fakeUser"; | |||
var identity = new Guid().ToString(); | |||
var fakeBuyerItem = new Buyer(identity, name); | |||
//Act | |||
var result = fakeBuyerItem.VerifyOrAddPaymentMethod(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration, orderId); | |||
//Assert | |||
Assert.NotNull(result); | |||
} | |||
[Fact] | |||
public void create_payment_method_success() | |||
{ | |||
//Arrange | |||
var cardTypeId = 1; | |||
var alias = "fakeAlias"; | |||
var cardNumber = "124"; | |||
var securityNumber = "1234"; | |||
var cardHolderName = "FakeHolderNAme"; | |||
var expiration = DateTime.Now.AddYears(1); | |||
var fakePaymentMethod = new PaymentMethod(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration); | |||
//Act | |||
var result = new PaymentMethod(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration); | |||
//Assert | |||
Assert.NotNull(result); | |||
} | |||
[Fact] | |||
public void create_payment_method_expiration_fail() | |||
{ | |||
//Arrange | |||
var cardTypeId = 1; | |||
var alias = "fakeAlias"; | |||
var cardNumber = "124"; | |||
var securityNumber = "1234"; | |||
var cardHolderName = "FakeHolderNAme"; | |||
var expiration = DateTime.Now.AddYears(-1); | |||
//Act - Assert | |||
Assert.Throws<OrderingDomainException>(() => new PaymentMethod(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration)); | |||
} | |||
[Fact] | |||
public void payment_method_isEqualTo() | |||
{ | |||
//Arrange | |||
var cardTypeId = 1; | |||
var alias = "fakeAlias"; | |||
var cardNumber = "124"; | |||
var securityNumber = "1234"; | |||
var cardHolderName = "FakeHolderNAme"; | |||
var expiration = DateTime.Now.AddYears(1); | |||
//Act | |||
var fakePaymentMethod = new PaymentMethod(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration); | |||
var result = fakePaymentMethod.IsEqualTo(cardTypeId, cardNumber, expiration); | |||
//Assert | |||
Assert.True(result); | |||
} | |||
[Fact] | |||
public void Add_new_PaymentMethod_raises_new_event() | |||
{ | |||
//Arrange | |||
var alias = "fakeAlias"; | |||
var orderId = 1; | |||
var cardTypeId = 5; | |||
var cardNumber = "12"; | |||
var cardSecurityNumber = "123"; | |||
var cardHolderName = "FakeName"; | |||
var cardExpiration = DateTime.Now.AddYears(1); | |||
var expectedResult = 1; | |||
var name = "fakeUser"; | |||
//Act | |||
var fakeBuyer = new Buyer(Guid.NewGuid().ToString(), name); | |||
fakeBuyer.VerifyOrAddPaymentMethod(cardTypeId, alias, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration, orderId); | |||
//Assert | |||
Assert.Equal(fakeBuyer.DomainEvents.Count, expectedResult); | |||
} | |||
} |
@ -0,0 +1,180 @@ | |||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; | |||
using Ordering.Domain.Events; | |||
using Ordering.Domain.Exceptions; | |||
using System; | |||
using System.Linq; | |||
using UnitTest.Ordering; | |||
using Xunit; | |||
public class OrderAggregateTest | |||
{ | |||
public OrderAggregateTest() | |||
{ } | |||
[Fact] | |||
public void Create_order_item_success() | |||
{ | |||
//Arrange | |||
var productId = 1; | |||
var productName = "FakeProductName"; | |||
var unitPrice = 12; | |||
var discount = 15; | |||
var pictureUrl = "FakeUrl"; | |||
var units = 5; | |||
//Act | |||
var fakeOrderItem = new OrderItem(productId, productName, unitPrice, discount, pictureUrl, units); | |||
//Assert | |||
Assert.NotNull(fakeOrderItem); | |||
} | |||
[Fact] | |||
public void Invalid_number_of_units() | |||
{ | |||
//Arrange | |||
var productId = 1; | |||
var productName = "FakeProductName"; | |||
var unitPrice = 12; | |||
var discount = 15; | |||
var pictureUrl = "FakeUrl"; | |||
var units = -1; | |||
//Act - Assert | |||
Assert.Throws<OrderingDomainException>(() => new OrderItem(productId, productName, unitPrice, discount, pictureUrl, units)); | |||
} | |||
[Fact] | |||
public void Invalid_total_of_order_item_lower_than_discount_applied() | |||
{ | |||
//Arrange | |||
var productId = 1; | |||
var productName = "FakeProductName"; | |||
var unitPrice = 12; | |||
var discount = 15; | |||
var pictureUrl = "FakeUrl"; | |||
var units = 1; | |||
//Act - Assert | |||
Assert.Throws<OrderingDomainException>(() => new OrderItem(productId, productName, unitPrice, discount, pictureUrl, units)); | |||
} | |||
[Fact] | |||
public void Invalid_discount_setting() | |||
{ | |||
//Arrange | |||
var productId = 1; | |||
var productName = "FakeProductName"; | |||
var unitPrice = 12; | |||
var discount = 15; | |||
var pictureUrl = "FakeUrl"; | |||
var units = 5; | |||
//Act | |||
var fakeOrderItem = new OrderItem(productId, productName, unitPrice, discount, pictureUrl, units); | |||
//Assert | |||
Assert.Throws<OrderingDomainException>(() => fakeOrderItem.SetNewDiscount(-1)); | |||
} | |||
[Fact] | |||
public void Invalid_units_setting() | |||
{ | |||
//Arrange | |||
var productId = 1; | |||
var productName = "FakeProductName"; | |||
var unitPrice = 12; | |||
var discount = 15; | |||
var pictureUrl = "FakeUrl"; | |||
var units = 5; | |||
//Act | |||
var fakeOrderItem = new OrderItem(productId, productName, unitPrice, discount, pictureUrl, units); | |||
//Assert | |||
Assert.Throws<OrderingDomainException>(() => fakeOrderItem.AddUnits(-1)); | |||
} | |||
[Fact] | |||
public void when_add_two_times_on_the_same_item_then_the_total_of_order_should_be_the_sum_of_the_two_items() | |||
{ | |||
var address = new AddressBuilder().Build(); | |||
var order = new OrderBuilder(address) | |||
.AddOne(1,"cup",10.0m,0,string.Empty) | |||
.AddOne(1,"cup",10.0m,0,string.Empty) | |||
.Build(); | |||
Assert.Equal(20.0m, order.GetTotal()); | |||
} | |||
[Fact] | |||
public void Add_new_Order_raises_new_event() | |||
{ | |||
//Arrange | |||
var street = "fakeStreet"; | |||
var city = "FakeCity"; | |||
var state = "fakeState"; | |||
var country = "fakeCountry"; | |||
var zipcode = "FakeZipCode"; | |||
var cardTypeId = 5; | |||
var cardNumber = "12"; | |||
var cardSecurityNumber = "123"; | |||
var cardHolderName = "FakeName"; | |||
var cardExpiration = DateTime.Now.AddYears(1); | |||
var expectedResult = 1; | |||
//Act | |||
var fakeOrder = new Order("1", "fakeName", new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); | |||
//Assert | |||
Assert.Equal(fakeOrder.DomainEvents.Count, expectedResult); | |||
} | |||
[Fact] | |||
public void Add_event_Order_explicitly_raises_new_event() | |||
{ | |||
//Arrange | |||
var street = "fakeStreet"; | |||
var city = "FakeCity"; | |||
var state = "fakeState"; | |||
var country = "fakeCountry"; | |||
var zipcode = "FakeZipCode"; | |||
var cardTypeId = 5; | |||
var cardNumber = "12"; | |||
var cardSecurityNumber = "123"; | |||
var cardHolderName = "FakeName"; | |||
var cardExpiration = DateTime.Now.AddYears(1); | |||
var expectedResult = 2; | |||
//Act | |||
var fakeOrder = new Order("1", "fakeName", new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); | |||
fakeOrder.AddDomainEvent(new OrderStartedDomainEvent(fakeOrder, "fakeName", "1", cardTypeId,cardNumber,cardSecurityNumber,cardHolderName,cardExpiration)); | |||
//Assert | |||
Assert.Equal(fakeOrder.DomainEvents.Count, expectedResult); | |||
} | |||
[Fact] | |||
public void Remove_event_Order_explicitly() | |||
{ | |||
//Arrange | |||
var street = "fakeStreet"; | |||
var city = "FakeCity"; | |||
var state = "fakeState"; | |||
var country = "fakeCountry"; | |||
var zipcode = "FakeZipCode"; | |||
var cardTypeId = 5; | |||
var cardNumber = "12"; | |||
var cardSecurityNumber = "123"; | |||
var cardHolderName = "FakeName"; | |||
var cardExpiration = DateTime.Now.AddYears(1); | |||
var fakeOrder = new Order("1", "fakeName", new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); | |||
var @fakeEvent = new OrderStartedDomainEvent(fakeOrder, "1", "fakeName", cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); | |||
var expectedResult = 1; | |||
//Act | |||
fakeOrder.AddDomainEvent(@fakeEvent); | |||
fakeOrder.RemoveDomainEvent(@fakeEvent); | |||
//Assert | |||
Assert.Equal(fakeOrder.DomainEvents.Count, expectedResult); | |||
} | |||
} |
@ -0,0 +1,25 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.1</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> | |||
<PackageReference Include="xunit" Version="2.3.1" /> | |||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | |||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> | |||
<PackageReference Include="MediatR" Version="4.1.0" /> | |||
<PackageReference Include="Moq" Version="4.8.1" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\src\Services\Ordering\Ordering.API\Ordering.API.csproj" /> | |||
<ProjectReference Include="..\..\src\Services\Ordering\Ordering.Domain\Ordering.Domain.csproj" /> | |||
<ProjectReference Include="..\..\src\Services\Ordering\Ordering.Infrastructure\Ordering.Infrastructure.csproj" /> | |||
<ProjectReference Include="..\..\src\Web\WebMVC\WebMVC.csproj" /> | |||
</ItemGroup> | |||
</Project> |