Browse Source

Add Identity sections to config and consume (likely broken). Simplify integration tests

davidfowl/common-services
Reuben Bond 1 year ago
parent
commit
16b63001df
26 changed files with 95 additions and 316 deletions
  1. +3
    -2
      src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs
  2. +4
    -0
      src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json
  3. +4
    -2
      src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json
  4. +3
    -2
      src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs
  5. +4
    -0
      src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json
  6. +0
    -2
      src/Services/Basket/Basket.API/appsettings.Development.json
  7. +2
    -0
      src/Services/Basket/Basket.API/appsettings.json
  8. +5
    -0
      src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs
  9. +8
    -0
      src/Services/Catalog/Catalog.API/appsettings.json
  10. +5
    -0
      src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs
  11. +5
    -1
      src/Services/Catalog/Catalog.FunctionalTests/appsettings.json
  12. +1
    -1
      src/Services/Ordering/Ordering.API/Program.cs
  13. +6
    -2
      src/Services/Ordering/Ordering.API/appsettings.json
  14. +3
    -2
      src/Services/Webhooks/Webhooks.API/Startup.cs
  15. +3
    -11
      src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj
  16. +1
    -20
      src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs
  17. +0
    -66
      src/Tests/Services/Application.FunctionalTests/Services/Basket/BasketScenariosBase.cs
  18. +0
    -16
      src/Tests/Services/Application.FunctionalTests/Services/Basket/appsettings.json
  19. +0
    -55
      src/Tests/Services/Application.FunctionalTests/Services/Catalog/CatalogScenariosBase.cs
  20. +0
    -9
      src/Tests/Services/Application.FunctionalTests/Services/Catalog/appsettings.json
  21. +7
    -4
      src/Tests/Services/Application.FunctionalTests/Services/IntegrationEventsScenarios.cs
  22. +0
    -85
      src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenariosBase.cs
  23. +0
    -11
      src/Tests/Services/Application.FunctionalTests/Services/Ordering/appsettings.json
  24. +14
    -10
      src/Tests/Services/Application.FunctionalTests/Services/OrderingScenarios.cs
  25. +13
    -11
      src/docker-compose.override.yml
  26. +4
    -4
      src/docker-compose.prod.yml

+ 3
- 2
src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs View File

