mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-04-17 08:26:28 +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
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unit.Test", "src\Services\Flight\tests\UnitTest\Unit.Test.csproj", "{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EndToEnd.Test", "src\Services\Flight\tests\EndToEndTest\EndToEnd.Test.csproj", "{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -102,6 +104,7 @@ Global
|
||||
{539364C8-88B1-48A3-8406-D0B19FF30509} = {C1EBE17D-BFAD-47DA-88EB-BB073B84593E}
|
||||
{50C66B53-ACA0-4AFF-8C5C-834D4EDA8FAC} = {5185D5C5-0EAD-49D5-B405-93B939F3639B}
|
||||
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8} = {C6EE337B-91EA-472A-87C7-E9528408CE59}
|
||||
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB} = {C6EE337B-91EA-472A-87C7-E9528408CE59}
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{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}.Release|Any CPU.ActiveCfg = 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
|
||||
EndGlobal
|
||||
|
||||
@ -1,14 +1,18 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
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/
|
||||
public static class AuthServiceCollectionExtensions
|
||||
{
|
||||
public static AuthenticationBuilder AddTestAuthentication(
|
||||
this IServiceCollection services)
|
||||
private static MockAuthUser GetMockUser() =>
|
||||
new MockAuthUser(new Claim("sub", Guid.NewGuid().ToString()),
|
||||
new Claim("email", "sam@test.com"));
|
||||
|
||||
public static AuthenticationBuilder AddTestAuthentication(this IServiceCollection services)
|
||||
{
|
||||
services.AddAuthorization(options =>
|
||||
{
|
||||
@ -18,6 +22,9 @@ public static class AuthServiceCollectionExtensions
|
||||
.Build();
|
||||
});
|
||||
|
||||
// Register a default user, so all requests have it by default
|
||||
services.AddScoped(_ => GetMockUser());
|
||||
|
||||
// Register our custom authentication handler
|
||||
return services.AddAuthentication("Test")
|
||||
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>("Test", options => { });
|
||||
@ -1,6 +1,6 @@
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace BuildingBlocks.TestBase.EndToEndTest.Auth;
|
||||
namespace BuildingBlocks.TestBase.Auth;
|
||||
|
||||
public class MockAuthUser
|
||||
{
|
||||
@ -4,11 +4,13 @@ using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.Extensions.Logging;
|
||||
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/
|
||||
public class TestAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
{
|
||||
|
||||
|
||||
private readonly MockAuthUser _mockAuthUser;
|
||||
|
||||
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.Model;
|
||||
using BuildingBlocks.EFCore;
|
||||
using BuildingBlocks.MassTransit;
|
||||
using BuildingBlocks.Mongo;
|
||||
using BuildingBlocks.PersistMessageProcessor;
|
||||
using BuildingBlocks.TestBase.EndToEndTest.Auth;
|
||||
using BuildingBlocks.TestBase.Auth;
|
||||
using BuildingBlocks.Web;
|
||||
using DotNet.Testcontainers.Containers;
|
||||
using EasyNetQ.Management.Client;
|
||||
@ -31,9 +30,9 @@ using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using ILogger = Serilog.ILogger;
|
||||
|
||||
namespace BuildingBlocks.TestBase.IntegrationTest;
|
||||
namespace BuildingBlocks.TestBase;
|
||||
|
||||
public class IntegrationTestFactory<TEntryPoint> : IAsyncLifetime
|
||||
public class TestFactory<TEntryPoint> : IAsyncLifetime
|
||||
where TEntryPoint : class
|
||||
{
|
||||
private readonly WebApplicationFactory<TEntryPoint> _factory;
|
||||
@ -52,7 +51,7 @@ public class IntegrationTestFactory<TEntryPoint> : IAsyncLifetime
|
||||
public IConfiguration Configuration => _factory?.Services.GetRequiredService<IConfiguration>();
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public IntegrationTestFactory()
|
||||
public TestFactory()
|
||||
{
|
||||
_factory = new WebApplicationFactory<TEntryPoint>()
|
||||
.WithWebHostBuilder(builder =>
|
||||
@ -64,11 +63,7 @@ public class IntegrationTestFactory<TEntryPoint> : IAsyncLifetime
|
||||
{
|
||||
TestRegistrationServices?.Invoke(services);
|
||||
services.ReplaceSingleton(AddHttpContextAccessorMock);
|
||||
// Add our custom handler
|
||||
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;
|
||||
}
|
||||
|
||||
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 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 TWContext : DbContext
|
||||
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
|
||||
{
|
||||
private Respawner _reSpawnerDefaultDb;
|
||||
@ -398,14 +389,14 @@ public class IntegrationTestFixtureCore<TEntryPoint> : IAsyncLifetime
|
||||
private SqlConnection DefaultDbConnection { get; set; }
|
||||
private SqlConnection PersistDbConnection { get; set; }
|
||||
|
||||
public IntegrationTestFixtureCore(IntegrationTestFactory<TEntryPoint> integrationTestFixture, ITestOutputHelper outputHelper)
|
||||
public TestFixtureCore(TestFactory<TEntryPoint> integrationTestFixture, ITestOutputHelper outputHelper)
|
||||
{
|
||||
Fixture = integrationTestFixture;
|
||||
integrationTestFixture.RegisterServices(services => RegisterTestsServices(services));
|
||||
integrationTestFixture.Logger = integrationTestFixture.CreateLogger(outputHelper);
|
||||
}
|
||||
|
||||
public IntegrationTestFactory<TEntryPoint> Fixture { get; }
|
||||
public TestFactory<TEntryPoint> Fixture { get; }
|
||||
|
||||
|
||||
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>>
|
||||
where TEntryPoint : class
|
||||
where TWContext : DbContext
|
||||
{
|
||||
protected IntegrationTestBase(
|
||||
IntegrationTestFactory<TEntryPoint, TWContext> integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper)
|
||||
protected TestBase(
|
||||
TestFactory<TEntryPoint, TWContext> integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper)
|
||||
{
|
||||
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>>
|
||||
where TEntryPoint : class
|
||||
where TWContext : DbContext
|
||||
where TRContext : MongoDbContext
|
||||
{
|
||||
protected IntegrationTestBase(
|
||||
IntegrationTestFactory<TEntryPoint, TWContext, TRContext> integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper)
|
||||
protected TestBase(
|
||||
TestFactory<TEntryPoint, TWContext, TRContext> integrationTestFixture, ITestOutputHelper outputHelper = null) : base(integrationTestFixture, outputHelper)
|
||||
{
|
||||
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)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Booking")
|
||||
.WithName("Create Booking")
|
||||
.WithName("CreateBooking")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Create Booking", "Create Booking"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Booking").Build())
|
||||
.Produces<ulong>()
|
||||
.Produces(StatusCodes.Status201Created)
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ public static class ProblemDetailsExtensions
|
||||
};
|
||||
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "Application rule broken",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status409Conflict,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/application-rule-validation-error",
|
||||
@ -32,35 +32,35 @@ public static class ProblemDetailsExtensions
|
||||
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
||||
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "input validation rules broken",
|
||||
Title = ex.GetType().Name,
|
||||
Status = (int)ex.StatusCode,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/input-validation-rules-error",
|
||||
});
|
||||
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "bad request exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status400BadRequest,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/bad-request-error",
|
||||
});
|
||||
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "not found exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status404NotFound,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/not-found-error",
|
||||
});
|
||||
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "api server exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status500InternalServerError,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/api-server-error",
|
||||
});
|
||||
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "application exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status400BadRequest,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/application-error",
|
||||
@ -69,7 +69,7 @@ public static class ProblemDetailsExtensions
|
||||
x.Map<RpcException>(ex => new ProblemDetails
|
||||
{
|
||||
Status = StatusCodes.Status400BadRequest,
|
||||
Title = "grpc exception",
|
||||
Title = ex.GetType().Name,
|
||||
Detail = ex.Status.Detail,
|
||||
Type = "https://somedomain/grpc-error"
|
||||
});
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Booking.Api;
|
||||
using Booking.Data;
|
||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||
using BuildingBlocks.EFCore;
|
||||
using BuildingBlocks.PersistMessageProcessor.Data;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Flight;
|
||||
using FluentAssertions;
|
||||
using Grpc.Core;
|
||||
@ -21,7 +23,7 @@ namespace Integration.Test.Booking.Features;
|
||||
|
||||
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();
|
||||
|
||||
// Act
|
||||
var response = await Fixture.SendAsync(command);
|
||||
try
|
||||
{
|
||||
var response = await Fixture.SendAsync(command);
|
||||
|
||||
// Assert
|
||||
response.Should().BeGreaterOrEqualTo(0);
|
||||
// Assert
|
||||
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.Data;
|
||||
using BuildingBlocks.EFCore;
|
||||
using BuildingBlocks.PersistMessageProcessor.Data;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Xunit;
|
||||
|
||||
namespace Integration.Test;
|
||||
|
||||
[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)]
|
||||
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, PersistMessageDbContext, BookingReadDbContext>>
|
||||
public class IntegrationTestCollection : ICollectionFixture<TestFactory<Program, AppDbContextBase, BookingReadDbContext>>
|
||||
{
|
||||
public const string Name = "Booking Integration Test";
|
||||
}
|
||||
|
||||
@ -20,11 +20,11 @@ public class CreateAircraftEndpoint : IMinimalEndpoint
|
||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/aircraft", CreateAircraft)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Flight")
|
||||
.WithName("Create Aircraft")
|
||||
.WithName("CreateAircraft")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Create Aircraft", "Create Aircraft"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||
.Produces<AircraftResponseDto>()
|
||||
.Produces(StatusCodes.Status201Created)
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
|
||||
@ -20,11 +20,11 @@ public class CreateAirportEndpoint : IMinimalEndpoint
|
||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/airport", CreateAirport)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Flight")
|
||||
.WithName("Create Airport")
|
||||
.WithName("CreateAirport")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Create Airport", "Create Airport"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||
.Produces<AirportResponseDto>()
|
||||
.Produces(StatusCodes.Status201Created)
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ public static class ProblemDetailsExtensions
|
||||
};
|
||||
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "Application rule broken",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status409Conflict,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/application-rule-validation-error"
|
||||
@ -31,35 +31,35 @@ public static class ProblemDetailsExtensions
|
||||
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
||||
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "input validation rules broken",
|
||||
Title = ex.GetType().Name,
|
||||
Status = (int)ex.StatusCode,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/input-validation-rules-error"
|
||||
});
|
||||
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "bad request exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status400BadRequest,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/bad-request-error"
|
||||
});
|
||||
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "not found exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status404NotFound,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/not-found-error"
|
||||
});
|
||||
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "api server exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status500InternalServerError,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/api-server-error"
|
||||
});
|
||||
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "application exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status400BadRequest,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/application-error"
|
||||
|
||||
@ -21,7 +21,7 @@ public class CreateFlightEndpoint : IMinimalEndpoint
|
||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight", CreateFlight)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Flight")
|
||||
.WithName("Create Flight")
|
||||
.WithName("CreateFlight")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Create Flight", "Create Flight"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||
.Produces<FlightResponseDto>()
|
||||
@ -39,6 +39,6 @@ public class CreateFlightEndpoint : IMinimalEndpoint
|
||||
|
||||
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)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Flight")
|
||||
.WithName("Delete Flight")
|
||||
.WithName("DeleteFlight")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Delete Flight", "Delete Flight"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||
.Produces<FlightResponseDto>()
|
||||
.Produces(StatusCodes.Status201Created)
|
||||
.Produces(StatusCodes.Status204NoContent)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
@ -33,6 +33,6 @@ public class DeleteFlightEndpoint : IMinimalEndpoint
|
||||
{
|
||||
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)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Flight")
|
||||
.WithName("Get Available Flights")
|
||||
.WithName("GetAvailableFlights")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Get Available Flights", "Get Available Flights"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||
.Produces<IEnumerable<FlightResponseDto>>()
|
||||
|
||||
@ -18,7 +18,7 @@ public class GetFlightByIdEndpoint : IMinimalEndpoint
|
||||
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/flight/{{id}}", GetById)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Flight")
|
||||
.WithName("Get Flight By Id")
|
||||
.WithName("GetFlightById")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Get Flight By Id", "Get Flight By Id"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||
.Produces<FlightResponseDto>()
|
||||
|
||||
@ -20,11 +20,11 @@ public class UpdateFlightEndpoint : IMinimalEndpoint
|
||||
endpoints.MapPut($"{EndpointConfig.BaseApiPath}/flight", UpdateFlight)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Flight")
|
||||
.WithName("Update Flight")
|
||||
.WithName("UpdateFlight")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Update Flight", "Update Flight"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||
.Produces<FlightResponseDto>()
|
||||
.Produces(StatusCodes.Status201Created)
|
||||
.Produces(StatusCodes.Status204NoContent)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
@ -37,6 +37,6 @@ public class UpdateFlightEndpoint : IMinimalEndpoint
|
||||
|
||||
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)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Flight")
|
||||
.WithName("Create Seat")
|
||||
.WithName("CreateSeat")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Create Seat", "Create Seat"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||
.Produces<SeatResponseDto>()
|
||||
.Produces(StatusCodes.Status201Created)
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ public class GetAvailableSeatsEndpoint : IMinimalEndpoint
|
||||
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/flight/get-available-seats/{{id}}", GetAvailableSeats)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Flight")
|
||||
.WithName("Get Available Seats")
|
||||
.WithName("GetAvailableSeats")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Get Available Seats", "Get Available Seats"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||
.Produces<IEnumerable<SeatResponseDto>>()
|
||||
@ -36,4 +36,4 @@ public class GetAvailableSeatsEndpoint : IMinimalEndpoint
|
||||
|
||||
return Results.Ok(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,11 +20,11 @@ public class ReserveSeatEndpoint : IMinimalEndpoint
|
||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/flight/reserve-seat", ReserveSeat)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Flight")
|
||||
.WithName("Reserve Seat")
|
||||
.WithName("ReserveSeat")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Reserve Seat", "Reserve Seat"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Flight").Build())
|
||||
.Produces<SeatResponseDto>()
|
||||
.Produces(StatusCodes.Status201Created)
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.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 BuildingBlocks.Contracts.EventBus.Messages;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Flight.Aircrafts.Features.CreateAircraft.Commands.V1.Reads;
|
||||
using Flight.Api;
|
||||
using Flight.Data;
|
||||
@ -13,7 +13,7 @@ namespace Integration.Test.Aircraft.Features;
|
||||
public class CreateAircraftTests : FlightIntegrationTestBase
|
||||
{
|
||||
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 BuildingBlocks.Contracts.EventBus.Messages;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Flight.Airports.Features.CreateAirport.Commands.V1.Reads;
|
||||
using Flight.Api;
|
||||
using Flight.Data;
|
||||
@ -13,7 +13,7 @@ namespace Integration.Test.Airport.Features;
|
||||
public class CreateAirportTests : FlightIntegrationTestBase
|
||||
{
|
||||
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 BuildingBlocks.Contracts.EventBus.Messages;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Flight.Api;
|
||||
using Flight.Data;
|
||||
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
||||
@ -13,7 +13,7 @@ namespace Integration.Test.Flight.Features;
|
||||
public class CreateFlightTests : FlightIntegrationTestBase
|
||||
{
|
||||
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.Threading.Tasks;
|
||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Flight.Api;
|
||||
using Flight.Data;
|
||||
using Flight.Flights.Features.DeleteFlight.Commands.V1;
|
||||
@ -15,7 +15,7 @@ namespace Integration.Test.Flight.Features;
|
||||
public class DeleteFlightTests : FlightIntegrationTestBase
|
||||
{
|
||||
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.Threading.Tasks;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Flight.Api;
|
||||
using Flight.Data;
|
||||
using Flight.Flights.Features.CreateFlight.Commands.V1.Reads;
|
||||
@ -14,7 +14,7 @@ namespace Integration.Test.Flight.Features;
|
||||
public class GetAvailableFlightsTests : FlightIntegrationTestBase
|
||||
{
|
||||
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 BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Flight;
|
||||
using Flight.Api;
|
||||
using Flight.Data;
|
||||
@ -14,7 +14,7 @@ namespace Integration.Test.Flight.Features;
|
||||
public class GetFlightByIdTests : FlightIntegrationTestBase
|
||||
{
|
||||
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 BuildingBlocks.Contracts.EventBus.Messages;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Flight.Api;
|
||||
using Flight.Data;
|
||||
using Flight.Flights.Features.UpdateFlight.Commands.V1.Reads;
|
||||
@ -13,7 +13,7 @@ namespace Integration.Test.Flight.Features;
|
||||
public class UpdateFlightTests : FlightIntegrationTestBase
|
||||
{
|
||||
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.Data;
|
||||
using Xunit;
|
||||
@ -6,15 +6,15 @@ using Xunit;
|
||||
namespace Integration.Test;
|
||||
|
||||
[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)]
|
||||
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, FlightDbContext, FlightReadDbContext>>
|
||||
public class IntegrationTestCollection : ICollectionFixture<TestFactory<Program, FlightDbContext, FlightReadDbContext>>
|
||||
{
|
||||
public const string Name = "Flight Integration Test";
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Flight;
|
||||
using Flight.Api;
|
||||
using Flight.Data;
|
||||
@ -14,7 +14,7 @@ namespace Integration.Test.Seat.Features;
|
||||
public class GetAvailableSeatsTests : FlightIntegrationTestBase
|
||||
{
|
||||
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 BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using Flight;
|
||||
using Flight.Api;
|
||||
using Flight.Data;
|
||||
@ -14,7 +14,7 @@ namespace Integration.Test.Seat.Features;
|
||||
public class ReserveSeatTests : FlightIntegrationTestBase
|
||||
{
|
||||
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
|
||||
{
|
||||
Title = "Application rule broken",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status409Conflict,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/application-rule-validation-error"
|
||||
@ -31,35 +31,35 @@ public static class ProblemDetailsExtensions
|
||||
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
||||
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "input validation rules broken",
|
||||
Title = ex.GetType().Name,
|
||||
Status = (int)ex.StatusCode,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/input-validation-rules-error"
|
||||
});
|
||||
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "bad request exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status400BadRequest,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/bad-request-error"
|
||||
});
|
||||
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "not found exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status404NotFound,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/not-found-error"
|
||||
});
|
||||
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "api server exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status500InternalServerError,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/api-server-error"
|
||||
});
|
||||
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "application exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status400BadRequest,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/application-error"
|
||||
|
||||
@ -19,11 +19,11 @@ public class RegisterNewUserEndpoint : IMinimalEndpoint
|
||||
{
|
||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/identity/register-user", RegisterNewUser)
|
||||
.WithTags("Identity")
|
||||
.WithName("Register User")
|
||||
.WithName("RegisterUser")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Register User", "Register User"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Identity").Build())
|
||||
.Produces<RegisterNewUserResponseDto>()
|
||||
.Produces(StatusCodes.Status201Created)
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using FluentAssertions;
|
||||
using Identity.Api;
|
||||
using Identity.Data;
|
||||
@ -12,7 +12,7 @@ namespace Integration.Test.Identity.Features;
|
||||
public class RegisterNewUserTests : IdentityIntegrationTestBase
|
||||
{
|
||||
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.Data;
|
||||
using Xunit;
|
||||
@ -6,16 +6,16 @@ using Xunit;
|
||||
namespace Integration.Test;
|
||||
|
||||
[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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[CollectionDefinition(Name)]
|
||||
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, IdentityContext>>
|
||||
public class IntegrationTestCollection : ICollectionFixture<TestFactory<Program, IdentityContext>>
|
||||
{
|
||||
public const string Name = "Identity Integration Test";
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ public static class ProblemDetailsExtensions
|
||||
};
|
||||
x.Map<ConflictException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "Application rule broken",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status409Conflict,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/application-rule-validation-error"
|
||||
@ -30,35 +30,35 @@ public static class ProblemDetailsExtensions
|
||||
// Exception will produce and returns from our FluentValidation RequestValidationBehavior
|
||||
x.Map<ValidationException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "input validation rules broken",
|
||||
Title = ex.GetType().Name,
|
||||
Status = (int)ex.StatusCode,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/input-validation-rules-error"
|
||||
});
|
||||
x.Map<BadRequestException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "bad request exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status400BadRequest,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/bad-request-error"
|
||||
});
|
||||
x.Map<NotFoundException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "not found exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status404NotFound,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/not-found-error"
|
||||
});
|
||||
x.Map<InternalServerException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "api server exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status500InternalServerError,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/api-server-error"
|
||||
});
|
||||
x.Map<AppException>(ex => new ProblemDetailsWithCode
|
||||
{
|
||||
Title = "application exception",
|
||||
Title = ex.GetType().Name,
|
||||
Status = StatusCodes.Status400BadRequest,
|
||||
Detail = ex.Message,
|
||||
Type = "https://somedomain/application-error"
|
||||
|
||||
@ -18,11 +18,11 @@ public class CompleteRegisterPassengerEndpoint : IMinimalEndpoint
|
||||
endpoints.MapPost($"{EndpointConfig.BaseApiPath}/passenger/complete-registration", CompleteRegisterPassenger)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Passenger")
|
||||
.WithName("Complete Register Passenger")
|
||||
.WithName("CompleteRegisterPassenger")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Complete Register Passenger", "Complete Register Passenger"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Passenger").Build())
|
||||
.Produces<PassengerResponseDto>()
|
||||
.Produces(StatusCodes.Status201Created)
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.HasApiVersion(1.0);
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ public class GetPassengerByIdEndpoint : IMinimalEndpoint
|
||||
endpoints.MapGet($"{EndpointConfig.BaseApiPath}/passenger/{{id}}", GetById)
|
||||
.RequireAuthorization()
|
||||
.WithTags("Passenger")
|
||||
.WithName("Get Passenger By Id")
|
||||
.WithName("GetPassengerById")
|
||||
.WithMetadata(new SwaggerOperationAttribute("Get Passenger By Id", "Get Passenger By Id"))
|
||||
.WithApiVersionSet(endpoints.NewApiVersionSet("Passenger").Build())
|
||||
.Produces<PassengerResponseDto>()
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using BuildingBlocks.Contracts.EventBus.Messages;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using FluentAssertions;
|
||||
using Integration.Test.Fakes;
|
||||
using Passenger.Api;
|
||||
@ -12,7 +12,7 @@ namespace Integration.Test.Passenger.Features;
|
||||
public class CompleteRegisterPassengerTests : PassengerIntegrationTestBase
|
||||
{
|
||||
public CompleteRegisterPassengerTests(
|
||||
IntegrationTestFactory<Program, PassengerDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||
TestFactory<Program, PassengerDbContext> integrationTestFactory) : base(integrationTestFactory)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using BuildingBlocks.TestBase.IntegrationTest;
|
||||
using BuildingBlocks.TestBase;
|
||||
using FluentAssertions;
|
||||
using Integration.Test.Fakes;
|
||||
using Passenger;
|
||||
@ -13,7 +13,7 @@ namespace Integration.Test.Passenger.Features;
|
||||
public class GetPassengerByIdTests : PassengerIntegrationTestBase
|
||||
{
|
||||
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.Data;
|
||||
using Xunit;
|
||||
@ -6,16 +6,16 @@ using Xunit;
|
||||
namespace Integration.Test;
|
||||
|
||||
[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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[CollectionDefinition(Name)]
|
||||
public class IntegrationTestCollection : ICollectionFixture<IntegrationTestFactory<Program, PassengerDbContext>>
|
||||
public class IntegrationTestCollection : ICollectionFixture<TestFactory<Program, PassengerDbContext>>
|
||||
{
|
||||
public const string Name = "Passenger Integration Test";
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user