mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-05-03 11:21:53 +08:00
feat:add end to end test for flight
This commit is contained in:
parent
1fb9558227
commit
68d9db7849
@ -9,10 +9,10 @@ var builder = WebApplication.CreateBuilder(args);
|
|||||||
|
|
||||||
builder.AddSharedInfrastructure();
|
builder.AddSharedInfrastructure();
|
||||||
|
|
||||||
builder.AddFlightModules();
|
|
||||||
builder.AddIdentityModules();
|
builder.AddIdentityModules();
|
||||||
builder.AddPassengerModules();
|
builder.AddPassengerModules();
|
||||||
builder.AddBookingModules();
|
builder.AddBookingModules();
|
||||||
|
builder.AddFlightModules();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="xunit.runner.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||||
|
<PackageReference Include="xunit" Version="2.9.2" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\..\Api\src\Api.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
using AutoBogus;
|
||||||
|
using Flight.Flights.Enums;
|
||||||
|
|
||||||
|
namespace EndToEnd.Test.Fakes;
|
||||||
|
|
||||||
|
using global::Flight.Data.Seed;
|
||||||
|
using global::Flight.Flights.Features.CreatingFlight.V1;
|
||||||
|
using MassTransit;
|
||||||
|
|
||||||
|
public sealed class FakeCreateFlightCommand : AutoFaker<CreateFlight>
|
||||||
|
{
|
||||||
|
public FakeCreateFlightCommand()
|
||||||
|
{
|
||||||
|
RuleFor(r => r.Id, _ => NewId.NextGuid());
|
||||||
|
RuleFor(r => r.FlightNumber, r => "12FF");
|
||||||
|
RuleFor(r => r.DepartureAirportId, _ => InitialData.Airports.First().Id);
|
||||||
|
RuleFor(r => r.ArriveAirportId, _ => InitialData.Airports.Last().Id);
|
||||||
|
RuleFor(r => r.Status, _ => FlightStatus.Flying);
|
||||||
|
RuleFor(r => r.AircraftId, _ => InitialData.Aircrafts.First().Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
namespace EndToEnd.Test.Fakes;
|
||||||
|
|
||||||
|
using AutoBogus;
|
||||||
|
using global::Flight.Data.Seed;
|
||||||
|
using global::Flight.Flights.Enums;
|
||||||
|
using global::Flight.Flights.Features.CreatingFlight.V1;
|
||||||
|
using MassTransit;
|
||||||
|
|
||||||
|
public sealed class FakeCreateFlightMongoCommand : AutoFaker<CreateFlightMongo>
|
||||||
|
{
|
||||||
|
public FakeCreateFlightMongoCommand()
|
||||||
|
{
|
||||||
|
RuleFor(r => r.Id, _ => NewId.NextGuid());
|
||||||
|
RuleFor(r => r.FlightNumber, r => "12FF");
|
||||||
|
RuleFor(r => r.DepartureAirportId, _ => InitialData.Airports.First().Id);
|
||||||
|
RuleFor(r => r.ArriveAirportId, _ => InitialData.Airports.Last().Id);
|
||||||
|
RuleFor(r => r.Status, _ => FlightStatus.Flying);
|
||||||
|
RuleFor(r => r.AircraftId, _ => InitialData.Aircrafts.First().Id);
|
||||||
|
RuleFor(r => r.IsDeleted, _ => false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
using System.Net;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using Api;
|
||||||
|
using BuildingBlocks.TestBase;
|
||||||
|
using EndToEnd.Test.Fakes;
|
||||||
|
using EndToEnd.Test.Routes;
|
||||||
|
using Flight.Data;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EndToEnd.Test.Flight.Features;
|
||||||
|
|
||||||
|
public class CreateFlightTests : FlightEndToEndTestBase
|
||||||
|
{
|
||||||
|
public CreateFlightTests(TestFixture<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,34 @@
|
|||||||
|
using System.Net;
|
||||||
|
using Api;
|
||||||
|
using BuildingBlocks.TestBase;
|
||||||
|
using EndToEnd.Test.Fakes;
|
||||||
|
using EndToEnd.Test.Routes;
|
||||||
|
using Flight.Data;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EndToEnd.Test.Flight.Features;
|
||||||
|
|
||||||
|
public class GetFlightByIdTests : FlightEndToEndTestBase
|
||||||
|
{
|
||||||
|
public GetFlightByIdTests(TestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task should_retrive_a_flight_by_id_currectly()
|
||||||
|
{
|
||||||
|
//Arrange
|
||||||
|
var command = new FakeCreateFlightMongoCommand().Generate();
|
||||||
|
|
||||||
|
await Fixture.SendAsync(command);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var route = ApiRoutes.Flight.GetFlightById.Replace(ApiRoutes.Flight.Id, command.Id.ToString(), StringComparison.CurrentCulture);
|
||||||
|
var result = await Fixture.HttpClient.GetAsync(route);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using Api;
|
||||||
|
using BuildingBlocks.TestBase;
|
||||||
|
using Flight.Data;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace EndToEnd.Test;
|
||||||
|
|
||||||
|
[Collection(EndToEndTestCollection.Name)]
|
||||||
|
public class FlightEndToEndTestBase : TestBase<Program, FlightDbContext, FlightReadDbContext>
|
||||||
|
{
|
||||||
|
public FlightEndToEndTestBase(TestFixture<Program, FlightDbContext, FlightReadDbContext> integrationTestFixture) : base(integrationTestFixture)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[CollectionDefinition(Name)]
|
||||||
|
public class EndToEndTestCollection : ICollectionFixture<TestFixture<Program, FlightDbContext, FlightReadDbContext>>
|
||||||
|
{
|
||||||
|
public const string Name = "Flight EndToEnd Test";
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
using BuildingBlocks.EFCore;
|
||||||
|
using Flight.Aircrafts.Models;
|
||||||
|
using Flight.Airports.Models;
|
||||||
|
using Flight.Data;
|
||||||
|
using Flight.Data.Seed;
|
||||||
|
using Flight.Flights.Models;
|
||||||
|
using Flight.Seats.Models;
|
||||||
|
using MapsterMapper;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
using MongoDB.Driver.Linq;
|
||||||
|
|
||||||
|
namespace EndToEnd.Test;
|
||||||
|
|
||||||
|
public class FlightTestDataSeeder(
|
||||||
|
FlightDbContext flightDbContext,
|
||||||
|
FlightReadDbContext flightReadDbContext,
|
||||||
|
IMapper mapper
|
||||||
|
) : ITestDataSeeder
|
||||||
|
{
|
||||||
|
public async Task SeedAllAsync()
|
||||||
|
{
|
||||||
|
await SeedAirportAsync();
|
||||||
|
await SeedAircraftAsync();
|
||||||
|
await SeedFlightAsync();
|
||||||
|
await SeedSeatAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SeedAirportAsync()
|
||||||
|
{
|
||||||
|
if (!await EntityFrameworkQueryableExtensions.AnyAsync(flightDbContext.Airports))
|
||||||
|
{
|
||||||
|
await flightDbContext.Airports.AddRangeAsync(InitialData.Airports);
|
||||||
|
await flightDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
if (!await MongoQueryable.AnyAsync(flightReadDbContext.Airport.AsQueryable()))
|
||||||
|
{
|
||||||
|
await flightReadDbContext.Airport.InsertManyAsync(mapper.Map<List<AirportReadModel>>(InitialData.Airports));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SeedAircraftAsync()
|
||||||
|
{
|
||||||
|
if (!await EntityFrameworkQueryableExtensions.AnyAsync(flightDbContext.Aircraft))
|
||||||
|
{
|
||||||
|
await flightDbContext.Aircraft.AddRangeAsync(InitialData.Aircrafts);
|
||||||
|
await flightDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
if (!await MongoQueryable.AnyAsync(flightReadDbContext.Aircraft.AsQueryable()))
|
||||||
|
{
|
||||||
|
await flightReadDbContext.Aircraft.InsertManyAsync(mapper.Map<List<AircraftReadModel>>(InitialData.Aircrafts));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task SeedSeatAsync()
|
||||||
|
{
|
||||||
|
if (!await EntityFrameworkQueryableExtensions.AnyAsync(flightDbContext.Seats))
|
||||||
|
{
|
||||||
|
await flightDbContext.Seats.AddRangeAsync(InitialData.Seats);
|
||||||
|
await flightDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
if (!await MongoQueryable.AnyAsync(flightReadDbContext.Seat.AsQueryable()))
|
||||||
|
{
|
||||||
|
await flightReadDbContext.Seat.InsertManyAsync(mapper.Map<List<SeatReadModel>>(InitialData.Seats));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SeedFlightAsync()
|
||||||
|
{
|
||||||
|
if (!await EntityFrameworkQueryableExtensions.AnyAsync(flightDbContext.Flights))
|
||||||
|
{
|
||||||
|
await flightDbContext.Flights.AddRangeAsync(InitialData.Flights);
|
||||||
|
await flightDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
if (!await MongoQueryable.AnyAsync(flightReadDbContext.Flight.AsQueryable()))
|
||||||
|
{
|
||||||
|
await flightReadDbContext.Flight.InsertManyAsync(mapper.Map<List<FlightReadModel>>(InitialData.Flights));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
namespace EndToEnd.Test.Routes;
|
||||||
|
|
||||||
|
public static class ApiRoutes
|
||||||
|
{
|
||||||
|
private 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";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"parallelizeAssembly": false,
|
||||||
|
"parallelizeTestCollections": false
|
||||||
|
}
|
||||||
@ -109,6 +109,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unit.Test", "2-modular-mono
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "2-modular-monolith-architecture-style\src\Modules\Flight\tests\Integration.Test\Integration.Test.csproj", "{AE7E4AE8-4A5C-44AE-B1FC-2A04824EE29B}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "2-modular-monolith-architecture-style\src\Modules\Flight\tests\Integration.Test\Integration.Test.csproj", "{AE7E4AE8-4A5C-44AE-B1FC-2A04824EE29B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EndToEnd.Test", "2-modular-monolith-architecture-style\src\Modules\Flight\tests\EndToEnd.Test\EndToEnd.Test.csproj", "{7CBA4E35-64EA-BFB3-0507-B7DE1E60CD54}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -215,6 +217,10 @@ Global
|
|||||||
{AE7E4AE8-4A5C-44AE-B1FC-2A04824EE29B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{AE7E4AE8-4A5C-44AE-B1FC-2A04824EE29B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{AE7E4AE8-4A5C-44AE-B1FC-2A04824EE29B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{AE7E4AE8-4A5C-44AE-B1FC-2A04824EE29B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{AE7E4AE8-4A5C-44AE-B1FC-2A04824EE29B}.Release|Any CPU.Build.0 = Release|Any CPU
|
{AE7E4AE8-4A5C-44AE-B1FC-2A04824EE29B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{7CBA4E35-64EA-BFB3-0507-B7DE1E60CD54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{7CBA4E35-64EA-BFB3-0507-B7DE1E60CD54}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7CBA4E35-64EA-BFB3-0507-B7DE1E60CD54}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{7CBA4E35-64EA-BFB3-0507-B7DE1E60CD54}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -269,6 +275,7 @@ Global
|
|||||||
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {AD2FB7C1-8641-47E9-B62D-B3A2D74147D8}
|
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {AD2FB7C1-8641-47E9-B62D-B3A2D74147D8}
|
||||||
{E7B7E65D-DB14-494C-A748-EF90666FB0B1} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
{E7B7E65D-DB14-494C-A748-EF90666FB0B1} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||||
{AE7E4AE8-4A5C-44AE-B1FC-2A04824EE29B} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
{AE7E4AE8-4A5C-44AE-B1FC-2A04824EE29B} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||||
|
{7CBA4E35-64EA-BFB3-0507-B7DE1E60CD54} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {BF29DFD4-25EC-44C4-9DA6-E3AC4B292257}
|
SolutionGuid = {BF29DFD4-25EC-44C4-9DA6-E3AC4B292257}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user