@ -92,6 +92,7 @@ public static class ServiceCollectionExtensions
Version = "v1", Version = "v1",
Description = "Shopping Aggregator for Mobile Clients" Description = "Shopping Aggregator for Mobile Clients"
}); });
var identityUrl = configuration.GetSection("Identity").GetValue<string>("ExternalUrl");
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{ {
Type = SecuritySchemeType.OAuth2, Type = SecuritySchemeType.OAuth2,
@ -99,8 +100,8 @@ public static class ServiceCollectionExtensions
{ {
Implicit = new OpenApiOAuthFlow() 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>() Scopes = new Dictionary<string, string>()
{ {


+ 4
- 0
src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json View File

@ -1,4 +1,8 @@
{ {
"Identity": {
"Url": "http://localhost:5105",
"Audience": "mobileshoppingagg"
},
"Logging": { "Logging": {
"Debug": { "Debug": {
"IncludeScopes": false, "IncludeScopes": false,


+ 4
- 2
src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json View File

@ -8,8 +8,10 @@
"grpcCatalog": "http://localhost:81", "grpcCatalog": "http://localhost:81",
"grpcOrdering": "http://localhost:5581" "grpcOrdering": "http://localhost:5581"
}, },
"IdentityUrlExternal": "http://localhost:5105",
"IdentityUrl": "http://localhost:5105",
"Identity": {
"ExternalUrl": "http://localhost:5105",
"Url": "http://localhost:5105",
},
"Logging": { "Logging": {
"Debug": { "Debug": {
"IncludeScopes": false, "IncludeScopes": false,


+ 3
- 2
src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs View File

@ -96,6 +96,7 @@ public static class ServiceCollectionExtensions
Version = "v1", Version = "v1",
Description = "Shopping Aggregator for Web Clients" Description = "Shopping Aggregator for Web Clients"
}); });
var identityUrl = configuration.GetSection("Identity").GetValue<string>("ExternalUrl");
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{ {
Type = SecuritySchemeType.OAuth2, Type = SecuritySchemeType.OAuth2,
@ -103,8 +104,8 @@ public static class ServiceCollectionExtensions
{ {
Implicit = new OpenApiOAuthFlow() 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>() Scopes = new Dictionary<string, string>()
{ {
{ "webshoppingagg", "Shopping Aggregator for Web Clients" } { "webshoppingagg", "Shopping Aggregator for Web Clients" }


+ 4
- 0
src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json View File

@ -1,4 +1,8 @@
{ {
"Identity": {
"Url": "http://localhost:5105",
"Audience": "webshoppingagg"
},
"Logging": { "Logging": {
"Debug": { "Debug": {
"IncludeScopes": false, "IncludeScopes": false,


+ 0
- 2
src/Services/Basket/Basket.API/appsettings.Development.json View File

@ -1,6 +1,4 @@
{ {
"IdentityUrlExternal": "http://localhost:5105",
"IdentityUrl": "http://localhost:5105",
"ConnectionString": "127.0.0.1", "ConnectionString": "127.0.0.1",
"AzureServiceBusEnabled": false, "AzureServiceBusEnabled": false,
"EventBusConnection": "localhost" "EventBusConnection": "localhost"

+ 2
- 0
src/Services/Basket/Basket.API/appsettings.json View File

@ -25,6 +25,8 @@
}, },
"Identity": { "Identity": {
"Audience": "basket", "Audience": "basket",
"Url": "http://localhost:5105",
"ExternalUrl": "http://localhost:5105",
"Scopes": { "Scopes": {
"basket": "Basket API" "basket": "Basket API"
} }


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

@ -19,6 +19,11 @@ public class BasketScenarioBase
{ {
return $"{ApiUrlBase}/{id}"; return $"{ApiUrlBase}/{id}";
} }
public static string GetBasketByCustomer(string customerId)
{
return $"{ApiUrlBase}/{customerId}";
}
} }
public static class Post public static class Post


+ 8
- 0
src/Services/Catalog/Catalog.API/appsettings.json View File

@ -5,6 +5,14 @@
"ApplicationInsights": { "ApplicationInsights": {
"InstrumentationKey": "" "InstrumentationKey": ""
}, },
"Identity": {
"Url": "http://localhost:5105",
"ExternalUrl": "http://localhost:5105",
"Audience": "catalog",
"Scopes": {
"catalog": "Catalog API"
}
},
"OpenApi": { "OpenApi": {
"Endpoint": { "Endpoint": {
"Name": "" "Name": ""


+ 5
- 0
src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs View File

@ -83,4 +83,9 @@ public class CatalogScenariosBase
return $"?pageIndex={pageIndex}&pageSize={pageCount}"; return $"?pageIndex={pageIndex}&pageSize={pageCount}";
} }
} }
public static class Put
{
public static string UpdateCatalogProduct = "api/v1/catalog/items";
}
} }

+ 5
- 1
src/Services/Catalog/Catalog.FunctionalTests/appsettings.json View File

@ -1,6 +1,10 @@
{ {
"ExternalCatalogBaseUrl": "http://localhost:5101", "ExternalCatalogBaseUrl": "http://localhost:5101",
"IdentityUrl": "http://localhost:5105",
"Identity": {
"Url": "http://localhost:5105",
"ExternalUrl": "http://localhost:5105",
"Audience": "catalog"
},
"isTest": "true", "isTest": "true",
"PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/", "PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/",


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

@ -255,7 +255,7 @@ static class CustomExtensionsMethods
Description = "The Ordering Service HTTP API" Description = "The Ordering Service HTTP API"
}); });
var identityUrl = configuration["IdentityUrlExternal"];
var identityUrl = configuration.GetSection("Identity")["ExternalUrl"];
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{ {


+ 6
- 2
src/Services/Ordering/Ordering.API/appsettings.json View File

@ -1,6 +1,10 @@
{ {
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;TrustServerCertificate=true", "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;TrustServerCertificate=true",
"IdentityUrl": "http://localhost:5105",
"Identity": {
"Url": "http://localhost:5105",
"ExternalUrl": "http://localhost:5105",
"Audience": "orders"
},
"UseCustomizationData": false, "UseCustomizationData": false,
"AzureServiceBusEnabled": false, "AzureServiceBusEnabled": false,
"SubscriptionClientName": "Ordering", "SubscriptionClientName": "Ordering",
@ -17,4 +21,4 @@
"ClientId": "your-client-id", "ClientId": "your-client-id",
"ClientSecret": "your-client-secret" "ClientSecret": "your-client-secret"
} }
}
}

+ 3
- 2
src/Services/Webhooks/Webhooks.API/Startup.cs View File

@ -142,6 +142,7 @@ internal static class CustomExtensionMethods
Description = "The Webhooks Microservice HTTP API. This is a simple webhooks CRUD registration entrypoint" Description = "The Webhooks Microservice HTTP API. This is a simple webhooks CRUD registration entrypoint"
}); });
var identityUrl = configuration.GetSection("Identity").GetValue<string>("ExternalUrl");
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{ {
Type = SecuritySchemeType.OAuth2, Type = SecuritySchemeType.OAuth2,
@ -149,8 +150,8 @@ internal static class CustomExtensionMethods
{ {
Implicit = new OpenApiOAuthFlow() 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>() Scopes = new Dictionary<string, string>()
{ {
{ "webhooks", "Webhooks API" } { "webhooks", "Webhooks API" }


+ 3
- 11
src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj View File

@ -11,12 +11,10 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Remove="Services\Basket\appsettings.json" />
<None Remove="Setup\CatalogBrands.csv" /> <None Remove="Setup\CatalogBrands.csv" />
<None Remove="Setup\CatalogItems.csv" /> <None Remove="Setup\CatalogItems.csv" />
<None Remove="Setup\CatalogItems.zip" /> <None Remove="Setup\CatalogItems.zip" />
<None Remove="Setup\CatalogTypes.csv" /> <None Remove="Setup\CatalogTypes.csv" />
<None Remove="Services\Ordering\appsettings.json" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -32,15 +30,6 @@
<Content Include="Setup\CatalogTypes.csv"> <Content Include="Setup\CatalogTypes.csv">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Include="Services\Ordering\appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Services\Basket\appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Services\Catalog\appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -56,8 +45,11 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\Services\Basket\Basket.API\Basket.API.csproj" /> <ProjectReference Include="..\..\..\Services\Basket\Basket.API\Basket.API.csproj" />
<ProjectReference Include="..\..\..\Services\Basket\Basket.FunctionalTests\Basket.FunctionalTests.csproj" />
<ProjectReference Include="..\..\..\Services\Catalog\Catalog.API\Catalog.API.csproj" /> <ProjectReference Include="..\..\..\Services\Catalog\Catalog.API\Catalog.API.csproj" />
<ProjectReference Include="..\..\..\Services\Catalog\Catalog.FunctionalTests\Catalog.FunctionalTests.csproj" />
<ProjectReference Include="..\..\..\Services\Ordering\Ordering.API\Ordering.API.csproj" /> <ProjectReference Include="..\..\..\Services\Ordering\Ordering.API\Ordering.API.csproj" />
<ProjectReference Include="..\..\..\Services\Ordering\Ordering.FunctionalTests\Ordering.FunctionalTests.csproj" />
<ProjectReference Include="..\..\..\Web\WebMVC\WebMVC.csproj" /> <ProjectReference Include="..\..\..\Web\WebMVC\WebMVC.csproj" />
</ItemGroup> </ItemGroup>


+ 1
- 20
src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs View File

@ -1,19 +1,8 @@
global using Microsoft.AspNetCore.TestHost;
global using System;
global using System;
global using System.Net.Http; global using System.Net.Http;
global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Http;
global using System.Security.Claims; global using System.Security.Claims;
global using System.Threading.Tasks; global using System.Threading.Tasks;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.Extensions.Configuration;
global using System.IO;
global using System.Reflection;
global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging;
global using Microsoft.Extensions.Options;
global using FunctionalTests.Services.Basket;
global using Microsoft.eShopOnContainers.Services.Basket.API.Model; global using Microsoft.eShopOnContainers.Services.Basket.API.Model;
global using Microsoft.eShopOnContainers.WebMVC.ViewModels; global using Microsoft.eShopOnContainers.WebMVC.ViewModels;
global using System.Text.Json; global using System.Text.Json;
@ -22,12 +11,4 @@ global using System.Linq;
global using System.Text; global using System.Text;
global using WebMVC.Services.ModelDTOs; global using WebMVC.Services.ModelDTOs;
global using Xunit; global using Xunit;
global using Microsoft.eShopOnContainers.Services.Ordering.API;
global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure;
global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
global using FunctionalTests.Services.Catalog;
// This is a bit of a hack, since we need to differentiate each of these app's program
global using BasketProgram = Microsoft.eShopOnContainers.Services.Basket.API.BasketSettings;
global using CatalogProgram = Microsoft.eShopOnContainers.Services.Catalog.API.CatalogSettings;
global using OrderingProgram = Microsoft.eShopOnContainers.Services.Ordering.API.OrderingSettings;

+ 0
- 66
src/Tests/Services/Application.FunctionalTests/Services/Basket/BasketScenariosBase.cs View File

@ -1,66 +0,0 @@
using FunctionalTests.Middleware;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Hosting;
namespace FunctionalTests.Services.Basket;
public class BasketScenariosBase : WebApplicationFactory<BasketProgram>
{
private const string ApiUrlBase = "api/v1/basket";
public TestServer CreateServer()
{
return Server;
}
protected override IHost CreateHost(IHostBuilder builder)
{
builder.ConfigureServices(servies =>
{
servies.AddSingleton<IStartupFilter, AuthStartupFilter>();
});
builder.ConfigureAppConfiguration(c =>
{
var directory = Path.GetDirectoryName(typeof(BasketScenariosBase).Assembly.Location)!;
c.AddJsonFile(Path.Combine(directory, "Services/Basket/appsettings.json"), optional: false);
});
return base.CreateHost(builder);
}
public static class Get
{
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";
}
private class AuthStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return app =>
{
app.UseMiddleware<AutoAuthorizeMiddleware>();
next(app);
};
}
}
}

+ 0
- 16
src/Tests/Services/Application.FunctionalTests/Services/Basket/appsettings.json View File

@ -1,16 +0,0 @@
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"IdentityUrl": "http://localhost:5105",
"IdentityUrlExternal": "http://localhost:5105",
"ConnectionString": "127.0.0.1",
"isTest": "true",
"EventBusConnection": "localhost",
"SubscriptionClientName": "Basket"
}

+ 0
- 55
src/Tests/Services/Application.FunctionalTests/Services/Catalog/CatalogScenariosBase.cs View File

@ -1,55 +0,0 @@
namespace FunctionalTests.Services.Catalog;
using FunctionalTests.Services.Ordering;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.eShopOnContainers.Services.Catalog.API;
using Microsoft.Extensions.Hosting;
public class CatalogScenariosBase : WebApplicationFactory<CatalogProgram>
{
public TestServer CreateServer()
{
Services.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 Server;
}
protected override IHost CreateHost(IHostBuilder builder)
{
builder.ConfigureAppConfiguration(c =>
{
var directory = Path.GetDirectoryName(typeof(CatalogScenariosBase).Assembly.Location)!;
c.AddJsonFile(Path.Combine(directory, "Services/Catalog/appsettings.json"), optional: false);
});
return base.CreateHost(builder);
}
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)
{
return $"api/v1/catalog/items/withname/{name}";
}
}
public static class Put
{
public static string UpdateCatalogProduct = "api/v1/catalog/items";
}
}

+ 0
- 9
src/Tests/Services/Application.FunctionalTests/Services/Catalog/appsettings.json View File

@ -1,9 +0,0 @@
{
"ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true",
"ExternalCatalogBaseUrl": "http://localhost:5101",
"IdentityUrl": "http://localhost:5105",
"isTest": "true",
"EventBusConnection": "localhost",
"PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/",
"SubscriptionClientName": "Catalog"
}

+ 7
- 4
src/Tests/Services/Application.FunctionalTests/Services/IntegrationEventsScenarios.cs View File

@ -1,4 +1,7 @@
namespace FunctionalTests.Services; namespace FunctionalTests.Services;
using global::Basket.FunctionalTests.Base;
using global::Catalog.FunctionalTests;
using Microsoft.eShopOnContainers.Services.Basket.API.Model; using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Microsoft.eShopOnContainers.Services.Catalog.API.Model; using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel; using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
@ -12,7 +15,7 @@ public class IntegrationEventsScenarios
string userId = "JohnId"; string userId = "JohnId";
using var catalogServer = new CatalogScenariosBase().CreateServer(); using var catalogServer = new CatalogScenariosBase().CreateServer();
using var basketServer = new BasketScenariosBase().CreateServer();
using var basketServer = new BasketScenarioBase().CreateServer();
var catalogClient = catalogServer.CreateClient(); var catalogClient = catalogServer.CreateClient();
var basketClient = basketServer.CreateClient(); var basketClient = basketServer.CreateClient();
@ -22,7 +25,7 @@ public class IntegrationEventsScenarios
// AND a user basket filled with products // AND a user basket filled with products
var basket = ComposeBasket(userId, originalCatalogProducts.Data.Take(3)); var basket = ComposeBasket(userId, originalCatalogProducts.Data.Take(3));
var res = await basketClient.PostAsync( var res = await basketClient.PostAsync(
BasketScenariosBase.Post.CreateBasket,
BasketScenarioBase.Post.Basket,
new StringContent(JsonSerializer.Serialize(basket), UTF8Encoding.UTF8, "application/json") new StringContent(JsonSerializer.Serialize(basket), UTF8Encoding.UTF8, "application/json")
); );
@ -60,7 +63,7 @@ public class IntegrationEventsScenarios
while (continueLoop && counter < 20) while (continueLoop && counter < 20)
{ {
//get the basket and verify that the price of the modified product is updated //get the basket and verify that the price of the modified product is updated
var basketGetResponse = await basketClient.GetAsync(BasketScenariosBase.Get.GetBasketByCustomer(userId));
var basketGetResponse = await basketClient.GetAsync(BasketScenarioBase.Get.GetBasketByCustomer(userId));
var basketUpdated = JsonSerializer.Deserialize<CustomerBasket>(await basketGetResponse.Content.ReadAsStringAsync(), new JsonSerializerOptions var basketUpdated = JsonSerializer.Deserialize<CustomerBasket>(await basketGetResponse.Content.ReadAsStringAsync(), new JsonSerializerOptions
{ {
PropertyNameCaseInsensitive = true PropertyNameCaseInsensitive = true
@ -84,7 +87,7 @@ public class IntegrationEventsScenarios
private async Task<PaginatedItemsViewModel<CatalogItem>> GetCatalogAsync(HttpClient catalogClient) private async Task<PaginatedItemsViewModel<CatalogItem>> GetCatalogAsync(HttpClient catalogClient)
{ {
var response = await catalogClient.GetAsync(CatalogScenariosBase.Get.Items);
var response = await catalogClient.GetAsync(CatalogScenariosBase.Get.Items(paginated: false));
var items = await response.Content.ReadAsStringAsync(); var items = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<PaginatedItemsViewModel<CatalogItem>>(items, new JsonSerializerOptions return JsonSerializer.Deserialize<PaginatedItemsViewModel<CatalogItem>>(items, new JsonSerializerOptions
{ {


+ 0
- 85
src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenariosBase.cs View File

@ -1,85 +0,0 @@
using FunctionalTests.Middleware;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Hosting;
namespace FunctionalTests.Services.Ordering;
public class OrderingScenariosBase : WebApplicationFactory<OrderingProgram>
{
public TestServer CreateServer()
{
Services
.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 Server;
}
protected override IHost CreateHost(IHostBuilder builder)
{
builder.ConfigureServices(servies =>
{
servies.AddSingleton<IStartupFilter, AuthStartupFilter>();
});
builder.ConfigureAppConfiguration(c =>
{
var directory = Path.GetDirectoryName(typeof(OrderingScenariosBase).Assembly.Location)!;
c.AddJsonFile(Path.Combine(directory, "Services/Ordering/appsettings.json"), optional: false);
});
return base.CreateHost(builder);
}
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}";
}
}
private class AuthStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return app =>
{
app.UseMiddleware<AutoAuthorizeMiddleware>();
next(app);
};
}
}
}

+ 0
- 11
src/Tests/Services/Application.FunctionalTests/Services/Ordering/appsettings.json View File

@ -1,11 +0,0 @@
{
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true",
"ExternalCatalogBaseUrl": "http://localhost:5101",
"IdentityUrl": "http://localhost:5105",
"isTest": "true",
"EventBusConnection": "localhost",
"CheckUpdateTime": "30000",
"GracePeriodTime": "1",
"SubscriptionClientName": "Ordering",
"IdentityUrlExternal": "http://localhost:5105"
}

src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenarios.cs → src/Tests/Services/Application.FunctionalTests/Services/OrderingScenarios.cs View File

@ -1,12 +1,15 @@
namespace FunctionalTests.Services.Ordering;
using Basket.FunctionalTests.Base;
using Ordering.FunctionalTests;
public class OrderingScenarios : OrderingScenariosBase
namespace FunctionalTests.Services.Ordering;
public class OrderingScenarios
{ {
[Fact] [Fact]
public async Task Cancel_basket_and_check_order_status_cancelled() 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 OrderingScenarioBase().CreateServer();
using var basketServer = new BasketScenarioBase().CreateServer();
// Expected data // Expected data
var cityExpected = $"city-{Guid.NewGuid()}"; var cityExpected = $"city-{Guid.NewGuid()}";
var orderStatusExpected = "cancelled"; var orderStatusExpected = "cancelled";
@ -19,11 +22,11 @@ public class OrderingScenarios : OrderingScenariosBase
{ {
Headers = { { "x-requestid", Guid.NewGuid().ToString() } } Headers = { { "x-requestid", Guid.NewGuid().ToString() } }
}; };
await basketClient.PostAsync(BasketScenariosBase.Post.CreateBasket, contentBasket);
await basketClient.PostAsync(BasketScenarioBase.Post.Basket, contentBasket);
// AND basket checkout is sent // AND basket checkout is sent
await basketClient.PostAsync( await basketClient.PostAsync(
BasketScenariosBase.Post.CheckoutOrder,
BasketScenarioBase.Post.CheckoutOrder,
new StringContent(BuildCheckout(cityExpected), UTF8Encoding.UTF8, "application/json") new StringContent(BuildCheckout(cityExpected), UTF8Encoding.UTF8, "application/json")
{ {
Headers = { { "x-requestid", Guid.NewGuid().ToString() } } Headers = { { "x-requestid", Guid.NewGuid().ToString() } }
@ -31,9 +34,10 @@ public class OrderingScenarios : OrderingScenariosBase
// WHEN Order is created in Ordering.api // WHEN Order is created in Ordering.api
var newOrder = await TryGetNewOrderCreated(cityExpected, orderClient); var newOrder = await TryGetNewOrderCreated(cityExpected, orderClient);
Assert.NotNull(newOrder);
// AND Order is cancelled in Ordering.api // AND Order is cancelled in Ordering.api
await orderClient.PutAsync(OrderingScenariosBase.Put.CancelOrder, new StringContent(BuildCancelOrder(newOrder.OrderNumber), UTF8Encoding.UTF8, "application/json")
await orderClient.PutAsync(OrderingScenarioBase.Put.CancelOrder, new StringContent(BuildCancelOrder(newOrder.OrderNumber), UTF8Encoding.UTF8, "application/json")
{ {
Headers = { { "x-requestid", Guid.NewGuid().ToString() } } Headers = { { "x-requestid", Guid.NewGuid().ToString() } }
}); });
@ -47,7 +51,7 @@ public class OrderingScenarios : OrderingScenariosBase
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 ordersGetResponse = await orderClient.GetStringAsync(OrderingScenarioBase.Get.Orders);
var orders = JsonSerializer.Deserialize<List<Order>>(ordersGetResponse, new JsonSerializerOptions var orders = JsonSerializer.Deserialize<List<Order>>(ordersGetResponse, new JsonSerializerOptions
{ {
PropertyNameCaseInsensitive = true PropertyNameCaseInsensitive = true
@ -64,7 +68,7 @@ public class OrderingScenarios : OrderingScenariosBase
while (counter < 20) while (counter < 20)
{ {
//get the orders and verify that the new order has been created //get the orders and verify that the new order has been created
var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenariosBase.Get.Orders);
var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenarioBase.Get.Orders);
var orders = JsonSerializer.Deserialize<List<Order>>(ordersGetResponse, new JsonSerializerOptions var orders = JsonSerializer.Deserialize<List<Order>>(ordersGetResponse, new JsonSerializerOptions
{ {
PropertyNameCaseInsensitive = true PropertyNameCaseInsensitive = true
@ -79,7 +83,7 @@ public class OrderingScenarios : OrderingScenariosBase
var lastOrder = orders.OrderByDescending(o => o.Date).First(); var lastOrder = orders.OrderByDescending(o => o.Date).First();
int.TryParse(lastOrder.OrderNumber, out int id); int.TryParse(lastOrder.OrderNumber, out int id);
var orderDetails = await orderClient.GetStringAsync(OrderingScenariosBase.Get.OrderBy(id));
var orderDetails = await orderClient.GetStringAsync(OrderingScenarioBase.Get.OrderBy(id));
order = JsonSerializer.Deserialize<Order>(orderDetails, new JsonSerializerOptions order = JsonSerializer.Deserialize<Order>(orderDetails, new JsonSerializerOptions
{ {
PropertyNameCaseInsensitive = true PropertyNameCaseInsensitive = true

+ 13
- 11
src/docker-compose.override.yml View File

@ -63,8 +63,8 @@ services:
- ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80 - ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basketdata} - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basketdata}
- identityUrl=http://identity-api
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__Url=http://identity-api
- Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
@ -106,8 +106,8 @@ services:
- ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80 - ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true}
- identityUrl=http://identity-api
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__Url=http://identity-api
- Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
@ -163,8 +163,8 @@ services:
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
- IdentityUrl=http://identity-api
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__Url=http://identity-api
- Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
ports: ports:
- "5113:80" - "5113:80"
@ -197,7 +197,8 @@ services:
- IdentityUrlHC=http://identity-api/hc - IdentityUrlHC=http://identity-api/hc
- BasketUrlHC=http://basket-api/hc - BasketUrlHC=http://basket-api/hc
- PaymentUrlHC=http://payment-api/hc - PaymentUrlHC=http://payment-api/hc
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__Url=http://identity-api
- Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
ports: ports:
- "5120:80" - "5120:80"
@ -216,7 +217,8 @@ services:
- IdentityUrlHC=http://identity-api/hc - IdentityUrlHC=http://identity-api/hc
- BasketUrlHC=http://basket-api/hc - BasketUrlHC=http://basket-api/hc
- PaymentUrlHC=http://payment-api/hc - PaymentUrlHC=http://payment-api/hc
- IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__Url=http://identity-api
- Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
ports: ports:
- "5121:80" - "5121:80"
@ -269,7 +271,7 @@ services:
environment: environment:
- ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://0.0.0.0:80 - ASPNETCORE_URLS=http://0.0.0.0:80
- IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- PurchaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202 - PurchaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
- IdentityUrlHC=http://identity-api/hc - IdentityUrlHC=http://identity-api/hc
- UseCustomizationData=True - UseCustomizationData=True
@ -284,7 +286,7 @@ services:
- ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80 - ASPNETCORE_URLS=http://0.0.0.0:80
- PurchaseUrl=http://webshoppingapigw - PurchaseUrl=http://webshoppingapigw
- IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202 - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
- IdentityUrlHC=http://identity-api/hc - IdentityUrlHC=http://identity-api/hc
- UseCustomizationData=True - UseCustomizationData=True
@ -298,7 +300,7 @@ services:
environment: environment:
- ASPNETCORE_URLS=http://0.0.0.0:80 - ASPNETCORE_URLS=http://0.0.0.0:80
- Token=6168DB8D-DC58-4094-AF24-483278923590 # Webhooks are registered with this token (any value is valid) but the client won't check it - Token=6168DB8D-DC58-4094-AF24-483278923590 # Webhooks are registered with this token (any value is valid) but the client won't check it
- IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- CallBackUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5114 - CallBackUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5114
- WebhooksUrl=http://webhooks-api - WebhooksUrl=http://webhooks-api
- SelfUrl=http://webhooks-client/ - SelfUrl=http://webhooks-client/


+ 4
- 4
src/docker-compose.prod.yml View File

@ -21,7 +21,7 @@ services:
- ASPNETCORE_URLS=http://0.0.0.0:80 - ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basket.data} - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basket.data}
- identityUrl=http://identity-api #Local: You need to open your local dev-machine firewall at range 5100-5110. - identityUrl=http://identity-api #Local: You need to open your local dev-machine firewall at range 5100-5110.
- IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
@ -75,8 +75,8 @@ services:
- ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80 - ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word} - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word}
- identityUrl=http://identity-api #Local: You need to open your local dev-machine firewall at range 5100-5110.
- IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- Identity__ExternalUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105
- EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
- EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
- EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
@ -111,7 +111,7 @@ services:
environment: environment:
- ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80 - ASPNETCORE_URLS=http://0.0.0.0:80
- IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
- Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
- PurchaseUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5202 - PurchaseUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5202
- CatalogUrlHC=http://catalog-api/hc - CatalogUrlHC=http://catalog-api/hc
- OrderingUrlHC=http://ordering-api/hc - OrderingUrlHC=http://ordering-api/hc


Loading…
Cancel
Save