diff --git a/2-modular-monolith-architecture-style/src/Api/src/Program.cs b/2-modular-monolith-architecture-style/src/Api/src/Program.cs
index 5fb7504..8fffce4 100644
--- a/2-modular-monolith-architecture-style/src/Api/src/Program.cs
+++ b/2-modular-monolith-architecture-style/src/Api/src/Program.cs
@@ -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();
diff --git a/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/EndToEnd.Test.csproj b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/EndToEnd.Test.csproj
new file mode 100644
index 0000000..a0c6e9f
--- /dev/null
+++ b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/EndToEnd.Test.csproj
@@ -0,0 +1,22 @@
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
diff --git a/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Fakes/FakeCreateFlightCommand.cs b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Fakes/FakeCreateFlightCommand.cs
new file mode 100644
index 0000000..83df003
--- /dev/null
+++ b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Fakes/FakeCreateFlightCommand.cs
@@ -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
+{
+ 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);
+ }
+}
diff --git a/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Fakes/FakeCreateFlightMongoCommand.cs b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Fakes/FakeCreateFlightMongoCommand.cs
new file mode 100644
index 0000000..603c455
--- /dev/null
+++ b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Fakes/FakeCreateFlightMongoCommand.cs
@@ -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
+{
+ 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);
+ }
+}
+
diff --git a/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Flight/Features/CreateFlightTests.cs b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Flight/Features/CreateFlightTests.cs
new file mode 100644
index 0000000..9e64a7c
--- /dev/null
+++ b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Flight/Features/CreateFlightTests.cs
@@ -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 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);
+ }
+}
diff --git a/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Flight/Features/GetFlightByIdTests.cs b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Flight/Features/GetFlightByIdTests.cs
new file mode 100644
index 0000000..609b039
--- /dev/null
+++ b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Flight/Features/GetFlightByIdTests.cs
@@ -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 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);
+ }
+}
diff --git a/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/FlightEndToEndTestBase.cs b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/FlightEndToEndTestBase.cs
new file mode 100644
index 0000000..ba8dad5
--- /dev/null
+++ b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/FlightEndToEndTestBase.cs
@@ -0,0 +1,20 @@
+using Api;
+using BuildingBlocks.TestBase;
+using Flight.Data;
+using Xunit;
+
+namespace EndToEnd.Test;
+
+[Collection(EndToEndTestCollection.Name)]
+public class FlightEndToEndTestBase : TestBase
+{
+ public FlightEndToEndTestBase(TestFixture integrationTestFixture) : base(integrationTestFixture)
+ {
+ }
+}
+
+[CollectionDefinition(Name)]
+public class EndToEndTestCollection : ICollectionFixture>
+{
+ public const string Name = "Flight EndToEnd Test";
+}
diff --git a/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/FlightTestDataSeeder.cs b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/FlightTestDataSeeder.cs
new file mode 100644
index 0000000..862356f
--- /dev/null
+++ b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/FlightTestDataSeeder.cs
@@ -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>(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>(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>(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>(InitialData.Flights));
+ }
+ }
+ }
+}
diff --git a/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Routes/ApiRoutes.cs b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Routes/ApiRoutes.cs
new file mode 100644
index 0000000..0517f29
--- /dev/null
+++ b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/Routes/ApiRoutes.cs
@@ -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";
+ }
+}
diff --git a/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/xunit.runner.json b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/xunit.runner.json
new file mode 100644
index 0000000..9db029b
--- /dev/null
+++ b/2-modular-monolith-architecture-style/src/Modules/Flight/tests/EndToEnd.Test/xunit.runner.json
@@ -0,0 +1,4 @@
+{
+ "parallelizeAssembly": false,
+ "parallelizeTestCollections": false
+}
diff --git a/monolith-to-cloud-architecture.sln b/monolith-to-cloud-architecture.sln
index dbd5d44..df06619 100644
--- a/monolith-to-cloud-architecture.sln
+++ b/monolith-to-cloud-architecture.sln
@@ -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}