Included file scoped namespace
This commit is contained in:
parent
15f5e49134
commit
f53a3e407f
@ -1,16 +1,11 @@
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
namespace FunctionalTests.Extensions;
|
||||
|
||||
namespace FunctionalTests.Extensions
|
||||
static class HttpClientExtensions
|
||||
{
|
||||
static class HttpClientExtensions
|
||||
public static HttpClient CreateIdempotentClient(this TestServer server)
|
||||
{
|
||||
public static HttpClient CreateIdempotentClient(this TestServer server)
|
||||
{
|
||||
var client = server.CreateClient();
|
||||
client.DefaultRequestHeaders.Add("x-requestid", Guid.NewGuid().ToString());
|
||||
return client;
|
||||
}
|
||||
var client = server.CreateClient();
|
||||
client.DefaultRequestHeaders.Add("x-requestid", Guid.NewGuid().ToString());
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,26 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
namespace FunctionalTests.Middleware;
|
||||
|
||||
namespace FunctionalTests.Middleware
|
||||
class AutoAuthorizeMiddleware
|
||||
{
|
||||
class AutoAuthorizeMiddleware
|
||||
public const string IDENTITY_ID = "9e3163b9-1ae6-4652-9dc6-7898ab7b7a00";
|
||||
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
|
||||
public AutoAuthorizeMiddleware(RequestDelegate rd)
|
||||
{
|
||||
public const string IDENTITY_ID = "9e3163b9-1ae6-4652-9dc6-7898ab7b7a00";
|
||||
_next = rd;
|
||||
}
|
||||
|
||||
private readonly RequestDelegate _next;
|
||||
public async Task Invoke(HttpContext httpContext)
|
||||
{
|
||||
var identity = new ClaimsIdentity("cookies");
|
||||
|
||||
identity.AddClaim(new Claim("sub", IDENTITY_ID));
|
||||
identity.AddClaim(new Claim("unique_name", IDENTITY_ID));
|
||||
identity.AddClaim(new Claim(ClaimTypes.Name, IDENTITY_ID));
|
||||
|
||||
public AutoAuthorizeMiddleware(RequestDelegate rd)
|
||||
{
|
||||
_next = rd;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext httpContext)
|
||||
{
|
||||
var identity = new ClaimsIdentity("cookies");
|
||||
|
||||
identity.AddClaim(new Claim("sub", IDENTITY_ID));
|
||||
identity.AddClaim(new Claim("unique_name", IDENTITY_ID));
|
||||
identity.AddClaim(new Claim(ClaimTypes.Name, IDENTITY_ID));
|
||||
|
||||
httpContext.User.AddIdentity(identity);
|
||||
await _next.Invoke(httpContext);
|
||||
}
|
||||
httpContext.User.AddIdentity(identity);
|
||||
await _next.Invoke(httpContext);
|
||||
}
|
||||
}
|
||||
|
@ -1,49 +1,42 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
namespace FunctionalTests.Services.Basket;
|
||||
|
||||
namespace FunctionalTests.Services.Basket
|
||||
public class BasketScenariosBase
|
||||
{
|
||||
public class BasketScenariosBase
|
||||
private const string ApiUrlBase = "api/v1/basket";
|
||||
|
||||
|
||||
public TestServer CreateServer()
|
||||
{
|
||||
private const string ApiUrlBase = "api/v1/basket";
|
||||
var path = Assembly.GetAssembly(typeof(BasketScenariosBase))
|
||||
.Location;
|
||||
|
||||
var hostBuilder = new WebHostBuilder()
|
||||
.UseContentRoot(Path.GetDirectoryName(path))
|
||||
.ConfigureAppConfiguration(cb =>
|
||||
{
|
||||
cb.AddJsonFile("Services/Basket/appsettings.json", optional: false)
|
||||
.AddEnvironmentVariables();
|
||||
}).UseStartup<BasketTestsStartup>();
|
||||
|
||||
public TestServer CreateServer()
|
||||
return new TestServer(hostBuilder);
|
||||
}
|
||||
|
||||
public static class Get
|
||||
{
|
||||
public static string GetBasket(int id)
|
||||
{
|
||||
var path = Assembly.GetAssembly(typeof(BasketScenariosBase))
|
||||
.Location;
|
||||
|
||||
var hostBuilder = new WebHostBuilder()
|
||||
.UseContentRoot(Path.GetDirectoryName(path))
|
||||
.ConfigureAppConfiguration(cb =>
|
||||
{
|
||||
cb.AddJsonFile("Services/Basket/appsettings.json", optional: false)
|
||||
.AddEnvironmentVariables();
|
||||
}).UseStartup<BasketTestsStartup>();
|
||||
|
||||
return new TestServer(hostBuilder);
|
||||
return $"{ApiUrlBase}/{id}";
|
||||
}
|
||||
|
||||
public static class Get
|
||||
public static string GetBasketByCustomer(string customerId)
|
||||
{
|
||||
public static string GetBasket(int id)
|
||||
{
|
||||
return $"{ApiUrlBase}/{id}";
|
||||
}
|
||||
|
||||
public static string GetBasketByCustomer(string customerId)
|
||||
{
|
||||
return $"{ApiUrlBase}/{customerId}";
|
||||
}
|
||||
}
|
||||
|
||||
public static class Post
|
||||
{
|
||||
public static string CreateBasket = $"{ApiUrlBase}/";
|
||||
public static string CheckoutOrder = $"{ApiUrlBase}/checkout";
|
||||
return $"{ApiUrlBase}/{customerId}";
|
||||
}
|
||||
}
|
||||
|
||||
public static class Post
|
||||
{
|
||||
public static string CreateBasket = $"{ApiUrlBase}/";
|
||||
public static string CheckoutOrder = $"{ApiUrlBase}/checkout";
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,21 @@
|
||||
using FunctionalTests.Middleware;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
namespace FunctionalTests.Services.Basket;
|
||||
using Microsoft.eShopOnContainers.Services.Basket.API;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace FunctionalTests.Services.Basket
|
||||
class BasketTestsStartup : Startup
|
||||
{
|
||||
class BasketTestsStartup : Startup
|
||||
public BasketTestsStartup(IConfiguration env) : base(env)
|
||||
{
|
||||
public BasketTestsStartup(IConfiguration env) : base(env)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ConfigureAuth(IApplicationBuilder app)
|
||||
protected override void ConfigureAuth(IApplicationBuilder app)
|
||||
{
|
||||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
|
||||
{
|
||||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
|
||||
{
|
||||
app.UseMiddleware<AutoAuthorizeMiddleware>();
|
||||
app.UseAuthorization();
|
||||
}
|
||||
else
|
||||
{
|
||||
base.ConfigureAuth(app);
|
||||
}
|
||||
app.UseMiddleware<AutoAuthorizeMiddleware>();
|
||||
app.UseAuthorization();
|
||||
}
|
||||
else
|
||||
{
|
||||
base.ConfigureAuth(app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,65 +1,53 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
|
||||
namespace FunctionalTests.Services.Catalog;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace FunctionalTests.Services.Catalog
|
||||
public class CatalogScenariosBase
|
||||
{
|
||||
public class CatalogScenariosBase
|
||||
public TestServer CreateServer()
|
||||
{
|
||||
public TestServer CreateServer()
|
||||
{
|
||||
var path = Assembly.GetAssembly(typeof(CatalogScenariosBase))
|
||||
.Location;
|
||||
var path = Assembly.GetAssembly(typeof(CatalogScenariosBase))
|
||||
.Location;
|
||||
|
||||
var hostBuilder = new WebHostBuilder()
|
||||
.UseContentRoot(Path.GetDirectoryName(path))
|
||||
.ConfigureAppConfiguration(cb =>
|
||||
{
|
||||
cb.AddJsonFile("Services/Catalog/appsettings.json", optional: false)
|
||||
.AddEnvironmentVariables();
|
||||
}).UseStartup<Startup>();
|
||||
|
||||
var testServer = new TestServer(hostBuilder);
|
||||
|
||||
testServer.Host
|
||||
.MigrateDbContext<CatalogContext>((context, services) =>
|
||||
{
|
||||
var env = services.GetService<IWebHostEnvironment>();
|
||||
var settings = services.GetService<IOptions<CatalogSettings>>();
|
||||
var logger = services.GetService<ILogger<CatalogContextSeed>>();
|
||||
|
||||
new CatalogContextSeed()
|
||||
.SeedAsync(context, env, settings, logger)
|
||||
.Wait();
|
||||
})
|
||||
.MigrateDbContext<IntegrationEventLogContext>((_, __) => { });
|
||||
|
||||
return testServer;
|
||||
}
|
||||
|
||||
public static class Get
|
||||
{
|
||||
public static string Orders = "api/v1/orders";
|
||||
|
||||
public static string Items = "api/v1/catalog/items";
|
||||
|
||||
public static string ProductByName(string name)
|
||||
var hostBuilder = new WebHostBuilder()
|
||||
.UseContentRoot(Path.GetDirectoryName(path))
|
||||
.ConfigureAppConfiguration(cb =>
|
||||
{
|
||||
return $"api/v1/catalog/items/withname/{name}";
|
||||
}
|
||||
}
|
||||
cb.AddJsonFile("Services/Catalog/appsettings.json", optional: false)
|
||||
.AddEnvironmentVariables();
|
||||
}).UseStartup<Startup>();
|
||||
|
||||
public static class Put
|
||||
var testServer = new TestServer(hostBuilder);
|
||||
|
||||
testServer.Host
|
||||
.MigrateDbContext<CatalogContext>((context, services) =>
|
||||
{
|
||||
var env = services.GetService<IWebHostEnvironment>();
|
||||
var settings = services.GetService<IOptions<CatalogSettings>>();
|
||||
var logger = services.GetService<ILogger<CatalogContextSeed>>();
|
||||
|
||||
new CatalogContextSeed()
|
||||
.SeedAsync(context, env, settings, logger)
|
||||
.Wait();
|
||||
})
|
||||
.MigrateDbContext<IntegrationEventLogContext>((_, __) => { });
|
||||
|
||||
return testServer;
|
||||
}
|
||||
|
||||
public static class Get
|
||||
{
|
||||
public static string Orders = "api/v1/orders";
|
||||
|
||||
public static string Items = "api/v1/catalog/items";
|
||||
|
||||
public static string ProductByName(string name)
|
||||
{
|
||||
public static string UpdateCatalogProduct = "api/v1/catalog/items";
|
||||
return $"api/v1/catalog/items/withname/{name}";
|
||||
}
|
||||
}
|
||||
|
||||
public static class Put
|
||||
{
|
||||
public static string UpdateCatalogProduct = "api/v1/catalog/items";
|
||||
}
|
||||
}
|
||||
|
@ -1,134 +1,122 @@
|
||||
using FunctionalTests.Services.Basket;
|
||||
using FunctionalTests.Services.Catalog;
|
||||
namespace FunctionalTests.Services;
|
||||
using Microsoft.eShopOnContainers.Services.Basket.API.Model;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace FunctionalTests.Services
|
||||
public class IntegrationEventsScenarios
|
||||
{
|
||||
public class IntegrationEventsScenarios
|
||||
[Fact]
|
||||
public async Task Post_update_product_price_and_catalog_and_basket_list_modified()
|
||||
{
|
||||
[Fact]
|
||||
public async Task Post_update_product_price_and_catalog_and_basket_list_modified()
|
||||
decimal priceModification = 0.15M;
|
||||
string userId = "JohnId";
|
||||
|
||||
using (var catalogServer = new CatalogScenariosBase().CreateServer())
|
||||
using (var basketServer = new BasketScenariosBase().CreateServer())
|
||||
{
|
||||
decimal priceModification = 0.15M;
|
||||
string userId = "JohnId";
|
||||
var catalogClient = catalogServer.CreateClient();
|
||||
var basketClient = basketServer.CreateClient();
|
||||
|
||||
using (var catalogServer = new CatalogScenariosBase().CreateServer())
|
||||
using (var basketServer = new BasketScenariosBase().CreateServer())
|
||||
// GIVEN a product catalog list
|
||||
var originalCatalogProducts = await GetCatalogAsync(catalogClient);
|
||||
|
||||
// AND a user basket filled with products
|
||||
var basket = ComposeBasket(userId, originalCatalogProducts.Data.Take(3));
|
||||
var res = await basketClient.PostAsync(
|
||||
BasketScenariosBase.Post.CreateBasket,
|
||||
new StringContent(JsonSerializer.Serialize(basket), UTF8Encoding.UTF8, "application/json")
|
||||
);
|
||||
|
||||
// WHEN the price of one product is modified in the catalog
|
||||
var itemToModify = basket.Items[2];
|
||||
var oldPrice = itemToModify.UnitPrice;
|
||||
var newPrice = oldPrice + priceModification;
|
||||
var pRes = await catalogClient.PutAsync(CatalogScenariosBase.Put.UpdateCatalogProduct, new StringContent(ChangePrice(itemToModify, newPrice, originalCatalogProducts), UTF8Encoding.UTF8, "application/json"));
|
||||
|
||||
var modifiedCatalogProducts = await GetCatalogAsync(catalogClient);
|
||||
|
||||
var itemUpdated = await GetUpdatedBasketItem(newPrice, itemToModify.ProductId, userId, basketClient);
|
||||
|
||||
if (itemUpdated == null)
|
||||
{
|
||||
var catalogClient = catalogServer.CreateClient();
|
||||
var basketClient = basketServer.CreateClient();
|
||||
Assert.False(true, $"The basket service has not been updated.");
|
||||
}
|
||||
else
|
||||
{
|
||||
//THEN the product price changes in the catalog
|
||||
Assert.Equal(newPrice, modifiedCatalogProducts.Data.Single(it => it.Id == itemToModify.ProductId).Price);
|
||||
|
||||
// GIVEN a product catalog list
|
||||
var originalCatalogProducts = await GetCatalogAsync(catalogClient);
|
||||
|
||||
// AND a user basket filled with products
|
||||
var basket = ComposeBasket(userId, originalCatalogProducts.Data.Take(3));
|
||||
var res = await basketClient.PostAsync(
|
||||
BasketScenariosBase.Post.CreateBasket,
|
||||
new StringContent(JsonSerializer.Serialize(basket), UTF8Encoding.UTF8, "application/json")
|
||||
);
|
||||
|
||||
// WHEN the price of one product is modified in the catalog
|
||||
var itemToModify = basket.Items[2];
|
||||
var oldPrice = itemToModify.UnitPrice;
|
||||
var newPrice = oldPrice + priceModification;
|
||||
var pRes = await catalogClient.PutAsync(CatalogScenariosBase.Put.UpdateCatalogProduct, new StringContent(ChangePrice(itemToModify, newPrice, originalCatalogProducts), UTF8Encoding.UTF8, "application/json"));
|
||||
|
||||
var modifiedCatalogProducts = await GetCatalogAsync(catalogClient);
|
||||
|
||||
var itemUpdated = await GetUpdatedBasketItem(newPrice, itemToModify.ProductId, userId, basketClient);
|
||||
|
||||
if (itemUpdated == null)
|
||||
{
|
||||
Assert.False(true, $"The basket service has not been updated.");
|
||||
}
|
||||
else
|
||||
{
|
||||
//THEN the product price changes in the catalog
|
||||
Assert.Equal(newPrice, modifiedCatalogProducts.Data.Single(it => it.Id == itemToModify.ProductId).Price);
|
||||
|
||||
// AND the products in the basket reflects the changed priced and the original price
|
||||
Assert.Equal(newPrice, itemUpdated.UnitPrice);
|
||||
Assert.Equal(oldPrice, itemUpdated.OldUnitPrice);
|
||||
}
|
||||
// AND the products in the basket reflects the changed priced and the original price
|
||||
Assert.Equal(newPrice, itemUpdated.UnitPrice);
|
||||
Assert.Equal(oldPrice, itemUpdated.OldUnitPrice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<BasketItem> GetUpdatedBasketItem(decimal newPrice, int productId, string userId, HttpClient basketClient)
|
||||
private async Task<BasketItem> GetUpdatedBasketItem(decimal newPrice, int productId, string userId, HttpClient basketClient)
|
||||
{
|
||||
bool continueLoop = true;
|
||||
var counter = 0;
|
||||
BasketItem itemUpdated = null;
|
||||
|
||||
while (continueLoop && counter < 20)
|
||||
{
|
||||
bool continueLoop = true;
|
||||
var counter = 0;
|
||||
BasketItem itemUpdated = null;
|
||||
|
||||
while (continueLoop && counter < 20)
|
||||
{
|
||||
//get the basket and verify that the price of the modified product is updated
|
||||
var basketGetResponse = await basketClient.GetAsync(BasketScenariosBase.Get.GetBasketByCustomer(userId));
|
||||
var basketUpdated = JsonSerializer.Deserialize<CustomerBasket>(await basketGetResponse.Content.ReadAsStringAsync(), new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
|
||||
itemUpdated = basketUpdated.Items.Single(pr => pr.ProductId == productId);
|
||||
|
||||
if (itemUpdated.UnitPrice == newPrice)
|
||||
{
|
||||
continueLoop = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
counter++;
|
||||
await Task.Delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
return itemUpdated;
|
||||
}
|
||||
|
||||
private async Task<PaginatedItemsViewModel<CatalogItem>> GetCatalogAsync(HttpClient catalogClient)
|
||||
{
|
||||
var response = await catalogClient.GetAsync(CatalogScenariosBase.Get.Items);
|
||||
var items = await response.Content.ReadAsStringAsync();
|
||||
return JsonSerializer.Deserialize<PaginatedItemsViewModel<CatalogItem>>(items, new JsonSerializerOptions
|
||||
//get the basket and verify that the price of the modified product is updated
|
||||
var basketGetResponse = await basketClient.GetAsync(BasketScenariosBase.Get.GetBasketByCustomer(userId));
|
||||
var basketUpdated = JsonSerializer.Deserialize<CustomerBasket>(await basketGetResponse.Content.ReadAsStringAsync(), new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
}
|
||||
|
||||
private string ChangePrice(BasketItem itemToModify, decimal newPrice, PaginatedItemsViewModel<CatalogItem> catalogProducts)
|
||||
{
|
||||
var catalogProduct = catalogProducts.Data.Single(pr => pr.Id == itemToModify.ProductId);
|
||||
catalogProduct.Price = newPrice;
|
||||
return JsonSerializer.Serialize(catalogProduct);
|
||||
}
|
||||
itemUpdated = basketUpdated.Items.Single(pr => pr.ProductId == productId);
|
||||
|
||||
private CustomerBasket ComposeBasket(string customerId, IEnumerable<CatalogItem> items)
|
||||
{
|
||||
var basket = new CustomerBasket(customerId);
|
||||
foreach (var item in items)
|
||||
if (itemUpdated.UnitPrice == newPrice)
|
||||
{
|
||||
basket.Items.Add(new BasketItem()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
UnitPrice = item.Price,
|
||||
PictureUrl = item.PictureUri,
|
||||
ProductId = item.Id,
|
||||
OldUnitPrice = 0,
|
||||
ProductName = item.Name,
|
||||
Quantity = 1
|
||||
});
|
||||
continueLoop = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
counter++;
|
||||
await Task.Delay(100);
|
||||
}
|
||||
return basket;
|
||||
}
|
||||
|
||||
return itemUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<PaginatedItemsViewModel<CatalogItem>> GetCatalogAsync(HttpClient catalogClient)
|
||||
{
|
||||
var response = await catalogClient.GetAsync(CatalogScenariosBase.Get.Items);
|
||||
var items = await response.Content.ReadAsStringAsync();
|
||||
return JsonSerializer.Deserialize<PaginatedItemsViewModel<CatalogItem>>(items, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
}
|
||||
|
||||
private string ChangePrice(BasketItem itemToModify, decimal newPrice, PaginatedItemsViewModel<CatalogItem> catalogProducts)
|
||||
{
|
||||
var catalogProduct = catalogProducts.Data.Single(pr => pr.Id == itemToModify.ProductId);
|
||||
catalogProduct.Price = newPrice;
|
||||
return JsonSerializer.Serialize(catalogProduct);
|
||||
}
|
||||
|
||||
private CustomerBasket ComposeBasket(string customerId, IEnumerable<CatalogItem> items)
|
||||
{
|
||||
var basket = new CustomerBasket(customerId);
|
||||
foreach (var item in items)
|
||||
{
|
||||
basket.Items.Add(new BasketItem()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
UnitPrice = item.Price,
|
||||
PictureUrl = item.PictureUri,
|
||||
ProductId = item.Id,
|
||||
OldUnitPrice = 0,
|
||||
ProductName = item.Name,
|
||||
Quantity = 1
|
||||
});
|
||||
}
|
||||
return basket;
|
||||
}
|
||||
}
|
||||
|
@ -1,156 +1,141 @@
|
||||
using FunctionalTests.Extensions;
|
||||
using FunctionalTests.Services.Basket;
|
||||
using Microsoft.eShopOnContainers.Services.Basket.API.Model;
|
||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WebMVC.Services.ModelDTOs;
|
||||
using Xunit;
|
||||
namespace FunctionalTests.Services.Ordering;
|
||||
|
||||
namespace FunctionalTests.Services.Ordering
|
||||
public class OrderingScenarios : OrderingScenariosBase
|
||||
{
|
||||
public class OrderingScenarios : OrderingScenariosBase
|
||||
[Fact]
|
||||
public async Task Cancel_basket_and_check_order_status_cancelled()
|
||||
{
|
||||
[Fact]
|
||||
public async Task Cancel_basket_and_check_order_status_cancelled()
|
||||
using (var orderServer = new OrderingScenariosBase().CreateServer())
|
||||
using (var basketServer = new BasketScenariosBase().CreateServer())
|
||||
{
|
||||
using (var orderServer = new OrderingScenariosBase().CreateServer())
|
||||
using (var basketServer = new BasketScenariosBase().CreateServer())
|
||||
{
|
||||
// Expected data
|
||||
var cityExpected = $"city-{Guid.NewGuid()}";
|
||||
var orderStatusExpected = "cancelled";
|
||||
// Expected data
|
||||
var cityExpected = $"city-{Guid.NewGuid()}";
|
||||
var orderStatusExpected = "cancelled";
|
||||
|
||||
var basketClient = basketServer.CreateIdempotentClient();
|
||||
var orderClient = orderServer.CreateIdempotentClient();
|
||||
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);
|
||||
// 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.CheckoutOrder, new StringContent(BuildCheckout(cityExpected), UTF8Encoding.UTF8, "application/json"));
|
||||
// AND basket checkout is sent
|
||||
await basketClient.PostAsync(BasketScenariosBase.Post.CheckoutOrder, new StringContent(BuildCheckout(cityExpected), UTF8Encoding.UTF8, "application/json"));
|
||||
|
||||
// WHEN Order is created in Ordering.api
|
||||
var newOrder = await TryGetNewOrderCreated(cityExpected, orderClient);
|
||||
// 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 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 TryGetOrder(newOrder.OrderNumber, orderClient);
|
||||
// AND the requested order is retrieved
|
||||
var order = await TryGetOrder(newOrder.OrderNumber, orderClient);
|
||||
|
||||
// THEN check status
|
||||
Assert.Equal(orderStatusExpected, order.Status);
|
||||
}
|
||||
// THEN check status
|
||||
Assert.Equal(orderStatusExpected, order.Status);
|
||||
}
|
||||
}
|
||||
|
||||
async Task<Order> TryGetOrder(string orderNumber, HttpClient orderClient)
|
||||
async Task<Order> TryGetOrder(string orderNumber, HttpClient orderClient)
|
||||
{
|
||||
var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenariosBase.Get.Orders);
|
||||
var orders = JsonSerializer.Deserialize<List<Order>>(ordersGetResponse, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
|
||||
return orders.Single(o => o.OrderNumber == orderNumber);
|
||||
}
|
||||
|
||||
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 = JsonSerializer.Deserialize<List<Order>>(ordersGetResponse, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
|
||||
return orders.Single(o => o.OrderNumber == orderNumber);
|
||||
}
|
||||
|
||||
private async Task<Order> TryGetNewOrderCreated(string city, HttpClient orderClient)
|
||||
{
|
||||
var counter = 0;
|
||||
Order order = null;
|
||||
|
||||
while (counter < 20)
|
||||
if (orders == null || orders.Count == 0)
|
||||
{
|
||||
//get the orders and verify that the new order has been created
|
||||
var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenariosBase.Get.Orders);
|
||||
var orders = JsonSerializer.Deserialize<List<Order>>(ordersGetResponse, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
|
||||
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 = JsonSerializer.Deserialize<Order>(orderDetails, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
|
||||
order.City = city;
|
||||
|
||||
if (IsOrderCreated(order, city))
|
||||
{
|
||||
break;
|
||||
}
|
||||
counter++;
|
||||
await Task.Delay(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
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>()
|
||||
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 = JsonSerializer.Deserialize<Order>(orderDetails, new JsonSerializerOptions
|
||||
{
|
||||
new Microsoft.eShopOnContainers.Services.Basket.API.Model.BasketItem()
|
||||
{
|
||||
Id = "1",
|
||||
ProductName = "ProductName",
|
||||
ProductId = 1,
|
||||
UnitPrice = 10,
|
||||
Quantity = 1
|
||||
}
|
||||
};
|
||||
return JsonSerializer.Serialize(order);
|
||||
}
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
|
||||
order.City = city;
|
||||
|
||||
string BuildCancelOrder(string orderId)
|
||||
{
|
||||
var order = new OrderDTO()
|
||||
if (IsOrderCreated(order, city))
|
||||
{
|
||||
OrderNumber = orderId
|
||||
};
|
||||
return JsonSerializer.Serialize(order);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string BuildCheckout(string cityExpected)
|
||||
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>()
|
||||
{
|
||||
var checkoutBasket = new BasketDTO()
|
||||
new Microsoft.eShopOnContainers.Services.Basket.API.Model.BasketItem()
|
||||
{
|
||||
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()
|
||||
};
|
||||
Id = "1",
|
||||
ProductName = "ProductName",
|
||||
ProductId = 1,
|
||||
UnitPrice = 10,
|
||||
Quantity = 1
|
||||
}
|
||||
};
|
||||
return JsonSerializer.Serialize(order);
|
||||
}
|
||||
|
||||
return JsonSerializer.Serialize(checkoutBasket);
|
||||
}
|
||||
string BuildCancelOrder(string orderId)
|
||||
{
|
||||
var order = new OrderDTO()
|
||||
{
|
||||
OrderNumber = orderId
|
||||
};
|
||||
return JsonSerializer.Serialize(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 JsonSerializer.Serialize(checkoutBasket);
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +1,63 @@
|
||||
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;
|
||||
using System.Reflection;
|
||||
namespace FunctionalTests.Services.Ordering;
|
||||
|
||||
namespace FunctionalTests.Services.Ordering
|
||||
public class OrderingScenariosBase
|
||||
{
|
||||
public class OrderingScenariosBase
|
||||
public TestServer CreateServer()
|
||||
{
|
||||
public TestServer CreateServer()
|
||||
{
|
||||
var path = Assembly.GetAssembly(typeof(OrderingScenariosBase))
|
||||
.Location;
|
||||
var path = Assembly.GetAssembly(typeof(OrderingScenariosBase))
|
||||
.Location;
|
||||
|
||||
var hostBuilder = new WebHostBuilder()
|
||||
.UseContentRoot(Path.GetDirectoryName(path))
|
||||
.ConfigureAppConfiguration(cb =>
|
||||
{
|
||||
cb.AddJsonFile("Services/Ordering/appsettings.json", optional: false)
|
||||
.AddEnvironmentVariables();
|
||||
}).UseStartup<OrderingTestsStartup>();
|
||||
|
||||
var testServer = new TestServer(hostBuilder);
|
||||
|
||||
testServer.Host
|
||||
.MigrateDbContext<OrderingContext>((context, services) =>
|
||||
{
|
||||
var env = services.GetService<IWebHostEnvironment>();
|
||||
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)
|
||||
var hostBuilder = new WebHostBuilder()
|
||||
.UseContentRoot(Path.GetDirectoryName(path))
|
||||
.ConfigureAppConfiguration(cb =>
|
||||
{
|
||||
return $"api/v1/orders/{id}";
|
||||
}
|
||||
}
|
||||
cb.AddJsonFile("Services/Ordering/appsettings.json", optional: false)
|
||||
.AddEnvironmentVariables();
|
||||
}).UseStartup<OrderingTestsStartup>();
|
||||
|
||||
public static class Post
|
||||
{
|
||||
public static string AddNewOrder = "api/v1/orders/new";
|
||||
}
|
||||
var testServer = new TestServer(hostBuilder);
|
||||
|
||||
public static class Put
|
||||
{
|
||||
public static string CancelOrder = "api/v1/orders/cancel";
|
||||
}
|
||||
|
||||
public static class Delete
|
||||
{
|
||||
public static string OrderBy(int id)
|
||||
testServer.Host
|
||||
.MigrateDbContext<OrderingContext>((context, services) =>
|
||||
{
|
||||
return $"api/v1/orders/{id}";
|
||||
}
|
||||
var env = services.GetService<IWebHostEnvironment>();
|
||||
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 class Delete
|
||||
{
|
||||
public static string OrderBy(int id)
|
||||
{
|
||||
return $"api/v1/orders/{id}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,22 @@
|
||||
using FunctionalTests.Middleware;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
namespace FunctionalTests.Services.Ordering;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.API;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace FunctionalTests.Services.Ordering
|
||||
public class OrderingTestsStartup : Startup
|
||||
{
|
||||
public class OrderingTestsStartup : Startup
|
||||
public OrderingTestsStartup(IConfiguration env) : base(env)
|
||||
{
|
||||
public OrderingTestsStartup(IConfiguration env) : base(env)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ConfigureAuth(IApplicationBuilder app)
|
||||
protected override void ConfigureAuth(IApplicationBuilder app)
|
||||
{
|
||||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
|
||||
{
|
||||
if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
|
||||
{
|
||||
app.UseMiddleware<AutoAuthorizeMiddleware>();
|
||||
app.UseAuthorization();
|
||||
}
|
||||
else
|
||||
{
|
||||
base.ConfigureAuth(app);
|
||||
}
|
||||
app.UseMiddleware<AutoAuthorizeMiddleware>();
|
||||
app.UseAuthorization();
|
||||
}
|
||||
else
|
||||
{
|
||||
base.ConfigureAuth(app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user