From 1bf20a833429988af5008c5ad720bf25ecd30628 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 16 May 2025 17:59:41 +0330 Subject: [PATCH] feat:compleate modular monolith tests --- .../Features/CreatingBook/V1/CreateBooking.cs | 4 +- .../Infrastructure/GrpcClientExtensions.cs | 2 +- .../src/GrpcClient/Protos/passenger.proto | 4 +- .../Booking/Features/CreateBookingTests.cs | 85 +++++++++++++++++++ .../BookingIntegrationTestBase.cs | 20 +++++ .../Fakes/FakeCreateBookingCommand.cs | 17 ++++ .../Fakes/FakeFlightResponse.cs | 31 +++++++ .../Fakes/FakeGetAvailableSeatsResponse.cs | 36 ++++++++ .../Fakes/FakePassengerResponse.cs | 22 +++++ .../Fakes/FakeReserveSeatResponse.cs | 14 +++ .../Integration.Test/Integration.Test.csproj | 22 +++++ .../tests/Integration.Test/xunit.runner.json | 4 + .../src/Modules/Booking/tests/tests.sln | 25 ++++++ .../Fakes/FakeRegisterNewUserCommand.cs | 16 ++++ .../Identity/Features/RegisterNewUserTests.cs | 34 ++++++++ .../IdentityIntegrationTestBase.cs | 21 +++++ .../IdentityTestDataSeeder.cs | 64 ++++++++++++++ .../Integration.Test/Integration.Test.csproj | 22 +++++ .../tests/Integration.Test/xunit.runner.json | 4 + .../src/Modules/Identity/tests/tests.sln | 25 ++++++ .../FakeCompleteRegisterPassengerCommand.cs | 19 +++++ ...keCompleteRegisterPassengerMongoCommand.cs | 19 +++++ .../Integration.Test/Fakes/FakeUserCreated.cs | 16 ++++ .../Integration.Test/Integration.Test.csproj | 22 +++++ .../CompleteRegisterPassengerTests.cs | 41 +++++++++ .../Features/GetPassengerByIdTests.cs | 56 ++++++++++++ .../PassengerIntegrationTestBase.cs | 21 +++++ .../tests/Integration.Test/xunit.runner.json | 4 + .../src/Modules/Passenger/tests/tests.sln | 25 ++++++ monolith-to-cloud-architecture.sln | 30 +++++++ 30 files changed, 720 insertions(+), 5 deletions(-) create mode 100644 2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Booking/Features/CreateBookingTests.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/BookingIntegrationTestBase.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeCreateBookingCommand.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeFlightResponse.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeGetAvailableSeatsResponse.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakePassengerResponse.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeReserveSeatResponse.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Integration.Test.csproj create mode 100644 2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/xunit.runner.json create mode 100644 2-modular-monolith-architecture-style/src/Modules/Booking/tests/tests.sln create mode 100644 2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Fakes/FakeRegisterNewUserCommand.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Identity/Features/RegisterNewUserTests.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/IdentityIntegrationTestBase.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/IdentityTestDataSeeder.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Integration.Test.csproj create mode 100644 2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/xunit.runner.json create mode 100644 2-modular-monolith-architecture-style/src/Modules/Identity/tests/tests.sln create mode 100644 2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeCompleteRegisterPassengerCommand.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeCompleteRegisterPassengerMongoCommand.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeUserCreated.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Integration.Test.csproj create mode 100644 2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Passenger/Features/CompleteRegisterPassengerTests.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Passenger/Features/GetPassengerByIdTests.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/PassengerIntegrationTestBase.cs create mode 100644 2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/xunit.runner.json create mode 100644 2-modular-monolith-architecture-style/src/Modules/Passenger/tests/tests.sln diff --git a/2-modular-monolith-architecture-style/src/Modules/Booking/src/Booking/Features/CreatingBook/V1/CreateBooking.cs b/2-modular-monolith-architecture-style/src/Modules/Booking/src/Booking/Features/CreatingBook/V1/CreateBooking.cs index 4563c6f..9707156 100644 --- a/2-modular-monolith-architecture-style/src/Modules/Booking/src/Booking/Features/CreatingBook/V1/CreateBooking.cs +++ b/2-modular-monolith-architecture-style/src/Modules/Booking/src/Booking/Features/CreatingBook/V1/CreateBooking.cs @@ -18,7 +18,7 @@ using MediatR; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; -using Passenger; +using BookingPassenger; using ValueObjects; public record CreateBooking(Guid PassengerId, Guid FlightId, string Description) : ICommand @@ -107,7 +107,7 @@ internal class CreateBookingCommandHandler : ICommandHandler integrationTestFixture) : base( + integrationTestFixture) + { + } + + protected override void RegisterTestsServices(IServiceCollection services) + { + MockFlightGrpcServices(services); + MockPassengerGrpcServices(services); + } + + [Fact] + public async Task should_create_booking_to_event_store_currectly() + { + // Arrange + var command = new FakeCreateBookingCommand().Generate(); + + // Act + var response = await Fixture.SendAsync(command); + + // Assert + response?.Id.Should().BeGreaterOrEqualTo(0); + + (await Fixture.WaitForPublishing()).Should().Be(true); + } + + + private void MockPassengerGrpcServices(IServiceCollection services) + { + services.Replace(ServiceDescriptor.Singleton(x => + { + var mockPassenger = Substitute.For(); + + mockPassenger.GetByIdAsync(Arg.Any()) + .Returns(TestCalls.AsyncUnaryCall(Task.FromResult(FakePassengerResponse.Generate()), + Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { })); + + return mockPassenger; + })); + } + + private void MockFlightGrpcServices(IServiceCollection services) + { + services.Replace(ServiceDescriptor.Singleton(x => + { + var mockFlight = Substitute.For(); + + mockFlight.GetByIdAsync(Arg.Any()) + .Returns(TestCalls.AsyncUnaryCall(Task.FromResult(FakeFlightResponse.Generate()), + Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { })); + + mockFlight.GetAvailableSeatsAsync(Arg.Any()) + .Returns(TestCalls.AsyncUnaryCall(Task.FromResult(FakeGetAvailableSeatsResponse.Generate()), + Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { })); + + mockFlight.ReserveSeatAsync(Arg.Any()) + .Returns(TestCalls.AsyncUnaryCall(Task.FromResult(FakeReserveSeatResponse.Generate()), + Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { })); + + return mockFlight; + })); + } + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/BookingIntegrationTestBase.cs b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/BookingIntegrationTestBase.cs new file mode 100644 index 0000000..acbcbae --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/BookingIntegrationTestBase.cs @@ -0,0 +1,20 @@ +using Api; +using Booking.Data; +using BuildingBlocks.TestBase; +using Xunit; + +namespace Integration.Test; + +[Collection(IntegrationTestCollection.Name)] +public class BookingIntegrationTestBase : TestReadBase +{ + public BookingIntegrationTestBase(TestReadFixture integrationTestFixture) : base(integrationTestFixture) + { + } +} + +[CollectionDefinition(Name)] +public class IntegrationTestCollection : ICollectionFixture> +{ + public const string Name = "Booking Integration Test"; +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeCreateBookingCommand.cs b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeCreateBookingCommand.cs new file mode 100644 index 0000000..ff5cb93 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeCreateBookingCommand.cs @@ -0,0 +1,17 @@ +using AutoBogus; + +namespace Integration.Test.Fakes; + +using System; +using global::Booking.Booking.Features.CreatingBook.V1; +using MassTransit; + +public sealed class FakeCreateBookingCommand : AutoFaker +{ + public FakeCreateBookingCommand() + { + RuleFor(r => r.Id, _ => NewId.NextGuid()); + RuleFor(r => r.FlightId, _ => new Guid("3c5c0000-97c6-fc34-2eb9-08db322230c9")); + RuleFor(r => r.PassengerId, _ => new Guid("4c5c8888-97c6-fc34-2eb9-18db322230c1")); + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeFlightResponse.cs b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeFlightResponse.cs new file mode 100644 index 0000000..da25e1d --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeFlightResponse.cs @@ -0,0 +1,31 @@ +using System; +using AutoBogus; +using BookingFlight; +using Google.Protobuf.WellKnownTypes; + +namespace Integration.Test.Fakes; + +public static class FakeFlightResponse +{ + public static GetFlightByIdResult Generate() + { + var flightMock = new GetFlightByIdResult + { + FlightDto = new FlightResponse + { + Id = new Guid("3c5c0000-97c6-fc34-2eb9-08db322230c9").ToString(), + Price = 100, + Status = FlightStatus.Completed, + AircraftId = new Guid("3c5c0000-97c6-fc34-fcd3-08db322230c8").ToString(), + ArriveAirportId = new Guid("3c5c0000-97c6-fc34-a0cb-08db322230c8").ToString(), + ArriveDate = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc).ToTimestamp(), + DepartureDate = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc).ToTimestamp(), + FlightDate = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc).ToTimestamp(), + FlightNumber = "1500B", + DepartureAirportId = new Guid("3c5c0000-97c6-fc34-fc3c-08db322230c8").ToString() + } + }; + + return flightMock; + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeGetAvailableSeatsResponse.cs b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeGetAvailableSeatsResponse.cs new file mode 100644 index 0000000..4c1e431 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeGetAvailableSeatsResponse.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using BookingFlight; + +namespace Integration.Test.Fakes; + +using System; +using MassTransit; + +public static class FakeGetAvailableSeatsResponse +{ + public static GetAvailableSeatsResult Generate() + { + var result = new GetAvailableSeatsResult(); + result.SeatDtos.AddRange(new List + { + new SeatDtoResponse() + { + FlightId = new Guid("3c5c0000-97c6-fc34-2eb9-08db322230c9").ToString(), + Class = SeatClass.Economy, + Type = SeatType.Aisle, + SeatNumber = "33F", + Id = NewId.NextGuid().ToString() + }, + new SeatDtoResponse() + { + FlightId = new Guid("3c5c0000-97c6-fc34-2eb9-08db322230c9").ToString(), + Class = SeatClass.Economy, + Type = SeatType.Window, + SeatNumber = "22D", + Id = NewId.NextGuid().ToString() + } + }); + + return result; + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakePassengerResponse.cs b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakePassengerResponse.cs new file mode 100644 index 0000000..d105a75 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakePassengerResponse.cs @@ -0,0 +1,22 @@ +namespace Integration.Test.Fakes; + +using MassTransit; +using BookingPassenger; + +public static class FakePassengerResponse +{ + public static GetPassengerByIdResult Generate() + { + var result = new GetPassengerByIdResult + { + PassengerDto = new PassengerResponse() + { + Id = NewId.NextGuid().ToString(), + Name = "Test", + PassportNumber = "121618" + } + }; + + return result; + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeReserveSeatResponse.cs b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeReserveSeatResponse.cs new file mode 100644 index 0000000..290b104 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Fakes/FakeReserveSeatResponse.cs @@ -0,0 +1,14 @@ +namespace Integration.Test.Fakes; +using BookingFlight; +using MassTransit; + +public static class FakeReserveSeatResponse +{ + public static ReserveSeatResult Generate() + { + var result = new ReserveSeatResult(); + result.Id = NewId.NextGuid().ToString(); + + return result; + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Integration.Test.csproj b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Integration.Test.csproj new file mode 100644 index 0000000..d28f617 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/Integration.Test.csproj @@ -0,0 +1,22 @@ + + + + + PreserveNewest + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/xunit.runner.json b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/xunit.runner.json new file mode 100644 index 0000000..9db029b --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/Integration.Test/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "parallelizeAssembly": false, + "parallelizeTestCollections": false +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Booking/tests/tests.sln b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/tests.sln new file mode 100644 index 0000000..05ce8b7 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Booking/tests/tests.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.35906.104 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "Integration.Test\Integration.Test.csproj", "{A0D4B2AE-53E4-454D-A1CB-E51168D016F3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BF30A2EF-A06D-4A7E-B99B-304221C5FC0C} + EndGlobalSection +EndGlobal diff --git a/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Fakes/FakeRegisterNewUserCommand.cs b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Fakes/FakeRegisterNewUserCommand.cs new file mode 100644 index 0000000..f351009 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Fakes/FakeRegisterNewUserCommand.cs @@ -0,0 +1,16 @@ +using AutoBogus; + +namespace Integration.Test.Fakes; + +using global::Identity.Identity.Features.RegisteringNewUser.V1; + +public class FakeRegisterNewUserCommand : AutoFaker +{ + public FakeRegisterNewUserCommand() + { + RuleFor(r => r.Username, x => "TestMyUser"); + RuleFor(r => r.Password, _ => "Password@123"); + RuleFor(r => r.ConfirmPassword, _ => "Password@123"); + RuleFor(r => r.Email, _ => "test@test.com"); + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Identity/Features/RegisterNewUserTests.cs b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Identity/Features/RegisterNewUserTests.cs new file mode 100644 index 0000000..15e33ed --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Identity/Features/RegisterNewUserTests.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using BuildingBlocks.Contracts.EventBus.Messages; +using BuildingBlocks.TestBase; +using FluentAssertions; +using Api; +using Identity.Data; +using Integration.Test.Fakes; +using Xunit; + +namespace Integration.Test.Identity.Features; + +public class RegisterNewUserTests : IdentityIntegrationTestBase +{ + public RegisterNewUserTests( + TestWriteFixture integrationTestFactory) : base(integrationTestFactory) + { + } + + [Fact] + public async Task should_create_new_user_to_db_and_publish_message_to_broker() + { + // Arrange + var command = new FakeRegisterNewUserCommand().Generate(); + + // Act + var response = await Fixture.SendAsync(command); + + // Assert + response?.Should().NotBeNull(); + response?.Username.Should().Be(command.Username); + + (await Fixture.WaitForPublishing()).Should().Be(true); + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/IdentityIntegrationTestBase.cs b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/IdentityIntegrationTestBase.cs new file mode 100644 index 0000000..d13b068 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/IdentityIntegrationTestBase.cs @@ -0,0 +1,21 @@ +using BuildingBlocks.TestBase; +using Api; +using Identity.Data; +using Xunit; + +namespace Integration.Test; + +[Collection(IntegrationTestCollection.Name)] +public class IdentityIntegrationTestBase : TestWriteBase +{ + public IdentityIntegrationTestBase(TestWriteFixture integrationTestFactory) + : base(integrationTestFactory) + { + } +} + +[CollectionDefinition(Name)] +public class IntegrationTestCollection : ICollectionFixture> +{ + public const string Name = "Identity Integration Test"; +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/IdentityTestDataSeeder.cs b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/IdentityTestDataSeeder.cs new file mode 100644 index 0000000..7bb371e --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/IdentityTestDataSeeder.cs @@ -0,0 +1,64 @@ +using BuildingBlocks.Constants; +using BuildingBlocks.Contracts.EventBus.Messages; +using BuildingBlocks.Core; +using BuildingBlocks.EFCore; +using Identity.Data.Seed; +using Identity.Identity.Constants; +using Identity.Identity.Models; +using Microsoft.AspNetCore.Identity; + +namespace Integration.Test; + +public class IdentityTestDataSeeder( + UserManager userManager, + RoleManager roleManager, + IEventDispatcher eventDispatcher +) + : ITestDataSeeder +{ + public async Task SeedAllAsync() + { + await SeedRoles(); + await SeedUsers(); + } + + private async Task SeedRoles() + { + if (await roleManager.RoleExistsAsync(IdentityConstant.Role.Admin) == false) + { + await roleManager.CreateAsync(new Role { Name = IdentityConstant.Role.Admin }); + } + + if (await roleManager.RoleExistsAsync(IdentityConstant.Role.User) == false) + { + await roleManager.CreateAsync(new Role { Name = IdentityConstant.Role.User }); + } + } + + private async Task SeedUsers() + { + if (await userManager.FindByNameAsync("samh") == null) + { + var result = await userManager.CreateAsync(InitialData.Users.First(), "Admin@123456"); + + if (result.Succeeded) + { + await userManager.AddToRoleAsync(InitialData.Users.First(), IdentityConstant.Role.Admin); + + await eventDispatcher.SendAsync(new UserCreated(InitialData.Users.First().Id, InitialData.Users.First().FirstName + " " + InitialData.Users.First().LastName, InitialData.Users.First().PassPortNumber)); + } + } + + if (await userManager.FindByNameAsync("meysamh2") == null) + { + var result = await userManager.CreateAsync(InitialData.Users.Last(), "User@123456"); + + if (result.Succeeded) + { + await userManager.AddToRoleAsync(InitialData.Users.Last(), IdentityConstant.Role.User); + + await eventDispatcher.SendAsync(new UserCreated(InitialData.Users.Last().Id, InitialData.Users.Last().FirstName + " " + InitialData.Users.Last().LastName, InitialData.Users.Last().PassPortNumber)); + } + } + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Integration.Test.csproj b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Integration.Test.csproj new file mode 100644 index 0000000..d28f617 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/Integration.Test.csproj @@ -0,0 +1,22 @@ + + + + + PreserveNewest + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/xunit.runner.json b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/xunit.runner.json new file mode 100644 index 0000000..9db029b --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/Integration.Test/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "parallelizeAssembly": false, + "parallelizeTestCollections": false +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Identity/tests/tests.sln b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/tests.sln new file mode 100644 index 0000000..05ce8b7 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Identity/tests/tests.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.35906.104 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "Integration.Test\Integration.Test.csproj", "{A0D4B2AE-53E4-454D-A1CB-E51168D016F3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BF30A2EF-A06D-4A7E-B99B-304221C5FC0C} + EndGlobalSection +EndGlobal diff --git a/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeCompleteRegisterPassengerCommand.cs b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeCompleteRegisterPassengerCommand.cs new file mode 100644 index 0000000..d470686 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeCompleteRegisterPassengerCommand.cs @@ -0,0 +1,19 @@ +using AutoBogus; +using Passenger.Passengers.Enums; + +namespace Integration.Test.Fakes; + +using global::Passenger.Passengers.Features.CompletingRegisterPassenger.V1; +using MassTransit; + +public sealed class FakeCompleteRegisterPassengerCommand : AutoFaker +{ + public FakeCompleteRegisterPassengerCommand(string passportNumber) + { + RuleFor(r => r.Id, _ => NewId.NextGuid()); + RuleFor(r => r.PassportNumber, _ => passportNumber); + RuleFor(r => r.PassengerType, _ => PassengerType.Male); + RuleFor(r => r.Age, _ => 30); + } +} + diff --git a/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeCompleteRegisterPassengerMongoCommand.cs b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeCompleteRegisterPassengerMongoCommand.cs new file mode 100644 index 0000000..f4c3f05 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeCompleteRegisterPassengerMongoCommand.cs @@ -0,0 +1,19 @@ +namespace Integration.Test.Fakes; + +using AutoBogus; +using global::Passenger.Passengers.Enums; +using global::Passenger.Passengers.Features.CompletingRegisterPassenger.V1; +using MassTransit; + +public class FakeCompleteRegisterPassengerMongoCommand : AutoFaker +{ + public FakeCompleteRegisterPassengerMongoCommand() + { + RuleFor(r => r.Id, _ => NewId.NextGuid()); + RuleFor(r => r.Name, _ => "Sam"); + RuleFor(r => r.PassportNumber, _ => "123456789"); + RuleFor(r => r.Age, _ => 30); + RuleFor(r => r.IsDeleted, _ => false); + RuleFor(r => r.PassengerType, _ => PassengerType.Male); + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeUserCreated.cs b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeUserCreated.cs new file mode 100644 index 0000000..de9e78e --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Fakes/FakeUserCreated.cs @@ -0,0 +1,16 @@ +using AutoBogus; +using BuildingBlocks.Contracts.EventBus.Messages; + +namespace Integration.Test.Fakes; + +using MassTransit; + +public class FakeUserCreated : AutoFaker +{ + public FakeUserCreated() + { + RuleFor(r => r.Id, _ => NewId.NextGuid()); + RuleFor(r => r.Name, _ => "Sam"); + RuleFor(r => r.PassportNumber, _ => "123456789"); + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Integration.Test.csproj b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Integration.Test.csproj new file mode 100644 index 0000000..9dbbc5b --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Integration.Test.csproj @@ -0,0 +1,22 @@ + + + + + PreserveNewest + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Passenger/Features/CompleteRegisterPassengerTests.cs b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Passenger/Features/CompleteRegisterPassengerTests.cs new file mode 100644 index 0000000..817b2db --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Passenger/Features/CompleteRegisterPassengerTests.cs @@ -0,0 +1,41 @@ +using System.Threading.Tasks; +using BuildingBlocks.Contracts.EventBus.Messages; +using BuildingBlocks.TestBase; +using FluentAssertions; +using Integration.Test.Fakes; +using Api; +using Passenger.Data; +using Xunit; + +namespace Integration.Test.Passenger.Features; +public class CompleteRegisterPassengerTests : PassengerIntegrationTestBase +{ + + public CompleteRegisterPassengerTests( + TestFixture integrationTestFactory) : base(integrationTestFactory) + { + } + + [Fact] + public async Task should_complete_register_passenger_and_update_to_db() + { + // Arrange + var userCreated = new FakeUserCreated().Generate(); + + await Fixture.Publish(userCreated); + (await Fixture.WaitForPublishing()).Should().Be(true); + (await Fixture.WaitForConsuming()).Should().Be(true); + + var command = new FakeCompleteRegisterPassengerCommand(userCreated.PassportNumber).Generate(); + + // Act + var response = await Fixture.SendAsync(command); + + // Assert + response.Should().NotBeNull(); + response?.PassengerDto?.Name.Should().Be(userCreated.Name); + response?.PassengerDto?.PassportNumber.Should().Be(command.PassportNumber); + response?.PassengerDto?.PassengerType.ToString().Should().Be(command.PassengerType.ToString()); + response?.PassengerDto?.Age.Should().Be(command.Age); + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Passenger/Features/GetPassengerByIdTests.cs b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Passenger/Features/GetPassengerByIdTests.cs new file mode 100644 index 0000000..be66ab6 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/Passenger/Features/GetPassengerByIdTests.cs @@ -0,0 +1,56 @@ +using System.Threading.Tasks; +using BuildingBlocks.TestBase; +using FluentAssertions; +using Integration.Test.Fakes; +using Passenger; +using Api; +using Passenger.Data; +using Xunit; + +namespace Integration.Test.Passenger.Features; + +using global::Passenger.Passengers.Features.GettingPassengerById.V1; + +public class GetPassengerByIdTests : PassengerIntegrationTestBase +{ + public GetPassengerByIdTests( + TestFixture integrationTestFactory) : base(integrationTestFactory) + { + } + + [Fact] + public async Task should_retrive_a_passenger_by_id_currectly() + { + // Arrange + var command = new FakeCompleteRegisterPassengerMongoCommand().Generate(); + + await Fixture.SendAsync(command); + + var query = new GetPassengerById(command.Id); + + // Act + var response = await Fixture.SendAsync(query); + + // Assert + response.Should().NotBeNull(); + response?.PassengerDto?.Id.Should().Be(command.Id); + } + + [Fact] + public async Task should_retrive_a_passenger_by_id_from_grpc_service() + { + // Arrange + var command = new FakeCompleteRegisterPassengerMongoCommand().Generate(); + + await Fixture.SendAsync(command); + + var passengerGrpcClient = new PassengerGrpcService.PassengerGrpcServiceClient(Fixture.Channel); + + // Act + var response = await passengerGrpcClient.GetByIdAsync(new GetByIdRequest { Id = command.Id.ToString() }); + + // Assert + response?.Should().NotBeNull(); + response?.PassengerDto?.Id.Should().Be(command.Id.ToString()); + } +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/PassengerIntegrationTestBase.cs b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/PassengerIntegrationTestBase.cs new file mode 100644 index 0000000..46cb3ae --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/PassengerIntegrationTestBase.cs @@ -0,0 +1,21 @@ +using BuildingBlocks.TestBase; +using Api; +using Passenger.Data; +using Xunit; + +namespace Integration.Test; + +[Collection(IntegrationTestCollection.Name)] +public class PassengerIntegrationTestBase : TestBase +{ + public PassengerIntegrationTestBase(TestFixture integrationTestFactory) + : base(integrationTestFactory) + { + } +} + +[CollectionDefinition(Name)] +public class IntegrationTestCollection : ICollectionFixture> +{ + public const string Name = "Passenger Integration Test"; +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/xunit.runner.json b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/xunit.runner.json new file mode 100644 index 0000000..9db029b --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/Integration.Test/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "parallelizeAssembly": false, + "parallelizeTestCollections": false +} diff --git a/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/tests.sln b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/tests.sln new file mode 100644 index 0000000..05ce8b7 --- /dev/null +++ b/2-modular-monolith-architecture-style/src/Modules/Passenger/tests/tests.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.35906.104 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "Integration.Test\Integration.Test.csproj", "{A0D4B2AE-53E4-454D-A1CB-E51168D016F3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A0D4B2AE-53E4-454D-A1CB-E51168D016F3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BF30A2EF-A06D-4A7E-B99B-304221C5FC0C} + EndGlobalSection +EndGlobal diff --git a/monolith-to-cloud-architecture.sln b/monolith-to-cloud-architecture.sln index df06619..abf159a 100644 --- a/monolith-to-cloud-architecture.sln +++ b/monolith-to-cloud-architecture.sln @@ -111,6 +111,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "2-modul 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 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Booking", "Booking", "{5DE68C42-13B1-44D0-B966-7EE083B9B2B5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "2-modular-monolith-architecture-style\src\Modules\Booking\tests\Integration.Test\Integration.Test.csproj", "{A23A47DB-7C4B-411C-9078-AE567407FEB1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Identity", "Identity", "{F59A33C1-6197-4F76-82BF-D7F2CC9D6438}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "2-modular-monolith-architecture-style\src\Modules\Identity\tests\Integration.Test\Integration.Test.csproj", "{39DE2739-1426-2288-DF5D-B58D339E5CDE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Passenger", "Passenger", "{687C40B6-F05C-4794-981D-5DA28C07E3D2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "2-modular-monolith-architecture-style\src\Modules\Passenger\tests\Integration.Test\Integration.Test.csproj", "{87AE85AA-A092-2130-C912-97B9B252845A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -221,6 +233,18 @@ Global {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 + {A23A47DB-7C4B-411C-9078-AE567407FEB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A23A47DB-7C4B-411C-9078-AE567407FEB1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A23A47DB-7C4B-411C-9078-AE567407FEB1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A23A47DB-7C4B-411C-9078-AE567407FEB1}.Release|Any CPU.Build.0 = Release|Any CPU + {39DE2739-1426-2288-DF5D-B58D339E5CDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {39DE2739-1426-2288-DF5D-B58D339E5CDE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {39DE2739-1426-2288-DF5D-B58D339E5CDE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {39DE2739-1426-2288-DF5D-B58D339E5CDE}.Release|Any CPU.Build.0 = Release|Any CPU + {87AE85AA-A092-2130-C912-97B9B252845A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87AE85AA-A092-2130-C912-97B9B252845A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87AE85AA-A092-2130-C912-97B9B252845A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87AE85AA-A092-2130-C912-97B9B252845A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -276,6 +300,12 @@ Global {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} + {5DE68C42-13B1-44D0-B966-7EE083B9B2B5} = {AD2FB7C1-8641-47E9-B62D-B3A2D74147D8} + {A23A47DB-7C4B-411C-9078-AE567407FEB1} = {5DE68C42-13B1-44D0-B966-7EE083B9B2B5} + {F59A33C1-6197-4F76-82BF-D7F2CC9D6438} = {AD2FB7C1-8641-47E9-B62D-B3A2D74147D8} + {39DE2739-1426-2288-DF5D-B58D339E5CDE} = {F59A33C1-6197-4F76-82BF-D7F2CC9D6438} + {687C40B6-F05C-4794-981D-5DA28C07E3D2} = {AD2FB7C1-8641-47E9-B62D-B3A2D74147D8} + {87AE85AA-A092-2130-C912-97B9B252845A} = {687C40B6-F05C-4794-981D-5DA28C07E3D2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BF29DFD4-25EC-44C4-9DA6-E3AC4B292257}