Fix ordering and basked scenarios
This commit is contained in:
parent
2736eae13e
commit
2b0889f684
@ -10,21 +10,21 @@ namespace Microsoft.AspNetCore.Hosting
|
|||||||
{
|
{
|
||||||
public static class IWebHostExtensions
|
public static class IWebHostExtensions
|
||||||
{
|
{
|
||||||
public static bool IsInKubernetes(this IWebHost webHost)
|
public static bool IsInKubernetes(this IServiceProvider services)
|
||||||
{
|
{
|
||||||
var cfg = webHost.Services.GetService<IConfiguration>();
|
var cfg = services.GetService<IConfiguration>();
|
||||||
var orchestratorType = cfg.GetValue<string>("OrchestratorType");
|
var orchestratorType = cfg.GetValue<string>("OrchestratorType");
|
||||||
return orchestratorType?.ToUpper() == "K8S";
|
return orchestratorType?.ToUpper() == "K8S";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IWebHost MigrateDbContext<TContext>(this IWebHost webHost, Action<TContext, IServiceProvider> seeder) where TContext : DbContext
|
public static IServiceProvider MigrateDbContext<TContext>(this IServiceProvider services, Action<TContext, IServiceProvider> seeder) where TContext : DbContext
|
||||||
{
|
{
|
||||||
var underK8s = webHost.IsInKubernetes();
|
var underK8s = services.IsInKubernetes();
|
||||||
|
|
||||||
using var scope = webHost.Services.CreateScope();
|
using var scope = services.CreateScope();
|
||||||
var services = scope.ServiceProvider;
|
var scopeServices = scope.ServiceProvider;
|
||||||
var logger = services.GetRequiredService<ILogger<TContext>>();
|
var logger = scopeServices.GetRequiredService<ILogger<TContext>>();
|
||||||
var context = services.GetService<TContext>();
|
var context = scopeServices.GetService<TContext>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Hosting
|
|||||||
|
|
||||||
if (underK8s)
|
if (underK8s)
|
||||||
{
|
{
|
||||||
InvokeSeeder(seeder, context, services);
|
InvokeSeeder(seeder, context, scopeServices);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Hosting
|
|||||||
//migration can't fail for network related exception. The retry options for DbContext only
|
//migration can't fail for network related exception. The retry options for DbContext only
|
||||||
//apply to transient exceptions
|
//apply to transient exceptions
|
||||||
// Note that this is NOT applied when running some orchestrators (let the orchestrator to recreate the failing service)
|
// Note that this is NOT applied when running some orchestrators (let the orchestrator to recreate the failing service)
|
||||||
retry.Execute(() => InvokeSeeder(seeder, context, services));
|
retry.Execute(() => InvokeSeeder(seeder, context, scopeServices));
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.LogInformation("Migrated database associated with context {DbContextName}", typeof(TContext).Name);
|
logger.LogInformation("Migrated database associated with context {DbContextName}", typeof(TContext).Name);
|
||||||
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Hosting
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return webHost;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InvokeSeeder<TContext>(Action<TContext, IServiceProvider> seeder, TContext context, IServiceProvider services)
|
private static void InvokeSeeder<TContext>(Action<TContext, IServiceProvider> seeder, TContext context, IServiceProvider services)
|
||||||
|
@ -6,6 +6,12 @@ namespace Basket.FunctionalTests.Base;
|
|||||||
public class BasketScenarioBase : WebApplicationFactory<Program>
|
public class BasketScenarioBase : WebApplicationFactory<Program>
|
||||||
{
|
{
|
||||||
private const string ApiUrlBase = "api/v1/basket";
|
private const string ApiUrlBase = "api/v1/basket";
|
||||||
|
|
||||||
|
public TestServer CreateServer()
|
||||||
|
{
|
||||||
|
return Server;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Get
|
public static class Get
|
||||||
{
|
{
|
||||||
public static string GetBasket(int id)
|
public static string GetBasket(int id)
|
||||||
|
@ -6,10 +6,6 @@
|
|||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Remove="appsettings.json" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="appsettings.json">
|
<Content Include="appsettings.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
namespace Basket.FunctionalTests;
|
namespace Basket.FunctionalTests;
|
||||||
|
|
||||||
public class BasketScenarios : BasketScenarioBase
|
public class BasketScenarios :
|
||||||
|
BasketScenarioBase
|
||||||
{
|
{
|
||||||
private readonly HttpClient _httpClient;
|
|
||||||
|
|
||||||
public BasketScenarios()
|
|
||||||
{
|
|
||||||
_httpClient = CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Post_basket_and_response_ok_status_code()
|
public async Task Post_basket_and_response_ok_status_code()
|
||||||
{
|
{
|
||||||
|
using var server = CreateServer();
|
||||||
var content = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json");
|
var content = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json");
|
||||||
var uri = "/api/v1/basket/";
|
var uri = "/api/v1/basket/";
|
||||||
var response = await _httpClient.PostAsync(uri, content);
|
var response = await server.CreateClient().PostAsync(uri, content);
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
@ -22,7 +17,8 @@ public class BasketScenarios : BasketScenarioBase
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task Get_basket_and_response_ok_status_code()
|
public async Task Get_basket_and_response_ok_status_code()
|
||||||
{
|
{
|
||||||
var response = await _httpClient
|
using var server = CreateServer();
|
||||||
|
var response = await server.CreateClient()
|
||||||
.GetAsync(Get.GetBasket(1));
|
.GetAsync(Get.GetBasket(1));
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
@ -30,9 +26,10 @@ public class BasketScenarios : BasketScenarioBase
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task Send_Checkout_basket_and_response_ok_status_code()
|
public async Task Send_Checkout_basket_and_response_ok_status_code()
|
||||||
{
|
{
|
||||||
|
using var server = CreateServer();
|
||||||
var contentBasket = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json");
|
var contentBasket = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
await _httpClient
|
await server.CreateClient()
|
||||||
.PostAsync(Post.Basket, contentBasket);
|
.PostAsync(Post.Basket, contentBasket);
|
||||||
|
|
||||||
var contentCheckout = new StringContent(BuildCheckout(), UTF8Encoding.UTF8, "application/json")
|
var contentCheckout = new StringContent(BuildCheckout(), UTF8Encoding.UTF8, "application/json")
|
||||||
@ -40,7 +37,7 @@ public class BasketScenarios : BasketScenarioBase
|
|||||||
Headers = { { "x-requestid", Guid.NewGuid().ToString() } }
|
Headers = { { "x-requestid", Guid.NewGuid().ToString() } }
|
||||||
};
|
};
|
||||||
|
|
||||||
var response = await _httpClient
|
var response = await server.CreateClient()
|
||||||
.PostAsync(Post.CheckoutOrder, contentCheckout);
|
.PostAsync(Post.CheckoutOrder, contentCheckout);
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
|
@ -331,7 +331,7 @@ static class CustomExtensionsMethods
|
|||||||
|
|
||||||
public static IServiceCollection AddCustomSwagger(this IServiceCollection services, IConfiguration configuration)
|
public static IServiceCollection AddCustomSwagger(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
services.AddSwaggerGen(options =>
|
return services.AddSwaggerGen(options =>
|
||||||
{
|
{
|
||||||
options.SwaggerDoc("v1", new OpenApiInfo
|
options.SwaggerDoc("v1", new OpenApiInfo
|
||||||
{
|
{
|
||||||
@ -339,6 +339,9 @@ static class CustomExtensionsMethods
|
|||||||
Version = "v1",
|
Version = "v1",
|
||||||
Description = "The Ordering Service HTTP API"
|
Description = "The Ordering Service HTTP API"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var identityUrl = configuration["IdentityUrlExternal"];
|
||||||
|
|
||||||
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
|
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
|
||||||
{
|
{
|
||||||
Type = SecuritySchemeType.OAuth2,
|
Type = SecuritySchemeType.OAuth2,
|
||||||
@ -346,8 +349,8 @@ static class CustomExtensionsMethods
|
|||||||
{
|
{
|
||||||
Implicit = new OpenApiOAuthFlow()
|
Implicit = new OpenApiOAuthFlow()
|
||||||
{
|
{
|
||||||
AuthorizationUrl = new Uri($"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize"),
|
AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"),
|
||||||
TokenUrl = new Uri($"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/token"),
|
TokenUrl = new Uri($"{identityUrl}/connect/token"),
|
||||||
Scopes = new Dictionary<string, string>()
|
Scopes = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "orders", "Ordering API" }
|
{ "orders", "Ordering API" }
|
||||||
@ -355,9 +358,9 @@ static class CustomExtensionsMethods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
options.OperationFilter<AuthorizeCheckOperationFilter>();
|
options.OperationFilter<AuthorizeCheckOperationFilter>();
|
||||||
});
|
});
|
||||||
return services;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration)
|
public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
@ -6,6 +6,12 @@
|
|||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="appsettings.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||||
@ -18,7 +24,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\Web\WebMVC\WebMVC.csproj" />
|
|
||||||
<ProjectReference Include="..\Ordering.API\Ordering.API.csproj" />
|
<ProjectReference Include="..\Ordering.API\Ordering.API.csproj" />
|
||||||
<ProjectReference Include="..\Ordering.Domain\Ordering.Domain.csproj" />
|
<ProjectReference Include="..\Ordering.Domain\Ordering.Domain.csproj" />
|
||||||
<ProjectReference Include="..\Ordering.Infrastructure\Ordering.Infrastructure.csproj" />
|
<ProjectReference Include="..\Ordering.Infrastructure\Ordering.Infrastructure.csproj" />
|
||||||
|
@ -1,24 +1,13 @@
|
|||||||
namespace Ordering.FunctionalTests;
|
using Microsoft.AspNetCore.Mvc.Testing;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
public class OrderingScenarioBase
|
namespace Ordering.FunctionalTests;
|
||||||
|
|
||||||
|
public class OrderingScenarioBase : WebApplicationFactory<Program>
|
||||||
{
|
{
|
||||||
public TestServer CreateServer()
|
public TestServer CreateServer()
|
||||||
{
|
{
|
||||||
var path = Assembly.GetAssembly(typeof(OrderingScenarioBase))
|
Services.MigrateDbContext<OrderingContext>((context, services) =>
|
||||||
.Location;
|
|
||||||
|
|
||||||
var hostBuilder = new WebHostBuilder()
|
|
||||||
.UseContentRoot(Path.GetDirectoryName(path))
|
|
||||||
.ConfigureAppConfiguration(cb =>
|
|
||||||
{
|
|
||||||
cb.AddJsonFile("appsettings.json", optional: false)
|
|
||||||
.AddEnvironmentVariables();
|
|
||||||
});
|
|
||||||
|
|
||||||
var testServer = new TestServer(hostBuilder);
|
|
||||||
|
|
||||||
testServer.Host
|
|
||||||
.MigrateDbContext<OrderingContext>((context, services) =>
|
|
||||||
{
|
{
|
||||||
var env = services.GetService<IWebHostEnvironment>();
|
var env = services.GetService<IWebHostEnvironment>();
|
||||||
var settings = services.GetService<IOptions<OrderingSettings>>();
|
var settings = services.GetService<IOptions<OrderingSettings>>();
|
||||||
@ -30,7 +19,24 @@ public class OrderingScenarioBase
|
|||||||
})
|
})
|
||||||
.MigrateDbContext<IntegrationEventLogContext>((_, __) => { });
|
.MigrateDbContext<IntegrationEventLogContext>((_, __) => { });
|
||||||
|
|
||||||
return testServer;
|
return Server;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IHost CreateHost(IHostBuilder builder)
|
||||||
|
{
|
||||||
|
builder.ConfigureServices(servies =>
|
||||||
|
{
|
||||||
|
servies.AddSingleton<IStartupFilter, AuthStartupFilter>();
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.ConfigureAppConfiguration(c =>
|
||||||
|
{
|
||||||
|
var directory = Path.GetDirectoryName(typeof(OrderingScenarioBase).Assembly.Location)!;
|
||||||
|
|
||||||
|
c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false);
|
||||||
|
});
|
||||||
|
|
||||||
|
return base.CreateHost(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Get
|
public static class Get
|
||||||
@ -48,4 +54,17 @@ public class OrderingScenarioBase
|
|||||||
public static string CancelOrder = "api/v1/orders/cancel";
|
public static string CancelOrder = "api/v1/orders/cancel";
|
||||||
public static string ShipOrder = "api/v1/orders/ship";
|
public static string ShipOrder = "api/v1/orders/ship";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class AuthStartupFilter : IStartupFilter
|
||||||
|
{
|
||||||
|
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
|
||||||
|
{
|
||||||
|
return app =>
|
||||||
|
{
|
||||||
|
app.UseMiddleware<AutoAuthorizeMiddleware>();
|
||||||
|
|
||||||
|
next(app);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using WebMVC.Services.ModelDTOs;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ordering.FunctionalTests
|
namespace Ordering.FunctionalTests
|
||||||
@ -16,6 +15,7 @@ namespace Ordering.FunctionalTests
|
|||||||
var response = await server.CreateClient()
|
var response = await server.CreateClient()
|
||||||
.GetAsync(Get.Orders);
|
.GetAsync(Get.Orders);
|
||||||
|
|
||||||
|
var s = await response.Content.ReadAsStringAsync();
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ namespace Ordering.FunctionalTests
|
|||||||
|
|
||||||
string BuildOrder()
|
string BuildOrder()
|
||||||
{
|
{
|
||||||
var order = new OrderDTO()
|
var order = new
|
||||||
{
|
{
|
||||||
OrderNumber = "-1"
|
OrderNumber = "-1"
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user