Browse Source

Fix ordering and basked scenarios

davidfowl/common-services
David Fowler 1 year ago
committed by Reuben Bond
parent
commit
c7edd50b38
8 changed files with 84 additions and 58 deletions
  1. +11
    -11
      src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs
  2. +6
    -0
      src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs
  3. +0
    -4
      src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj
  4. +9
    -12
      src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs
  5. +7
    -4
      src/Services/Ordering/Ordering.API/Program.cs
  6. +6
    -1
      src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj
  7. +43
    -24
      src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs
  8. +2
    -2
      src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs

+ 11
- 11
src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs View File

@ -10,21 +10,21 @@ namespace Microsoft.AspNetCore.Hosting
{
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");
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();
var services = scope.ServiceProvider;
var logger = services.GetRequiredService<ILogger<TContext>>();
var context = services.GetService<TContext>();
using var scope = services.CreateScope();
var scopeServices = scope.ServiceProvider;
var logger = scopeServices.GetRequiredService<ILogger<TContext>>();
var context = scopeServices.GetService<TContext>();
try
{
@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Hosting
if (underK8s)
{
InvokeSeeder(seeder, context, services);
InvokeSeeder(seeder, context, scopeServices);
}
else
{
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Hosting
//migration can't fail for network related exception. The retry options for DbContext only
//apply to transient exceptions
// 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);
@ -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)


+ 6
- 0
src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs View File

@ -6,6 +6,12 @@ namespace Basket.FunctionalTests.Base;
public class BasketScenarioBase : WebApplicationFactory<Program>
{
private const string ApiUrlBase = "api/v1/basket";
public TestServer CreateServer()
{
return Server;
}
public static class Get
{
public static string GetBasket(int id)


+ 0
- 4
src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj View File

@ -6,10 +6,6 @@
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<None Remove="appsettings.json" />
</ItemGroup>
<ItemGroup>
<Content Include="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>


+ 9
- 12
src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs View File

@ -1,20 +1,15 @@
namespace Basket.FunctionalTests;
public class BasketScenarios : BasketScenarioBase
public class BasketScenarios :
BasketScenarioBase
{
private readonly HttpClient _httpClient;
public BasketScenarios()
{
_httpClient = CreateClient();
}
[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 uri = "/api/v1/basket/";
var response = await _httpClient.PostAsync(uri, content);
var response = await server.CreateClient().PostAsync(uri, content);
response.EnsureSuccessStatusCode();
}
@ -22,7 +17,8 @@ public class BasketScenarios : BasketScenarioBase
[Fact]
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));
response.EnsureSuccessStatusCode();
}
@ -30,9 +26,10 @@ public class BasketScenarios : BasketScenarioBase
[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 _httpClient
await server.CreateClient()
.PostAsync(Post.Basket, contentBasket);
var contentCheckout = new StringContent(BuildCheckout(), UTF8Encoding.UTF8, "application/json")
@ -40,7 +37,7 @@ public class BasketScenarios : BasketScenarioBase
Headers = { { "x-requestid", Guid.NewGuid().ToString() } }
};
var response = await _httpClient
var response = await server.CreateClient()
.PostAsync(Post.CheckoutOrder, contentCheckout);
response.EnsureSuccessStatusCode();


+ 7
- 4
src/Services/Ordering/Ordering.API/Program.cs View File

@ -331,7 +331,7 @@ static class CustomExtensionsMethods
public static IServiceCollection AddCustomSwagger(this IServiceCollection services, IConfiguration configuration)
{
services.AddSwaggerGen(options =>
return services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
@ -339,6 +339,9 @@ static class CustomExtensionsMethods
Version = "v1",
Description = "The Ordering Service HTTP API"
});
var identityUrl = configuration["IdentityUrlExternal"];
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
@ -346,8 +349,8 @@ static class CustomExtensionsMethods
{
Implicit = new OpenApiOAuthFlow()
{
AuthorizationUrl = new Uri($"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize"),
TokenUrl = new Uri($"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/token"),
AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"),
TokenUrl = new Uri($"{identityUrl}/connect/token"),
Scopes = new Dictionary<string, string>()
{
{ "orders", "Ordering API" }
@ -355,9 +358,9 @@ static class CustomExtensionsMethods
}
}
});
options.OperationFilter<AuthorizeCheckOperationFilter>();
});
return services;
}
public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration)


+ 6
- 1
src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj View File

@ -6,6 +6,12 @@
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<Content Include="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
@ -18,7 +24,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Web\WebMVC\WebMVC.csproj" />
<ProjectReference Include="..\Ordering.API\Ordering.API.csproj" />
<ProjectReference Include="..\Ordering.Domain\Ordering.Domain.csproj" />
<ProjectReference Include="..\Ordering.Infrastructure\Ordering.Infrastructure.csproj" />


+ 43
- 24
src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs View File

@ -1,36 +1,42 @@
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()
{
var path = Assembly.GetAssembly(typeof(OrderingScenarioBase))
.Location;
Services.MigrateDbContext<OrderingContext>((context, services) =>
{
var env = services.GetService<IWebHostEnvironment>();
var settings = services.GetService<IOptions<OrderingSettings>>();
var logger = services.GetService<ILogger<OrderingContextSeed>>();
var hostBuilder = new WebHostBuilder()
.UseContentRoot(Path.GetDirectoryName(path))
.ConfigureAppConfiguration(cb =>
{
cb.AddJsonFile("appsettings.json", optional: false)
.AddEnvironmentVariables();
});
new OrderingContextSeed()
.SeedAsync(context, env, settings, logger)
.Wait();
})
.MigrateDbContext<IntegrationEventLogContext>((_, __) => { });
return Server;
}
var testServer = new TestServer(hostBuilder);
protected override IHost CreateHost(IHostBuilder builder)
{
builder.ConfigureServices(servies =>
{
servies.AddSingleton<IStartupFilter, AuthStartupFilter>();
});
testServer.Host
.MigrateDbContext<OrderingContext>((context, services) =>
{
var env = services.GetService<IWebHostEnvironment>();
var settings = services.GetService<IOptions<OrderingSettings>>();
var logger = services.GetService<ILogger<OrderingContextSeed>>();
builder.ConfigureAppConfiguration(c =>
{
var directory = Path.GetDirectoryName(typeof(OrderingScenarioBase).Assembly.Location)!;
new OrderingContextSeed()
.SeedAsync(context, env, settings, logger)
.Wait();
})
.MigrateDbContext<IntegrationEventLogContext>((_, __) => { });
c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false);
});
return testServer;
return base.CreateHost(builder);
}
public static class Get
@ -48,4 +54,17 @@ public class OrderingScenarioBase
public static string CancelOrder = "api/v1/orders/cancel";
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);
};
}
}
}

+ 2
- 2
src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs View File

@ -1,7 +1,6 @@
using System.Net;
using System.Text;
using System.Text.Json;
using WebMVC.Services.ModelDTOs;
using Xunit;
namespace Ordering.FunctionalTests
@ -16,6 +15,7 @@ namespace Ordering.FunctionalTests
var response = await server.CreateClient()
.GetAsync(Get.Orders);
var s = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode();
}
@ -49,7 +49,7 @@ namespace Ordering.FunctionalTests
string BuildOrder()
{
var order = new OrderDTO()
var order = new
{
OrderNumber = "-1"
};


Loading…
Cancel
Save