mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-05-04 11:58:46 +08:00
Merge pull request #68 from meysamhadeli/develop
add some end-to-end tests
This commit is contained in:
commit
5e679b7c55
@ -65,6 +65,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Ser
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unit.Test", "src\Services\Flight\tests\UnitTest\Unit.Test.csproj", "{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unit.Test", "src\Services\Flight\tests\UnitTest\Unit.Test.csproj", "{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EndToEnd.Test", "src\Services\Flight\tests\EndToEndTest\EndToEnd.Test.csproj", "{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -102,6 +104,7 @@ Global
|
|||||||
{539364C8-88B1-48A3-8406-D0B19FF30509} = {C1EBE17D-BFAD-47DA-88EB-BB073B84593E}
|
{539364C8-88B1-48A3-8406-D0B19FF30509} = {C1EBE17D-BFAD-47DA-88EB-BB073B84593E}
|
||||||
{50C66B53-ACA0-4AFF-8C5C-834D4EDA8FAC} = {5185D5C5-0EAD-49D5-B405-93B939F3639B}
|
{50C66B53-ACA0-4AFF-8C5C-834D4EDA8FAC} = {5185D5C5-0EAD-49D5-B405-93B939F3639B}
|
||||||
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8} = {C6EE337B-91EA-472A-87C7-E9528408CE59}
|
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8} = {C6EE337B-91EA-472A-87C7-E9528408CE59}
|
||||||
|
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB} = {C6EE337B-91EA-472A-87C7-E9528408CE59}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{A2D7C5C4-5148-4C3E-BB12-B7A197A290F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A2D7C5C4-5148-4C3E-BB12-B7A197A290F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
@ -164,5 +167,9 @@ Global
|
|||||||
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}.Release|Any CPU.Build.0 = Release|Any CPU
|
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@ -1,14 +1,18 @@
|
|||||||
using Microsoft.AspNetCore.Authentication;
|
using System.Security.Claims;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace BuildingBlocks.TestBase.EndToEndTest.Auth;
|
namespace BuildingBlocks.TestBase.Auth;
|
||||||
|
|
||||||
//ref: https://blog.joaograssi.com/posts/2021/asp-net-core-testing-permission-protected-api-endpoints/
|
//ref: https://blog.joaograssi.com/posts/2021/asp-net-core-testing-permission-protected-api-endpoints/
|
||||||
public static class AuthServiceCollectionExtensions
|
public static class AuthServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
public static AuthenticationBuilder AddTestAuthentication(
|
private static MockAuthUser GetMockUser() =>
|
||||||
this IServiceCollection services)
|
new MockAuthUser(new Claim("sub", Guid.NewGuid().ToString()),
|
||||||
|
new Claim("email", "sam@test.com"));
|
||||||
|
|
||||||
|
public static AuthenticationBuilder AddTestAuthentication(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddAuthorization(options =>
|
services.AddAuthorization(options =>
|
||||||
{
|
{
|
||||||
@ -18,6 +22,9 @@ public static class AuthServiceCollectionExtensions
|
|||||||
.Build();
|
.Build();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Register a default user, so all requests have it by default
|
||||||
|
services.AddScoped(_ => GetMockUser());
|
||||||
|
|
||||||
// Register our custom authentication handler
|
// Register our custom authentication handler
|
||||||
return services.AddAuthentication("Test")
|
return services.AddAuthentication("Test")
|
||||||
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>("Test", options => { });
|
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>("Test", options => { });
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace BuildingBlocks.TestBase.EndToEndTest.Auth;
|
namespace BuildingBlocks.TestBase.Auth;
|
||||||
|
|
||||||
public class MockAuthUser
|
public class MockAuthUser
|
||||||
{
|
{
|
||||||
@ -4,11 +4,13 @@ using Microsoft.AspNetCore.Authentication;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace BuildingBlocks.TestBase.EndToEndTest.Auth;
|
namespace BuildingBlocks.TestBase.Auth;
|
||||||
|
|
||||||
//ref: https://blog.joaograssi.com/posts/2021/asp-net-core-testing-permission-protected-api-endpoints/
|
//ref: https://blog.joaograssi.com/posts/2021/asp-net-core-testing-permission-protected-api-endpoints/
|
||||||
public class TestAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
public class TestAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
private readonly MockAuthUser _mockAuthUser;
|
private readonly MockAuthUser _mockAuthUser;
|
||||||
|
|
||||||
public TestAuthHandler(
|
public TestAuthHandler(
|
||||||
@ -1,46 +0,0 @@
|
|||||||
using System.Net.Http.Json;
|
|
||||||
using BuildingBlocks.Mongo;
|
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
|
||||||
using BuildingBlocks.Web;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace BuildingBlocks.TestBase.EndToEndTest;
|
|
||||||
|
|
||||||
public class EndToEndTestBase<TEntryPoint, TWContext, TRContext> :
|
|
||||||
IntegrationTestBase<TEntryPoint, TWContext, TRContext>
|
|
||||||
where TWContext : DbContext
|
|
||||||
where TRContext : MongoDbContext
|
|
||||||
where TEntryPoint : class
|
|
||||||
{
|
|
||||||
public EndToEndTestBase(
|
|
||||||
IntegrationTestFactory<TEntryPoint, TWContext, TRContext> sharedFixture,
|
|
||||||
ITestOutputHelper outputHelper = null)
|
|
||||||
: base(sharedFixture, outputHelper)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TResponse> GetAsync<TResponse>(string requestUrl, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await Fixture.HttpClient.GetFromJsonAsync<TResponse>(requestUrl, cancellationToken: cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TResponse> PostAsync<TRequest, TResponse>(string requestUrl, TRequest request,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await Fixture.HttpClient.PostAsJsonAsync<TRequest, TResponse>(requestUrl, request, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TResponse> PutAsync<TRequest, TResponse>(
|
|
||||||
string requestUrl,
|
|
||||||
TRequest request,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await Fixture.HttpClient.PutAsJsonAsync<TRequest, TResponse>(requestUrl, request, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Delete(string requestUrl, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await Fixture.HttpClient.DeleteAsync(requestUrl, cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,12 +1,11 @@
|
|||||||
using System.Security.Claims;
|
using Ardalis.GuardClauses;
|
||||||
using Ardalis.GuardClauses;
|
|
||||||
using BuildingBlocks.Core.Event;
|
using BuildingBlocks.Core.Event;
|
||||||
using BuildingBlocks.Core.Model;
|
using BuildingBlocks.Core.Model;
|
||||||
using BuildingBlocks.EFCore;
|
using BuildingBlocks.EFCore;
|
||||||
using BuildingBlocks.MassTransit;
|
using BuildingBlocks.MassTransit;
|
||||||
using BuildingBlocks.Mongo;
|
using BuildingBlocks.Mongo;
|
||||||
using BuildingBlocks.PersistMessageProcessor;
|
using BuildingBlocks.PersistMessageProcessor;
|
||||||
using BuildingBlocks.TestBase.EndToEndTest.Auth;
|
using BuildingBlocks.TestBase.Auth;
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using DotNet.Testcontainers.Containers;
|
using DotNet.Testcontainers.Containers;
|
||||||
using EasyNetQ.Management.Client;
|
using EasyNetQ.Management.Client;
|
||||||
@ -31,9 +30,9 @@ using Xunit;
|
|||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
using ILogger = Serilog.ILogger;
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
namespace BuildingBlocks.TestBase.IntegrationTest;
|
namespace BuildingBlocks.TestBase;
|
||||||
|
|
||||||
public class IntegrationTestFactory<TEntryPoint> : IAsyncLifetime
|
public class TestFactory<TEntryPoint> : IAsyncLifetime
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
{
|
{
|
||||||
private readonly WebApplicationFactory<TEntryPoint> _factory;
|
private readonly WebApplicationFactory<TEntryPoint> _factory;
|
||||||
@ -52,7 +51,7 @@ public class IntegrationTestFactory<TEntryPoint> : IAsyncLifetime
|
|||||||
public IConfiguration Configuration => _factory?.Services.GetRequiredService<IConfiguration>();
|
public IConfiguration Configuration => _factory?.Services.GetRequiredService<IConfiguration>();
|
||||||
public ILogger Logger { get; set; }
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
public IntegrationTestFactory()
|
public TestFactory()
|
||||||
{
|
{
|
||||||
_factory = new WebApplicationFactory<TEntryPoint>()
|
_factory = new WebApplicationFactory<TEntryPoint>()
|
||||||
.WithWebHostBuilder(builder =>
|
.WithWebHostBuilder(builder =>
|
||||||
@ -64,11 +63,7 @@ public class IntegrationTestFactory<TEntryPoint> : IAsyncLifetime
|
|||||||
{
|
{
|
||||||
TestRegistrationServices?.Invoke(services);
|
TestRegistrationServices?.Invoke(services);
|
||||||
services.ReplaceSingleton(AddHttpContextAccessorMock);
|
services.ReplaceSingleton(AddHttpContextAccessorMock);
|
||||||
// Add our custom handler
|
|
||||||
services.AddTestAuthentication();
|
services.AddTestAuthentication();
|
||||||
|
|
||||||
// Register a default user, so all requests have it by default
|
|
||||||
services.AddScoped(_ => GetMockUser());
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -261,13 +256,9 @@ public class IntegrationTestFactory<TEntryPoint> : IAsyncLifetime
|
|||||||
|
|
||||||
return httpContextAccessorMock;
|
return httpContextAccessorMock;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MockAuthUser GetMockUser() =>
|
|
||||||
new MockAuthUser(new Claim("sub", Guid.NewGuid().ToString()),
|
|
||||||
new Claim("email", "sam@test.com"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IntegrationTestFactory<TEntryPoint, TWContext> : IntegrationTestFactory<TEntryPoint>
|
public class TestFactory<TEntryPoint, TWContext> : TestFactory<TEntryPoint>
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
where TWContext : DbContext
|
where TWContext : DbContext
|
||||||
{
|
{
|
||||||
@ -374,7 +365,7 @@ public class IntegrationTestFactory<TEntryPoint, TWContext> : IntegrationTestFac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IntegrationTestFactory<TEntryPoint, TWContext, TRContext> : IntegrationTestFactory<TEntryPoint, TWContext>
|
public class TestFactory<TEntryPoint, TWContext, TRContext> : TestFactory<TEntryPoint, TWContext>
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
where TWContext : DbContext
|
where TWContext : DbContext
|
||||||
where TRContext : MongoDbContext
|
where TRContext : MongoDbContext
|
||||||
@ -390,7 +381,7 @@ public class IntegrationTestFactory<TEntryPoint, TWContext, TRContext> : Integra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IntegrationTestFixtureCore<TEntryPoint> : IAsyncLifetime
|
public class TestFixtureCore<TEntryPoint> : IAsyncLifetime
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
{
|
{
|
||||||
private Respawner _reSpawnerDefaultDb;
|
private Respawner _reSpawnerDefaultDb;
|
||||||
@ -398,14 +389,14 @@ public class IntegrationTestFixtureCore<TEntryPoint> : IAsyncLifetime
|
|||||||
private SqlConnection DefaultDbConnection { get; set; }
|
private SqlConnection DefaultDbConnection { get; set; }
|
||||||
private SqlConnection PersistDbConnection { get; set; }
|
private SqlConnection PersistDbConnection { get; set; }
|
||||||
|
|
||||||
public IntegrationTestFixtureCore(IntegrationTestFactory<TEntryPoint> integrationTestFixture, ITestOutputHelper outputHelper)
|
public TestFixtureCore(TestFactory<TEntryPoint> integrationTestFixture, ITestOutputHelper outputHelper)
|
||||||
{
|
{
|
||||||
Fixture = integrationTestFixture;
|
Fixture = integrationTestFixture;
|
||||||
integrationTestFixture.RegisterServices(services => RegisterTestsServices(services));
|
integrationTestFixture.RegisterServices(services => RegisterTestsServices(services));
|
||||||
integrationTestFixture.Logger = integrationTestFixture.CreateLogger(outputHelper);
|
integrationTestFixture.Logger = integrationTestFixture.CreateLogger(outputHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntegrationTestFactory<TEntryPoint> Fixture { get; }
|
public TestFactory<TEntryPoint> Fixture { get; }
|
||||||
|
|
||||||
|
|
||||||
public async Task InitializeAsync()
|
public async Task InitializeAsync()
|
||||||
@ -496,31 +487,31 @@ public class IntegrationTestFixtureCore<TEntryPoint> : IAsyncLifetime
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class IntegrationTestBase<TEntryPoint, TWContext> : IntegrationTestFixtureCore<TEntryPoint>
|
public abstract class TestBase<TEntryPoint, TWContext> : TestFixtureCore<TEntryPoint>
|
||||||
//,IClassFixture<IntegrationTestFactory<TEntryPoint, TWContext>>
|
//,IClassFixture<IntegrationTestFactory<TEntryPoint, TWContext>>
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
where TWContext : DbContext
|
where TWContext : DbContext
|
||||||
{
|
{
|
||||||
protected IntegrationTestBase(
|
protected TestBase(
|
||||||
IntegrationTestFactory<TEntryPoint, TWContext> integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper)
|
TestFactory<TEntryPoint, TWContext> integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper)
|
||||||
{
|
{
|
||||||
Fixture = integrationTestFixture;
|
Fixture = integrationTestFixture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntegrationTestFactory<TEntryPoint, TWContext> Fixture { get; }
|
public TestFactory<TEntryPoint, TWContext> Fixture { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class IntegrationTestBase<TEntryPoint, TWContext, TRContext> : IntegrationTestFixtureCore<TEntryPoint>
|
public abstract class TestBase<TEntryPoint, TWContext, TRContext> : TestFixtureCore<TEntryPoint>
|
||||||
//,IClassFixture<IntegrationTestFactory<TEntryPoint, TWContext, TRContext>>
|
//,IClassFixture<IntegrationTestFactory<TEntryPoint, TWContext, TRContext>>
|
||||||
where TEntryPoint : class
|
where TEntryPoint : class
|
||||||
where TWContext : DbContext
|
where TWContext : DbContext
|
||||||
where TRContext : MongoDbContext
|
where TRContext : MongoDbContext
|
||||||
{
|
{
|
||||||
protected IntegrationTestBase(
|
protected TestBase(
|
||||||
IntegrationTestFactory<TEntryPoint, TWContext, TRContext> integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper)
|
TestFactory<TEntryPoint, TWContext, TRContext> integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper)
|
||||||
{
|
{
|
||||||
Fixture = integrationTestFixture;
|
Fixture = integrationTestFixture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntegrationTestFactory<TEntryPoint, TWContext, TRContext> Fixture { get; }
|
public TestFactory<TEntryPoint, TWContext, TRContext> Fixture { get; }
|
||||||
}
|
}
|
||||||
@ -1,36 +0,0 @@
|
|||||||
using System.Net.Http.Json;
|
|
||||||
|
|
||||||
namespace BuildingBlocks.Web;
|
|
||||||
|
|
||||||
public static class HttpClientExtensions
|
|
||||||
{
|
|
||||||
public static async Task<TResponse>
|
|
||||||
PostAsJsonAsync<TRequest, TResponse>(
|
|
||||||
this HttpClient httpClient,
|
|
||||||
string requestUri,
|
|
||||||
TRequest request,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
var responseMessage =
|
|
||||||
await httpClient.PostAsJsonAsync(requestUri, request, cancellationToken: cancellationToken);
|
|
||||||
|
|
||||||
var result = await responseMessage.Content.ReadFromJsonAsync<TResponse>(cancellationToken: cancellationToken);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<TResponse?>
|
|
||||||
PutAsJsonAsync<TRequest, TResponse>(
|
|
||||||
this HttpClient httpClient,
|
|
||||||
string requestUri,
|
|
||||||
TRequest request,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
var responseMessage =
|
|
||||||
await httpClient.PutAsJsonAsync(requestUri, request, cancellationToken: cancellationToken);
|
|
||||||
|
|
||||||
var result = await responseMessage.Content.ReadFromJsonAsync<TResponse>(cancellationToken: cancellationToken);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -19,11 +19,11 @@ public class CreateBookingEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/booking", CreateBooking)
|
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/booking", CreateBooking)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Booking")
|
.WithTags("Booking")
|
||||||
.WithName("Create Booking")
|
.WithName("CreateBooking")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Create Booking", "Create Booking"))
|
.WithMetadata(new SwaggerOperationAttribute("Create Booking", "Create Booking"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Booking").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Booking").Build())
|
||||||
.Produces<ulong>()
|
.Produces<ulong>()
|
||||||
.Produces(StatusCodes.Status201Created)
|
.Produces(StatusCodes.Status200OK)
|
||||||
.Produces(StatusCodes.Status400BadRequest)
|
.Produces(StatusCodes.Status400BadRequest)
|
||||||
.HasApiVersion(1.0);
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,7 @@ public static class ProblemDetailsExtensions
|
|||||||
};
|
};
|
||||||
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "Application rule broken",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status409Conflict,
|
Status = StatusCodes.Status409Conflict,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/application-rule-validation-error",
|
Type = "https://somedomain/application-rule-validation-error",
|
||||||
@ -32,35 +32,35 @@ public static class ProblemDetailsExtensions
|
|||||||
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
||||||
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "input validation rules broken",
|
Title = ex.GetType().Name,
|
||||||
Status = (int)ex.StatusCode,
|
Status = (int)ex.StatusCode,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/input-validation-rules-error",
|
Type = "https://somedomain/input-validation-rules-error",
|
||||||
});
|
});
|
||||||
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "bad request exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status400BadRequest,
|
Status = StatusCodes.Status400BadRequest,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/bad-request-error",
|
Type = "https://somedomain/bad-request-error",
|
||||||
});
|
});
|
||||||
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "not found exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status404NotFound,
|
Status = StatusCodes.Status404NotFound,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/not-found-error",
|
Type = "https://somedomain/not-found-error",
|
||||||
});
|
});
|
||||||
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "api server exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status500InternalServerError,
|
Status = StatusCodes.Status500InternalServerError,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/api-server-error",
|
Type = "https://somedomain/api-server-error",
|
||||||
});
|
});
|
||||||
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "application exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status400BadRequest,
|
Status = StatusCodes.Status400BadRequest,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/application-error",
|
Type = "https://somedomain/application-error",
|
||||||
@ -69,7 +69,7 @@ public static class ProblemDetailsExtensions
|
|||||||
x.Map<RpcException>(ex => new ProblemDetails
|
x.Map<RpcException>(ex => new ProblemDetails
|
||||||
{
|
{
|
||||||
Status = StatusCodes.Status400BadRequest,
|
Status = StatusCodes.Status400BadRequest,
|
||||||
Title = "grpc exception",
|
Title = ex.GetType().Name,
|
||||||
Detail = ex.Status.Detail,
|
Detail = ex.Status.Detail,
|
||||||
Type = "https://somedomain/grpc-error"
|
Type = "https://somedomain/grpc-error"
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
using System.Linq;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Booking.Api;
|
using Booking.Api;
|
||||||
using Booking.Data;
|
using Booking.Data;
|
||||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
|
using BuildingBlocks.EFCore;
|
||||||
using BuildingBlocks.PersistMessageProcessor.Data;
|
using BuildingBlocks.PersistMessageProcessor.Data;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight;
|
using Flight;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
@ -21,7 +23,7 @@ namespace Integration.Test.Booking.Features;
|
|||||||
|
|
||||||
public class CreateBookingTests : BookingIntegrationTestBase
|
public class CreateBookingTests : BookingIntegrationTestBase
|
||||||
{
|
{
|
||||||
public CreateBookingTests(IntegrationTestFactory<Program, PersistMessageDbContext, BookingReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
public CreateBookingTests(TestFactory<Program, AppDbContextBase, BookingReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,12 +41,21 @@ public class CreateBookingTests : BookingIntegrationTestBase
|
|||||||
var command = new FakeCreateBookingCommand().Generate();
|
var command = new FakeCreateBookingCommand().Generate();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await Fixture.SendAsync(command);
|
try
|
||||||
|
{
|
||||||
|
var response = await Fixture.SendAsync(command);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
response.Should().BeGreaterOrEqualTo(0);
|
response.Should().BeGreaterOrEqualTo(0);
|
||||||
|
|
||||||
|
(await Fixture.WaitForPublishing<BookingCreated>()).Should().Be(true);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
(await Fixture.WaitForPublishing<BookingCreated>()).Should().Be(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,21 +1,22 @@
|
|||||||
using Booking.Api;
|
using Booking.Api;
|
||||||
using Booking.Data;
|
using Booking.Data;
|
||||||
|
using BuildingBlocks.EFCore;
|
||||||
using BuildingBlocks.PersistMessageProcessor.Data;
|
using BuildingBlocks.PersistMessageProcessor.Data;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Integration.Test;
|
namespace Integration.Test;
|
||||||
|
|
||||||
[Collection(IntegrationTestCollection.Name)]
|
[Collection(IntegrationTestCollection.Name)]
|
||||||
public class BookingIntegrationTestBase: IntegrationTestBase<Program, PersistMessageDbContext, BookingReadDbContext>
|
public class BookingIntegrationTestBase: TestBase<Program, AppDbContextBase, BookingReadDbContext>
|
||||||
{
|
{
|
||||||
public BookingIntegrationTestBase(IntegrationTestFactory<Program, PersistMessageDbContext, BookingReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
public BookingIntegrationTestBase(TestFactory<Program, AppDbContextBase, BookingReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CollectionDefinition(Name)]
|
[CollectionDefinition(Name)]
|
||||||
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, PersistMessageDbContext, BookingReadDbContext>>
|
public class IntegrationTestCollection : ICollectionFixture<TestFactory<Program, AppDbContextBase, BookingReadDbContext>>
|
||||||
{
|
{
|
||||||
public const string Name = "Booking Integration Test";
|
public const string Name = "Booking Integration Test";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,11 +20,11 @@ public class CreateAircraftEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/aircraft", CreateAircraft)
|
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/aircraft", CreateAircraft)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Flight")
|
.WithTags("Flight")
|
||||||
.WithName("Create Aircraft")
|
.WithName("CreateAircraft")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Create Aircraft", "Create Aircraft"))
|
.WithMetadata(new SwaggerOperationAttribute("Create Aircraft", "Create Aircraft"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||||
.Produces<AircraftResponseDto>()
|
.Produces<AircraftResponseDto>()
|
||||||
.Produces(StatusCodes.Status201Created)
|
.Produces(StatusCodes.Status200OK)
|
||||||
.Produces(StatusCodes.Status400BadRequest)
|
.Produces(StatusCodes.Status400BadRequest)
|
||||||
.HasApiVersion(1.0);
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
|
|||||||
@ -20,11 +20,11 @@ public class CreateAirportEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/airport", CreateAirport)
|
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/airport", CreateAirport)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Flight")
|
.WithTags("Flight")
|
||||||
.WithName("Create Airport")
|
.WithName("CreateAirport")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Create Airport", "Create Airport"))
|
.WithMetadata(new SwaggerOperationAttribute("Create Airport", "Create Airport"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||||
.Produces<AirportResponseDto>()
|
.Produces<AirportResponseDto>()
|
||||||
.Produces(StatusCodes.Status201Created)
|
.Produces(StatusCodes.Status200OK)
|
||||||
.Produces(StatusCodes.Status400BadRequest)
|
.Produces(StatusCodes.Status400BadRequest)
|
||||||
.HasApiVersion(1.0);
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ public static class ProblemDetailsExtensions
|
|||||||
};
|
};
|
||||||
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "Application rule broken",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status409Conflict,
|
Status = StatusCodes.Status409Conflict,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/application-rule-validation-error"
|
Type = "https://somedomain/application-rule-validation-error"
|
||||||
@ -31,35 +31,35 @@ public static class ProblemDetailsExtensions
|
|||||||
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
||||||
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "input validation rules broken",
|
Title = ex.GetType().Name,
|
||||||
Status = (int)ex.StatusCode,
|
Status = (int)ex.StatusCode,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/input-validation-rules-error"
|
Type = "https://somedomain/input-validation-rules-error"
|
||||||
});
|
});
|
||||||
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "bad request exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status400BadRequest,
|
Status = StatusCodes.Status400BadRequest,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/bad-request-error"
|
Type = "https://somedomain/bad-request-error"
|
||||||
});
|
});
|
||||||
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "not found exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status404NotFound,
|
Status = StatusCodes.Status404NotFound,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/not-found-error"
|
Type = "https://somedomain/not-found-error"
|
||||||
});
|
});
|
||||||
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "api server exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status500InternalServerError,
|
Status = StatusCodes.Status500InternalServerError,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/api-server-error"
|
Type = "https://somedomain/api-server-error"
|
||||||
});
|
});
|
||||||
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "application exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status400BadRequest,
|
Status = StatusCodes.Status400BadRequest,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/application-error"
|
Type = "https://somedomain/application-error"
|
||||||
|
|||||||
@ -21,7 +21,7 @@ public class CreateFlightEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight", CreateFlight)
|
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight", CreateFlight)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Flight")
|
.WithTags("Flight")
|
||||||
.WithName("Create Flight")
|
.WithName("CreateFlight")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Create Flight", "Create Flight"))
|
.WithMetadata(new SwaggerOperationAttribute("Create Flight", "Create Flight"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||||
.Produces<FlightResponseDto>()
|
.Produces<FlightResponseDto>()
|
||||||
@ -39,6 +39,6 @@ public class CreateFlightEndpoint : IMinimalEndpoint
|
|||||||
|
|
||||||
var result = await mediator.Send(command, cancellationToken);
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
|
|
||||||
return Results.Ok(result);
|
return Results.CreatedAtRoute("GetFlightById", new {id = result.Id}, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,11 +18,11 @@ public class DeleteFlightEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapDelete($"{EndpointConfig.BaseApiPath}/flight/{{id}}", DeleteFlight)
|
endpoints.MapDelete($"{EndpointConfig.BaseApiPath}/flight/{{id}}", DeleteFlight)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Flight")
|
.WithTags("Flight")
|
||||||
.WithName("Delete Flight")
|
.WithName("DeleteFlight")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Delete Flight", "Delete Flight"))
|
.WithMetadata(new SwaggerOperationAttribute("Delete Flight", "Delete Flight"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||||
.Produces<FlightResponseDto>()
|
.Produces<FlightResponseDto>()
|
||||||
.Produces(StatusCodes.Status201Created)
|
.Produces(StatusCodes.Status204NoContent)
|
||||||
.Produces(StatusCodes.Status400BadRequest)
|
.Produces(StatusCodes.Status400BadRequest)
|
||||||
.HasApiVersion(1.0);
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
@ -33,6 +33,6 @@ public class DeleteFlightEndpoint : IMinimalEndpoint
|
|||||||
{
|
{
|
||||||
var result = await mediator.Send(new DeleteFlightCommand(id), cancellationToken);
|
var result = await mediator.Send(new DeleteFlightCommand(id), cancellationToken);
|
||||||
|
|
||||||
return Results.Ok(result);
|
return Results.NoContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ public class GetAvailableFlightsEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/flight/get-available-flights", GetAvailableFlights)
|
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/flight/get-available-flights", GetAvailableFlights)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Flight")
|
.WithTags("Flight")
|
||||||
.WithName("Get Available Flights")
|
.WithName("GetAvailableFlights")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Get Available Flights", "Get Available Flights"))
|
.WithMetadata(new SwaggerOperationAttribute("Get Available Flights", "Get Available Flights"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||||
.Produces<IEnumerable<FlightResponseDto>>()
|
.Produces<IEnumerable<FlightResponseDto>>()
|
||||||
|
|||||||
@ -18,7 +18,7 @@ public class GetFlightByIdEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/flight/{{id}}", GetById)
|
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/flight/{{id}}", GetById)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Flight")
|
.WithTags("Flight")
|
||||||
.WithName("Get Flight By Id")
|
.WithName("GetFlightById")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Get Flight By Id", "Get Flight By Id"))
|
.WithMetadata(new SwaggerOperationAttribute("Get Flight By Id", "Get Flight By Id"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||||
.Produces<FlightResponseDto>()
|
.Produces<FlightResponseDto>()
|
||||||
|
|||||||
@ -20,11 +20,11 @@ public class UpdateFlightEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapPut($"{EndpointConfig.BaseApiPath}/flight", UpdateFlight)
|
endpoints.MapPut($"{EndpointConfig.BaseApiPath}/flight", UpdateFlight)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Flight")
|
.WithTags("Flight")
|
||||||
.WithName("Update Flight")
|
.WithName("UpdateFlight")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Update Flight", "Update Flight"))
|
.WithMetadata(new SwaggerOperationAttribute("Update Flight", "Update Flight"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||||
.Produces<FlightResponseDto>()
|
.Produces<FlightResponseDto>()
|
||||||
.Produces(StatusCodes.Status201Created)
|
.Produces(StatusCodes.Status204NoContent)
|
||||||
.Produces(StatusCodes.Status400BadRequest)
|
.Produces(StatusCodes.Status400BadRequest)
|
||||||
.HasApiVersion(1.0);
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
@ -37,6 +37,6 @@ public class UpdateFlightEndpoint : IMinimalEndpoint
|
|||||||
|
|
||||||
var result = await mediator.Send(command, cancellationToken);
|
var result = await mediator.Send(command, cancellationToken);
|
||||||
|
|
||||||
return Results.Ok(result);
|
return Results.NoContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,11 +20,11 @@ public class CreateSeatEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/seat", CreateSeat)
|
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/seat", CreateSeat)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Flight")
|
.WithTags("Flight")
|
||||||
.WithName("Create Seat")
|
.WithName("CreateSeat")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Create Seat", "Create Seat"))
|
.WithMetadata(new SwaggerOperationAttribute("Create Seat", "Create Seat"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||||
.Produces<SeatResponseDto>()
|
.Produces<SeatResponseDto>()
|
||||||
.Produces(StatusCodes.Status201Created)
|
.Produces(StatusCodes.Status200OK)
|
||||||
.Produces(StatusCodes.Status400BadRequest)
|
.Produces(StatusCodes.Status400BadRequest)
|
||||||
.HasApiVersion(1.0);
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ public class GetAvailableSeatsEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/flight/get-available-seats/{{id}}", GetAvailableSeats)
|
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/flight/get-available-seats/{{id}}", GetAvailableSeats)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Flight")
|
.WithTags("Flight")
|
||||||
.WithName("Get Available Seats")
|
.WithName("GetAvailableSeats")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Get Available Seats", "Get Available Seats"))
|
.WithMetadata(new SwaggerOperationAttribute("Get Available Seats", "Get Available Seats"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||||
.Produces<IEnumerable<SeatResponseDto>>()
|
.Produces<IEnumerable<SeatResponseDto>>()
|
||||||
@ -36,4 +36,4 @@ public class GetAvailableSeatsEndpoint : IMinimalEndpoint
|
|||||||
|
|
||||||
return Results.Ok(result);
|
return Results.Ok(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,11 +20,11 @@ public class ReserveSeatEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/reserve-seat", ReserveSeat)
|
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/reserve-seat", ReserveSeat)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Flight")
|
.WithTags("Flight")
|
||||||
.WithName("Reserve Seat")
|
.WithName("ReserveSeat")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Reserve Seat", "Reserve Seat"))
|
.WithMetadata(new SwaggerOperationAttribute("Reserve Seat", "Reserve Seat"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||||
.Produces<SeatResponseDto>()
|
.Produces<SeatResponseDto>()
|
||||||
.Produces(StatusCodes.Status201Created)
|
.Produces(StatusCodes.Status200OK)
|
||||||
.Produces(StatusCodes.Status400BadRequest)
|
.Produces(StatusCodes.Status400BadRequest)
|
||||||
.HasApiVersion(1.0);
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
|
|||||||
40
src/Services/Flight/tests/EndToEndTest/EndToEnd.Test.csproj
Normal file
40
src/Services/Flight/tests/EndToEndTest/EndToEnd.Test.csproj
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="xunit.runner.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
|
||||||
|
<PackageReference Include="xunit" Version="2.4.2" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.2.0">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Flight.Api\Flight.Api.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Fakes" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
using AutoBogus;
|
||||||
|
using BuildingBlocks.IdsGenerator;
|
||||||
|
using Flight.Flights.Enums;
|
||||||
|
using Flight.Flights.Features.CreateFlight.Commands.V1;
|
||||||
|
|
||||||
|
namespace EndToEnd.Test.Fakes;
|
||||||
|
|
||||||
|
public sealed class FakeCreateFlightCommand : AutoFaker<CreateFlightCommand>
|
||||||
|
{
|
||||||
|
public FakeCreateFlightCommand()
|
||||||
|
{
|
||||||
|
RuleFor(r => r.Id, _ => SnowFlakIdGenerator.NewId());
|
||||||
|
RuleFor(r => r.FlightNumber, r => r.Random.String());
|
||||||
|
RuleFor(r => r.DepartureAirportId, _ => 1);
|
||||||
|
RuleFor(r => r.ArriveAirportId, _ => 2);
|
||||||
|
RuleFor(r => r.Status, _ => FlightStatus.Flying);
|
||||||
|
RuleFor(r => r.AircraftId, _ => 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
using System.Net;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using BuildingBlocks.TestBase;
|
||||||
|
using EndToEnd.Test.Fakes;
|
||||||
|
using EndToEnd.Test.Routes;
|
||||||
|
using Flight.Api;
|
||||||
|
using Flight.Data;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EndToEnd.Test.Flight.Features;
|
||||||
|
|
||||||
|
public class CreateFlightTests : FlightEndToEndTestBase
|
||||||
|
{
|
||||||
|
public CreateFlightTests(TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task should_create_new_flight_to_db_and_publish_message_to_broker()
|
||||||
|
{
|
||||||
|
//Arrange
|
||||||
|
var command = new FakeCreateFlightCommand().Generate();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var route = ApiRoutes.Flight.CreateFlight;
|
||||||
|
var result = await Fixture.HttpClient.PostAsJsonAsync(route, command);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.StatusCode.Should().Be(HttpStatusCode.Created);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
using System.Net;
|
||||||
|
using BuildingBlocks.TestBase;
|
||||||
|
using EndToEnd.Test.Fakes;
|
||||||
|
using EndToEnd.Test.Routes;
|
||||||
|
using Flight.Api;
|
||||||
|
using Flight.Data;
|
||||||
|
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EndToEnd.Test.Flight.Features;
|
||||||
|
|
||||||
|
public class GetFlightByIdTests: FlightEndToEndTestBase
|
||||||
|
{
|
||||||
|
public GetFlightByIdTests(TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task should_retrive_a_flight_by_id_currectly()
|
||||||
|
{
|
||||||
|
//Arrange
|
||||||
|
var command = new FakeCreateFlightCommand().Generate();
|
||||||
|
await Fixture.SendAsync(command);
|
||||||
|
(await Fixture.ShouldProcessedPersistInternalCommand<CreateFlightMongoCommand>()).Should().Be(true);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var route = ApiRoutes.Flight.GetFlightById.Replace(ApiRoutes.Flight.Id, command.Id.ToString());
|
||||||
|
var result = await Fixture.HttpClient.GetAsync(route);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/Services/Flight/tests/EndToEndTest/FlightTestBase.cs
Normal file
20
src/Services/Flight/tests/EndToEndTest/FlightTestBase.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using BuildingBlocks.TestBase;
|
||||||
|
using Flight.Api;
|
||||||
|
using Flight.Data;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EndToEnd.Test;
|
||||||
|
|
||||||
|
[Collection(EndToEndTestCollection.Name)]
|
||||||
|
public class FlightEndToEndTestBase: TestBase<Program, FlightDbContext, FlightReadDbContext>
|
||||||
|
{
|
||||||
|
public FlightEndToEndTestBase(TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CollectionDefinition(Name)]
|
||||||
|
public class EndToEndTestCollection : ICollectionFixture<TestFactory<Program, FlightDbContext, FlightReadDbContext>>
|
||||||
|
{
|
||||||
|
public const string Name = "Flight EndToEnd Test";
|
||||||
|
}
|
||||||
13
src/Services/Flight/tests/EndToEndTest/Routes/ApiRoutes.cs
Normal file
13
src/Services/Flight/tests/EndToEndTest/Routes/ApiRoutes.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace EndToEnd.Test.Routes;
|
||||||
|
|
||||||
|
public class ApiRoutes
|
||||||
|
{
|
||||||
|
public const string BaseApiPath = "api/v1.0";
|
||||||
|
|
||||||
|
public static class Flight
|
||||||
|
{
|
||||||
|
public const string Id = "{id}";
|
||||||
|
public const string GetFlightById = $"{BaseApiPath}/flight/{Id}";
|
||||||
|
public const string CreateFlight = $"{BaseApiPath}/flight";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight.Aircrafts.Features.CreateAircraft.Commands.V1.Reads;
|
using Flight.Aircrafts.Features.CreateAircraft.Commands.V1.Reads;
|
||||||
using Flight.Api;
|
using Flight.Api;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
@ -13,7 +13,7 @@ namespace Integration.Test.Aircraft.Features;
|
|||||||
public class CreateAircraftTests : FlightIntegrationTestBase
|
public class CreateAircraftTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public CreateAircraftTests(
|
public CreateAircraftTests(
|
||||||
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight.Airports.Features.CreateAirport.Commands.V1.Reads;
|
using Flight.Airports.Features.CreateAirport.Commands.V1.Reads;
|
||||||
using Flight.Api;
|
using Flight.Api;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
@ -13,7 +13,7 @@ namespace Integration.Test.Airport.Features;
|
|||||||
public class CreateAirportTests : FlightIntegrationTestBase
|
public class CreateAirportTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public CreateAirportTests(
|
public CreateAirportTests(
|
||||||
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight.Api;
|
using Flight.Api;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
||||||
@ -13,7 +13,7 @@ namespace Integration.Test.Flight.Features;
|
|||||||
public class CreateFlightTests : FlightIntegrationTestBase
|
public class CreateFlightTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public CreateFlightTests(
|
public CreateFlightTests(
|
||||||
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight.Api;
|
using Flight.Api;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
using Flight.Flights.Features.DeleteFlight.Commands.V1;
|
using Flight.Flights.Features.DeleteFlight.Commands.V1;
|
||||||
@ -15,7 +15,7 @@ namespace Integration.Test.Flight.Features;
|
|||||||
public class DeleteFlightTests : FlightIntegrationTestBase
|
public class DeleteFlightTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public DeleteFlightTests(
|
public DeleteFlightTests(
|
||||||
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight.Api;
|
using Flight.Api;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
||||||
@ -14,7 +14,7 @@ namespace Integration.Test.Flight.Features;
|
|||||||
public class GetAvailableFlightsTests : FlightIntegrationTestBase
|
public class GetAvailableFlightsTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public GetAvailableFlightsTests(
|
public GetAvailableFlightsTests(
|
||||||
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight;
|
using Flight;
|
||||||
using Flight.Api;
|
using Flight.Api;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
@ -14,7 +14,7 @@ namespace Integration.Test.Flight.Features;
|
|||||||
public class GetFlightByIdTests : FlightIntegrationTestBase
|
public class GetFlightByIdTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public GetFlightByIdTests(
|
public GetFlightByIdTests(
|
||||||
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight.Api;
|
using Flight.Api;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
using Flight.Flights.Features.UpdateFlight.Commands.V1.Reads;
|
using Flight.Flights.Features.UpdateFlight.Commands.V1.Reads;
|
||||||
@ -13,7 +13,7 @@ namespace Integration.Test.Flight.Features;
|
|||||||
public class UpdateFlightTests : FlightIntegrationTestBase
|
public class UpdateFlightTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public UpdateFlightTests(
|
public UpdateFlightTests(
|
||||||
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight.Api;
|
using Flight.Api;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@ -6,15 +6,15 @@ using Xunit;
|
|||||||
namespace Integration.Test;
|
namespace Integration.Test;
|
||||||
|
|
||||||
[Collection(IntegrationTestCollection.Name)]
|
[Collection(IntegrationTestCollection.Name)]
|
||||||
public class FlightIntegrationTestBase: IntegrationTestBase<Program, FlightDbContext, FlightReadDbContext>
|
public class FlightIntegrationTestBase: TestBase<Program, FlightDbContext, FlightReadDbContext>
|
||||||
{
|
{
|
||||||
public FlightIntegrationTestBase(IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
public FlightIntegrationTestBase(TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CollectionDefinition(Name)]
|
[CollectionDefinition(Name)]
|
||||||
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext>>
|
public class IntegrationTestCollection : ICollectionFixture<TestFactory<Program, FlightDbContext, FlightReadDbContext>>
|
||||||
{
|
{
|
||||||
public const string Name = "Flight Integration Test";
|
public const string Name = "Flight Integration Test";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight;
|
using Flight;
|
||||||
using Flight.Api;
|
using Flight.Api;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
@ -14,7 +14,7 @@ namespace Integration.Test.Seat.Features;
|
|||||||
public class GetAvailableSeatsTests : FlightIntegrationTestBase
|
public class GetAvailableSeatsTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public GetAvailableSeatsTests(
|
public GetAvailableSeatsTests(
|
||||||
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Flight;
|
using Flight;
|
||||||
using Flight.Api;
|
using Flight.Api;
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
@ -14,7 +14,7 @@ namespace Integration.Test.Seat.Features;
|
|||||||
public class ReserveSeatTests : FlightIntegrationTestBase
|
public class ReserveSeatTests : FlightIntegrationTestBase
|
||||||
{
|
{
|
||||||
public ReserveSeatTests(
|
public ReserveSeatTests(
|
||||||
IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, FlightDbContext, FlightReadDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ public static class ProblemDetailsExtensions
|
|||||||
};
|
};
|
||||||
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "Application rule broken",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status409Conflict,
|
Status = StatusCodes.Status409Conflict,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/application-rule-validation-error"
|
Type = "https://somedomain/application-rule-validation-error"
|
||||||
@ -31,35 +31,35 @@ public static class ProblemDetailsExtensions
|
|||||||
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
||||||
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "input validation rules broken",
|
Title = ex.GetType().Name,
|
||||||
Status = (int)ex.StatusCode,
|
Status = (int)ex.StatusCode,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/input-validation-rules-error"
|
Type = "https://somedomain/input-validation-rules-error"
|
||||||
});
|
});
|
||||||
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "bad request exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status400BadRequest,
|
Status = StatusCodes.Status400BadRequest,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/bad-request-error"
|
Type = "https://somedomain/bad-request-error"
|
||||||
});
|
});
|
||||||
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "not found exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status404NotFound,
|
Status = StatusCodes.Status404NotFound,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/not-found-error"
|
Type = "https://somedomain/not-found-error"
|
||||||
});
|
});
|
||||||
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "api server exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status500InternalServerError,
|
Status = StatusCodes.Status500InternalServerError,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/api-server-error"
|
Type = "https://somedomain/api-server-error"
|
||||||
});
|
});
|
||||||
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "application exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status400BadRequest,
|
Status = StatusCodes.Status400BadRequest,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/application-error"
|
Type = "https://somedomain/application-error"
|
||||||
|
|||||||
@ -19,11 +19,11 @@ public class RegisterNewUserEndpoint : IMinimalEndpoint
|
|||||||
{
|
{
|
||||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/identity/register-user", RegisterNewUser)
|
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/identity/register-user", RegisterNewUser)
|
||||||
.WithTags("Identity")
|
.WithTags("Identity")
|
||||||
.WithName("Register User")
|
.WithName("RegisterUser")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Register User", "Register User"))
|
.WithMetadata(new SwaggerOperationAttribute("Register User", "Register User"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Identity").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Identity").Build())
|
||||||
.Produces<RegisterNewUserResponseDto>()
|
.Produces<RegisterNewUserResponseDto>()
|
||||||
.Produces(StatusCodes.Status201Created)
|
.Produces(StatusCodes.Status200OK)
|
||||||
.Produces(StatusCodes.Status400BadRequest)
|
.Produces(StatusCodes.Status400BadRequest)
|
||||||
.HasApiVersion(1.0);
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Identity.Api;
|
using Identity.Api;
|
||||||
using Identity.Data;
|
using Identity.Data;
|
||||||
@ -12,7 +12,7 @@ namespace Integration.Test.Identity.Features;
|
|||||||
public class RegisterNewUserTests : IdentityIntegrationTestBase
|
public class RegisterNewUserTests : IdentityIntegrationTestBase
|
||||||
{
|
{
|
||||||
public RegisterNewUserTests(
|
public RegisterNewUserTests(
|
||||||
IntegrationTestFactory<Program, IdentityContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, IdentityContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Identity.Api;
|
using Identity.Api;
|
||||||
using Identity.Data;
|
using Identity.Data;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@ -6,16 +6,16 @@ using Xunit;
|
|||||||
namespace Integration.Test;
|
namespace Integration.Test;
|
||||||
|
|
||||||
[Collection(IntegrationTestCollection.Name)]
|
[Collection(IntegrationTestCollection.Name)]
|
||||||
public class IdentityIntegrationTestBase: IntegrationTestBase<Program, IdentityContext>
|
public class IdentityIntegrationTestBase: TestBase<Program, IdentityContext>
|
||||||
{
|
{
|
||||||
public IdentityIntegrationTestBase(IntegrationTestFactory<Program, IdentityContext> integrationTestFactory)
|
public IdentityIntegrationTestBase(TestFactory<Program, IdentityContext> integrationTestFactory)
|
||||||
: base(integrationTestFactory)
|
: base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CollectionDefinition(Name)]
|
[CollectionDefinition(Name)]
|
||||||
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, IdentityContext>>
|
public class IntegrationTestCollection : ICollectionFixture<TestFactory<Program, IdentityContext>>
|
||||||
{
|
{
|
||||||
public const string Name = "Identity Integration Test";
|
public const string Name = "Identity Integration Test";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ public static class ProblemDetailsExtensions
|
|||||||
};
|
};
|
||||||
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "Application rule broken",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status409Conflict,
|
Status = StatusCodes.Status409Conflict,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/application-rule-validation-error"
|
Type = "https://somedomain/application-rule-validation-error"
|
||||||
@ -30,35 +30,35 @@ public static class ProblemDetailsExtensions
|
|||||||
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
||||||
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "input validation rules broken",
|
Title = ex.GetType().Name,
|
||||||
Status = (int)ex.StatusCode,
|
Status = (int)ex.StatusCode,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/input-validation-rules-error"
|
Type = "https://somedomain/input-validation-rules-error"
|
||||||
});
|
});
|
||||||
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "bad request exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status400BadRequest,
|
Status = StatusCodes.Status400BadRequest,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/bad-request-error"
|
Type = "https://somedomain/bad-request-error"
|
||||||
});
|
});
|
||||||
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "not found exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status404NotFound,
|
Status = StatusCodes.Status404NotFound,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/not-found-error"
|
Type = "https://somedomain/not-found-error"
|
||||||
});
|
});
|
||||||
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "api server exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status500InternalServerError,
|
Status = StatusCodes.Status500InternalServerError,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/api-server-error"
|
Type = "https://somedomain/api-server-error"
|
||||||
});
|
});
|
||||||
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
||||||
{
|
{
|
||||||
Title = "application exception",
|
Title = ex.GetType().Name,
|
||||||
Status = StatusCodes.Status400BadRequest,
|
Status = StatusCodes.Status400BadRequest,
|
||||||
Detail = ex.Message,
|
Detail = ex.Message,
|
||||||
Type = "https://somedomain/application-error"
|
Type = "https://somedomain/application-error"
|
||||||
|
|||||||
@ -18,11 +18,11 @@ public class CompleteRegisterPassengerEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/passenger/complete-registration", CompleteRegisterPassenger)
|
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/passenger/complete-registration", CompleteRegisterPassenger)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Passenger")
|
.WithTags("Passenger")
|
||||||
.WithName("Complete Register Passenger")
|
.WithName("CompleteRegisterPassenger")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Complete Register Passenger", "Complete Register Passenger"))
|
.WithMetadata(new SwaggerOperationAttribute("Complete Register Passenger", "Complete Register Passenger"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Passenger").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Passenger").Build())
|
||||||
.Produces<PassengerResponseDto>()
|
.Produces<PassengerResponseDto>()
|
||||||
.Produces(StatusCodes.Status201Created)
|
.Produces(StatusCodes.Status200OK)
|
||||||
.Produces(StatusCodes.Status400BadRequest)
|
.Produces(StatusCodes.Status400BadRequest)
|
||||||
.HasApiVersion(1.0);
|
.HasApiVersion(1.0);
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ public class GetPassengerByIdEndpoint : IMinimalEndpoint
|
|||||||
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/passenger/{{id}}", GetById)
|
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/passenger/{{id}}", GetById)
|
||||||
.RequireAuthorization()
|
.RequireAuthorization()
|
||||||
.WithTags("Passenger")
|
.WithTags("Passenger")
|
||||||
.WithName("Get Passenger By Id")
|
.WithName("GetPassengerById")
|
||||||
.WithMetadata(new SwaggerOperationAttribute("Get Passenger By Id", "Get Passenger By Id"))
|
.WithMetadata(new SwaggerOperationAttribute("Get Passenger By Id", "Get Passenger By Id"))
|
||||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Passenger").Build())
|
.WithApiVersionSet(endpoints.NewApiVersionSet("Passenger").Build())
|
||||||
.Produces<PassengerResponseDto>()
|
.Produces<PassengerResponseDto>()
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Integration.Test.Fakes;
|
using Integration.Test.Fakes;
|
||||||
using Passenger.Api;
|
using Passenger.Api;
|
||||||
@ -12,7 +12,7 @@ namespace Integration.Test.Passenger.Features;
|
|||||||
public class CompleteRegisterPassengerTests : PassengerIntegrationTestBase
|
public class CompleteRegisterPassengerTests : PassengerIntegrationTestBase
|
||||||
{
|
{
|
||||||
public CompleteRegisterPassengerTests(
|
public CompleteRegisterPassengerTests(
|
||||||
IntegrationTestFactory<Program, PassengerDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, PassengerDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Integration.Test.Fakes;
|
using Integration.Test.Fakes;
|
||||||
using Passenger;
|
using Passenger;
|
||||||
@ -13,7 +13,7 @@ namespace Integration.Test.Passenger.Features;
|
|||||||
public class GetPassengerByIdTests : PassengerIntegrationTestBase
|
public class GetPassengerByIdTests : PassengerIntegrationTestBase
|
||||||
{
|
{
|
||||||
public GetPassengerByIdTests(
|
public GetPassengerByIdTests(
|
||||||
IntegrationTestFactory<Program, PassengerDbContext> integrationTestFactory) : base(integrationTestFactory)
|
TestFactory<Program, PassengerDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using BuildingBlocks.TestBase.IntegrationTest;
|
using BuildingBlocks.TestBase;
|
||||||
using Passenger.Api;
|
using Passenger.Api;
|
||||||
using Passenger.Data;
|
using Passenger.Data;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@ -6,16 +6,16 @@ using Xunit;
|
|||||||
namespace Integration.Test;
|
namespace Integration.Test;
|
||||||
|
|
||||||
[Collection(IntegrationTestCollection.Name)]
|
[Collection(IntegrationTestCollection.Name)]
|
||||||
public class PassengerIntegrationTestBase: IntegrationTestBase<Program, PassengerDbContext>
|
public class PassengerIntegrationTestBase: TestBase<Program, PassengerDbContext>
|
||||||
{
|
{
|
||||||
public PassengerIntegrationTestBase(IntegrationTestFactory<Program, PassengerDbContext> integrationTestFactory)
|
public PassengerIntegrationTestBase(TestFactory<Program, PassengerDbContext> integrationTestFactory)
|
||||||
: base(integrationTestFactory)
|
: base(integrationTestFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CollectionDefinition(Name)]
|
[CollectionDefinition(Name)]
|
||||||
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, PassengerDbContext>>
|
public class IntegrationTestCollection : ICollectionFixture<TestFactory<Program, PassengerDbContext>>
|
||||||
{
|
{
|
||||||
public const string Name = "Passenger Integration Test";
|
public const string Name = "Passenger Integration Test";
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user