mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-04-10 17:59:38 +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.AddFlightModules();
|
||||
builder.AddIdentityModules();
|
||||
builder.AddPassengerModules();
|
||||
builder.AddBookingModules();
|
||||
builder.AddFlightModules();
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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}.Release|Any CPU.ActiveCfg = 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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -269,6 +275,7 @@ Global
|
||||
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {AD2FB7C1-8641-47E9-B62D-B3A2D74147D8}
|
||||
{E7B7E65D-DB14-494C-A748-EF90666FB0B1} = {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
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {BF29DFD4-25EC-44C4-9DA6-E3AC4B292257}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user