diff --git a/booking-microservices-sample.sln b/booking-microservices-sample.sln
index 2bbb2ce..cbb185a 100644
--- a/booking-microservices-sample.sln
+++ b/booking-microservices-sample.sln
@@ -55,7 +55,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Passenger", "src\Services\P
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Passenger.Api", "src\Services\Passenger\src\Passenger.Api\Passenger.Api.csproj", "{4F29C4B6-A7DA-4A92-9CDB-42FE98238837}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Flight\tests\Integration.Test.csproj", "{92E4D21C-2904-46F5-947D-74138003B19F}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Flight\tests\IntegrationTest\Integration.Test.csproj", "{6B6603C8-D8B6-4775-9C7A-FFE6058070C2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Identity\tests\IntegrationTest\Integration.Test.csproj", "{BC7871B8-BB18-4BCC-96A8-7324C11BF4A2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Passenger\tests\IntegrationTest\Integration.Test.csproj", "{539364C8-88B1-48A3-8406-D0B19FF30509}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -89,7 +93,9 @@ Global
{BEE7A9D7-1BFC-477E-B070-4BE63C0361AA} = {F39D8F09-6233-4495-ACD0-F98904993B7E}
{6D7BCECE-D77D-4C57-A296-CA6E728E94B7} = {85DA00E5-CC11-463C-8577-C34967C328F7}
{4F29C4B6-A7DA-4A92-9CDB-42FE98238837} = {85DA00E5-CC11-463C-8577-C34967C328F7}
- {92E4D21C-2904-46F5-947D-74138003B19F} = {C6EE337B-91EA-472A-87C7-E9528408CE59}
+ {6B6603C8-D8B6-4775-9C7A-FFE6058070C2} = {C6EE337B-91EA-472A-87C7-E9528408CE59}
+ {BC7871B8-BB18-4BCC-96A8-7324C11BF4A2} = {295284BA-D4E4-40AA-A2C2-BE36343F7DE6}
+ {539364C8-88B1-48A3-8406-D0B19FF30509} = {C1EBE17D-BFAD-47DA-88EB-BB073B84593E}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A2D7C5C4-5148-4C3E-BB12-B7A197A290F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -132,9 +138,17 @@ Global
{4F29C4B6-A7DA-4A92-9CDB-42FE98238837}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F29C4B6-A7DA-4A92-9CDB-42FE98238837}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F29C4B6-A7DA-4A92-9CDB-42FE98238837}.Release|Any CPU.Build.0 = Release|Any CPU
- {92E4D21C-2904-46F5-947D-74138003B19F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {92E4D21C-2904-46F5-947D-74138003B19F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {92E4D21C-2904-46F5-947D-74138003B19F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {92E4D21C-2904-46F5-947D-74138003B19F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6B6603C8-D8B6-4775-9C7A-FFE6058070C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6B6603C8-D8B6-4775-9C7A-FFE6058070C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6B6603C8-D8B6-4775-9C7A-FFE6058070C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6B6603C8-D8B6-4775-9C7A-FFE6058070C2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BC7871B8-BB18-4BCC-96A8-7324C11BF4A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BC7871B8-BB18-4BCC-96A8-7324C11BF4A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BC7871B8-BB18-4BCC-96A8-7324C11BF4A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BC7871B8-BB18-4BCC-96A8-7324C11BF4A2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {539364C8-88B1-48A3-8406-D0B19FF30509}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {539364C8-88B1-48A3-8406-D0B19FF30509}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {539364C8-88B1-48A3-8406-D0B19FF30509}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {539364C8-88B1-48A3-8406-D0B19FF30509}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/src/BuildingBlocks/BuildingBlocks.csproj b/src/BuildingBlocks/BuildingBlocks.csproj
index 27e8d73..655ddae 100644
--- a/src/BuildingBlocks/BuildingBlocks.csproj
+++ b/src/BuildingBlocks/BuildingBlocks.csproj
@@ -7,120 +7,126 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/src/Services/Flight/tests/Integration.Test.csproj b/src/Services/Flight/tests/Integration.Test.csproj
deleted file mode 100644
index 6d79eb8..0000000
--- a/src/Services/Flight/tests/Integration.Test.csproj
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
- net6.0
- false
-
-
-
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Services/Flight/tests/Aircraft/CreateAircraftTests.cs b/src/Services/Flight/tests/IntegrationTest/Aircraft/Features/CreateAircraftTests.cs
similarity index 54%
rename from src/Services/Flight/tests/Aircraft/CreateAircraftTests.cs
rename to src/Services/Flight/tests/IntegrationTest/Aircraft/Features/CreateAircraftTests.cs
index 060c463..bae7504 100644
--- a/src/Services/Flight/tests/Aircraft/CreateAircraftTests.cs
+++ b/src/Services/Flight/tests/IntegrationTest/Aircraft/Features/CreateAircraftTests.cs
@@ -2,18 +2,22 @@
using BuildingBlocks.Contracts.EventBus.Messages;
using FluentAssertions;
using Integration.Test.Fakes;
+using MassTransit;
+using MassTransit.Testing;
using Xunit;
-namespace Integration.Test.Aircraft;
+namespace Integration.Test.Aircraft.Features;
[Collection(nameof(TestFixture))]
public class CreateAircraftTests
{
private readonly TestFixture _fixture;
+ private readonly ITestHarness _testHarness;
public CreateAircraftTests(TestFixture fixture)
{
_fixture = fixture;
+ _testHarness = fixture.TestHarness;
}
[Fact]
@@ -23,12 +27,12 @@ public class CreateAircraftTests
var command = new FakeCreateAircraftCommand().Generate();
// Act
- var aircraftResponse = await _fixture.SendAsync(command);
+ var response = await _fixture.SendAsync(command);
// Assert
- aircraftResponse.Should().NotBeNull();
- aircraftResponse?.Name.Should().Be(command.Name);
- (await _fixture.IsFaultyPublished()).Should().BeFalse();
- (await _fixture.IsPublished()).Should().BeTrue();
+ response?.Should().NotBeNull();
+ response?.Name.Should().Be(command.Name);
+ (await _testHarness.Published.Any>()).Should().BeFalse();
+ (await _testHarness.Published.Any()).Should().BeTrue();
}
}
diff --git a/src/Services/Flight/tests/Airport/CreateAirportTests.cs b/src/Services/Flight/tests/IntegrationTest/Airport/Features/CreateAirportTests.cs
similarity index 54%
rename from src/Services/Flight/tests/Airport/CreateAirportTests.cs
rename to src/Services/Flight/tests/IntegrationTest/Airport/Features/CreateAirportTests.cs
index 2b73679..65cf55b 100644
--- a/src/Services/Flight/tests/Airport/CreateAirportTests.cs
+++ b/src/Services/Flight/tests/IntegrationTest/Airport/Features/CreateAirportTests.cs
@@ -2,18 +2,22 @@
using BuildingBlocks.Contracts.EventBus.Messages;
using FluentAssertions;
using Integration.Test.Fakes;
+using MassTransit;
+using MassTransit.Testing;
using Xunit;
-namespace Integration.Test.Airport;
+namespace Integration.Test.Airport.Features;
[Collection(nameof(TestFixture))]
public class CreateAirportTests
{
private readonly TestFixture _fixture;
+ private readonly ITestHarness _testHarness;
public CreateAirportTests(TestFixture fixture)
{
_fixture = fixture;
+ _testHarness = fixture.TestHarness;
}
[Fact]
@@ -23,12 +27,12 @@ public class CreateAirportTests
var command = new FakeCreateAirportCommand().Generate();
// Act
- var airportResponse = await _fixture.SendAsync(command);
+ var response = await _fixture.SendAsync(command);
// Assert
- airportResponse.Should().NotBeNull();
- airportResponse?.Name.Should().Be(command.Name);
- (await _fixture.IsFaultyPublished()).Should().BeFalse();
- (await _fixture.IsPublished()).Should().BeTrue();
+ response?.Should().NotBeNull();
+ response?.Name.Should().Be(command.Name);
+ (await _testHarness.Published.Any>()).Should().BeFalse();
+ (await _testHarness.Published.Any()).Should().BeTrue();
}
}
diff --git a/src/Services/Flight/tests/Fakes/FakeCreateAircraftCommand.cs b/src/Services/Flight/tests/IntegrationTest/Fakes/FakeCreateAircraftCommand.cs
similarity index 100%
rename from src/Services/Flight/tests/Fakes/FakeCreateAircraftCommand.cs
rename to src/Services/Flight/tests/IntegrationTest/Fakes/FakeCreateAircraftCommand.cs
diff --git a/src/Services/Flight/tests/Fakes/FakeCreateAirportCommand.cs b/src/Services/Flight/tests/IntegrationTest/Fakes/FakeCreateAirportCommand.cs
similarity index 100%
rename from src/Services/Flight/tests/Fakes/FakeCreateAirportCommand.cs
rename to src/Services/Flight/tests/IntegrationTest/Fakes/FakeCreateAirportCommand.cs
diff --git a/src/Services/Flight/tests/Fakes/FakeCreateFlightCommand.cs b/src/Services/Flight/tests/IntegrationTest/Fakes/FakeCreateFlightCommand.cs
similarity index 100%
rename from src/Services/Flight/tests/Fakes/FakeCreateFlightCommand.cs
rename to src/Services/Flight/tests/IntegrationTest/Fakes/FakeCreateFlightCommand.cs
diff --git a/src/Services/Flight/tests/Fakes/FakeUpdateFlightCommand.cs b/src/Services/Flight/tests/IntegrationTest/Fakes/FakeUpdateFlightCommand.cs
similarity index 100%
rename from src/Services/Flight/tests/Fakes/FakeUpdateFlightCommand.cs
rename to src/Services/Flight/tests/IntegrationTest/Fakes/FakeUpdateFlightCommand.cs
diff --git a/src/Services/Flight/tests/Flight/CreateFlightTests.cs b/src/Services/Flight/tests/IntegrationTest/Flight/Features/CreateFlightTests.cs
similarity index 53%
rename from src/Services/Flight/tests/Flight/CreateFlightTests.cs
rename to src/Services/Flight/tests/IntegrationTest/Flight/Features/CreateFlightTests.cs
index cd7a3b8..926edca 100644
--- a/src/Services/Flight/tests/Flight/CreateFlightTests.cs
+++ b/src/Services/Flight/tests/IntegrationTest/Flight/Features/CreateFlightTests.cs
@@ -2,18 +2,22 @@
using BuildingBlocks.Contracts.EventBus.Messages;
using FluentAssertions;
using Integration.Test.Fakes;
+using MassTransit;
+using MassTransit.Testing;
using Xunit;
-namespace Integration.Test.Flight;
+namespace Integration.Test.Flight.Features;
[Collection(nameof(TestFixture))]
public class CreateFlightTests
{
private readonly TestFixture _fixture;
+ private readonly ITestHarness _testHarness;
public CreateFlightTests(TestFixture fixture)
{
_fixture = fixture;
+ _testHarness = _fixture.TestHarness;
}
[Fact]
@@ -23,12 +27,12 @@ public class CreateFlightTests
var command = new FakeCreateFlightCommand().Generate();
// Act
- var flightResponse = await _fixture.SendAsync(command);
+ var response = await _fixture.SendAsync(command);
// Assert
- flightResponse.Should().NotBeNull();
- flightResponse?.FlightNumber.Should().Be(command.FlightNumber);
- (await _fixture.IsFaultyPublished()).Should().BeFalse();
- (await _fixture.IsPublished()).Should().BeTrue();
+ response.Should().NotBeNull();
+ response?.FlightNumber.Should().Be(command.FlightNumber);
+ (await _testHarness.Published.Any>()).Should().BeFalse();
+ (await _testHarness.Published.Any()).Should().BeTrue();
}
}
diff --git a/src/Services/Flight/tests/Flight/DeleteFlightTests.cs b/src/Services/Flight/tests/IntegrationTest/Flight/Features/DeleteFlightTests.cs
similarity index 81%
rename from src/Services/Flight/tests/Flight/DeleteFlightTests.cs
rename to src/Services/Flight/tests/IntegrationTest/Flight/Features/DeleteFlightTests.cs
index f43d14f..530ec0d 100644
--- a/src/Services/Flight/tests/Flight/DeleteFlightTests.cs
+++ b/src/Services/Flight/tests/IntegrationTest/Flight/Features/DeleteFlightTests.cs
@@ -1,23 +1,26 @@
using System.Linq;
using System.Threading.Tasks;
using BuildingBlocks.Contracts.EventBus.Messages;
-using Flight.Flights.Features.CreateFlight;
using Flight.Flights.Features.DeleteFlight;
using FluentAssertions;
using Integration.Test.Fakes;
+using MassTransit;
+using MassTransit.Testing;
using Microsoft.EntityFrameworkCore;
using Xunit;
-namespace Integration.Test.Flight;
+namespace Integration.Test.Flight.Features;
[Collection(nameof(TestFixture))]
public class DeleteFlightTests
{
private readonly TestFixture _fixture;
+ private readonly ITestHarness _testHarness;
public DeleteFlightTests(TestFixture fixture)
{
_fixture = fixture;
+ _testHarness = fixture.TestHarness;
}
[Fact]
@@ -43,8 +46,8 @@ public class DeleteFlightTests
// Assert
deletedFlight?.IsDeleted.Should().BeTrue();
- (await _fixture.IsFaultyPublished()).Should().BeFalse();
- (await _fixture.IsPublished()).Should().BeTrue();
+ (await _testHarness.Published.Any>()).Should().BeFalse();
+ (await _testHarness.Published.Any()).Should().BeTrue();
}
}
diff --git a/src/Services/Flight/tests/Flight/GetAvailableFlightsTests.cs b/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetAvailableFlightsTests.cs
similarity index 81%
rename from src/Services/Flight/tests/Flight/GetAvailableFlightsTests.cs
rename to src/Services/Flight/tests/IntegrationTest/Flight/Features/GetAvailableFlightsTests.cs
index 83e2be8..30cc0a3 100644
--- a/src/Services/Flight/tests/Flight/GetAvailableFlightsTests.cs
+++ b/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetAvailableFlightsTests.cs
@@ -1,16 +1,11 @@
using System.Linq;
using System.Threading.Tasks;
-using AutoBogus;
-using Bogus;
-using BuildingBlocks.IdsGenerator;
-using Flight.Flights.Features.CreateFlight;
using Flight.Flights.Features.GetAvailableFlights;
-using Flight.Flights.Features.GetFlightById;
using FluentAssertions;
using Integration.Test.Fakes;
using Xunit;
-namespace Integration.Test.Flight;
+namespace Integration.Test.Flight.Features;
[Collection(nameof(TestFixture))]
public class GetAvailableFlightsTests
@@ -42,10 +37,10 @@ public class GetAvailableFlightsTests
var query = new GetAvailableFlightsQuery();
// Act
- var flightResponse = await _fixture.SendAsync(query);
+ var response = (await _fixture.SendAsync(query))?.ToList();
// Assert
- flightResponse?.Should().NotBeNull();
- flightResponse?.Count().Should().BeGreaterOrEqualTo(2);
+ response?.Should().NotBeNull();
+ response?.Count().Should().BeGreaterOrEqualTo(2);
}
}
diff --git a/src/Services/Flight/tests/Flight/GetFlightByIdTests.cs b/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetFlightByIdTests.cs
similarity index 77%
rename from src/Services/Flight/tests/Flight/GetFlightByIdTests.cs
rename to src/Services/Flight/tests/IntegrationTest/Flight/Features/GetFlightByIdTests.cs
index 39e394e..7de000d 100644
--- a/src/Services/Flight/tests/Flight/GetFlightByIdTests.cs
+++ b/src/Services/Flight/tests/IntegrationTest/Flight/Features/GetFlightByIdTests.cs
@@ -1,12 +1,10 @@
using System.Threading.Tasks;
-using BuildingBlocks.Contracts.EventBus.Messages;
-using Flight.Flights.Features.CreateFlight;
using Flight.Flights.Features.GetFlightById;
using FluentAssertions;
using Integration.Test.Fakes;
using Xunit;
-namespace Integration.Test.Flight;
+namespace Integration.Test.Flight.Features;
[Collection(nameof(TestFixture))]
public class GetFlightByIdTests
@@ -31,10 +29,10 @@ public class GetFlightByIdTests
var query = new GetFlightByIdQuery(flightEntity.Id);
// Act
- var flightResponse = await _fixture.SendAsync(query);
+ var response = await _fixture.SendAsync(query);
// Assert
- flightResponse.Should().NotBeNull();
- flightResponse?.Id.Should().Be(flightEntity.Id);
+ response.Should().NotBeNull();
+ response?.Id.Should().Be(flightEntity.Id);
}
}
diff --git a/src/Services/Flight/tests/Flight/UpdateFlightTests.cs b/src/Services/Flight/tests/IntegrationTest/Flight/Features/UpdateFlightTests.cs
similarity index 66%
rename from src/Services/Flight/tests/Flight/UpdateFlightTests.cs
rename to src/Services/Flight/tests/IntegrationTest/Flight/Features/UpdateFlightTests.cs
index 1458c7b..9393bb2 100644
--- a/src/Services/Flight/tests/Flight/UpdateFlightTests.cs
+++ b/src/Services/Flight/tests/IntegrationTest/Flight/Features/UpdateFlightTests.cs
@@ -1,22 +1,23 @@
-using System.Linq;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using BuildingBlocks.Contracts.EventBus.Messages;
-using Flight.Flights.Features.CreateFlight;
using FluentAssertions;
using Integration.Test.Fakes;
-using Microsoft.EntityFrameworkCore;
+using MassTransit;
+using MassTransit.Testing;
using Xunit;
-namespace Integration.Test.Flight;
+namespace Integration.Test.Flight.Features;
[Collection(nameof(TestFixture))]
public class UpdateFlightTests
{
private readonly TestFixture _fixture;
+ private readonly ITestHarness _testHarness;
public UpdateFlightTests(TestFixture fixture)
{
_fixture = fixture;
+ _testHarness = _fixture.TestHarness;
}
[Fact]
@@ -33,13 +34,13 @@ public class UpdateFlightTests
var command = new FakeUpdateFlightCommand(flightEntity.Id).Generate();
// Act
- var flightResponse = await _fixture.SendAsync(command);
+ var response = await _fixture.SendAsync(command);
// Assert
- flightResponse.Should().NotBeNull();
- flightResponse?.Id.Should().Be(flightEntity?.Id);
- flightResponse?.Price.Should().NotBe(flightEntity?.Price);
- (await _fixture.IsFaultyPublished()).Should().BeFalse();
- (await _fixture.IsPublished()).Should().BeTrue();
+ response.Should().NotBeNull();
+ response?.Id.Should().Be(flightEntity?.Id);
+ response?.Price.Should().NotBe(flightEntity?.Price);
+ (await _testHarness.Published.Any>()).Should().BeFalse();
+ (await _testHarness.Published.Any()).Should().BeTrue();
}
}
diff --git a/src/Services/Flight/tests/IntegrationTest/Integration.Test.csproj b/src/Services/Flight/tests/IntegrationTest/Integration.Test.csproj
new file mode 100644
index 0000000..13598de
--- /dev/null
+++ b/src/Services/Flight/tests/IntegrationTest/Integration.Test.csproj
@@ -0,0 +1,27 @@
+
+
+
+ net6.0
+ false
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
diff --git a/src/Services/Flight/tests/TestFixture.cs b/src/Services/Flight/tests/IntegrationTest/TestFixture.cs
similarity index 74%
rename from src/Services/Flight/tests/TestFixture.cs
rename to src/Services/Flight/tests/IntegrationTest/TestFixture.cs
index e1447e4..de307a6 100644
--- a/src/Services/Flight/tests/TestFixture.cs
+++ b/src/Services/Flight/tests/IntegrationTest/TestFixture.cs
@@ -17,6 +17,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
+using Microsoft.VisualStudio.TestPlatform.TestHost;
using NSubstitute;
using Respawn;
using Serilog;
@@ -33,14 +34,18 @@ public class TestFixtureCollection : ICollectionFixture
// ref: https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-6.0
// ref: https://github.com/jbogard/ContosoUniversityDotNetCore-Pages/blob/master/ContosoUniversity.IntegrationTests/SliceFixture.cs
// ref: https://github.com/jasontaylordev/CleanArchitecture/blob/main/tests/Application.IntegrationTests/Testing.cs
+// ref: https://github.com/MassTransit/MassTransit/blob/00d6992286911a437b63b93c89a56e920b053c11/src/MassTransit.TestFramework/InMemoryTestFixture.cs
public class TestFixture : IAsyncLifetime
{
private Checkpoint _checkpoint;
private IConfiguration _configuration;
private WebApplicationFactory _factory;
- private ITestHarness _harness;
private IServiceScopeFactory _scopeFactory;
private HttpClient _httpClient;
+ private ITestHarness _testHarness;
+
+ public ITestHarness TestHarness => _testHarness;
+
public async Task InitializeAsync()
{
@@ -69,9 +74,9 @@ public class TestFixture : IAsyncLifetime
});
}));
- _harness = _factory.Services.GetTestHarness();
+ _testHarness = _factory.Services.GetTestHarness();
- await _harness.Start();
+ await _testHarness.Start();
_configuration = _factory.Services.GetRequiredService();
_scopeFactory = _factory.Services.GetRequiredService();
@@ -85,7 +90,7 @@ public class TestFixture : IAsyncLifetime
public async Task DisposeAsync()
{
- _harness.Cancel();
+ _testHarness.Cancel();
await _factory.DisposeAsync();
await _checkpoint.Reset(_configuration.GetConnectionString("DefaultConnection"));
}
@@ -242,69 +247,6 @@ public class TestFixture : IAsyncLifetime
});
}
-
- // ref: https://github.com/MassTransit/MassTransit/blob/00d6992286911a437b63b93c89a56e920b053c11/src/MassTransit.TestFramework/InMemoryTestFixture.cs
- // ref: https://wrapt.dev/blog/building-an-event-driven-dotnet-application-integration-testing
-
- ///
- /// Publishes a message to the bus, and waits for the specified response.
- ///
- /// The message that should be published.
- /// The message that should be published.
- public async Task PublishMessage(object message)
- where TMessage : class
- {
- await _harness.Bus.Publish(message);
- }
-
- ///
- /// Confirm if there was a fault when publishing for this harness.
- ///
- /// The message that should be published.
- /// A boolean of true if there was a fault for a message of the given type when published.
- public Task IsFaultyPublished()
- where TMessage : class
- {
- return _harness.Published.Any>();
- }
-
- ///
- /// Confirm that a message has been published for this harness.
- ///
- /// The message that should be published.
- /// A boolean of true if a message of the given type has been published.
- public Task IsPublished()
- where TMessage : class
- {
- return _harness.Published.Any();
- }
-
- ///
- /// Confirm that a message has been consumed for this harness.
- ///
- /// The message that should be consumed.
- /// A boolean of true if a message of the given type has been consumed.
- public Task IsConsumed()
- where TMessage : class
- {
- return _harness.Consumed.Any();
- }
-
- ///
- /// The desired consumer consumed the message.
- ///
- /// The message that should be consumed.
- /// The consumer of the message.
- /// A boolean of true if a message of the given type has been consumed by the given consumer.
- public Task IsConsumed()
- where TMessage : class
- where TConsumedBy : class, IConsumer
- {
- using var scope = _scopeFactory.CreateScope();
- var consumerHarness = scope.ServiceProvider.GetRequiredService>();
- return consumerHarness.Consumed.Any();
- }
-
private async Task EnsureDatabaseAsync()
{
using var scope = _scopeFactory.CreateScope();
@@ -323,7 +265,7 @@ public class TestFixture : IAsyncLifetime
using var scope = serviceProvider.CreateScope();
httpContextAccessorMock.HttpContext = new DefaultHttpContext {RequestServices = scope.ServiceProvider};
- httpContextAccessorMock.HttpContext.Request.Host = new HostString("localhost", 5000);
+ httpContextAccessorMock.HttpContext.Request.Host = new HostString("localhost", 5004);
httpContextAccessorMock.HttpContext.Request.Scheme = "http";
return httpContextAccessorMock;
diff --git a/src/Services/Identity/src/Identity.Api/Program.cs b/src/Services/Identity/src/Identity.Api/Program.cs
index f24dc23..aed3eb7 100644
--- a/src/Services/Identity/src/Identity.Api/Program.cs
+++ b/src/Services/Identity/src/Identity.Api/Program.cs
@@ -79,3 +79,5 @@ app.UseEndpoints(endpoints =>
app.MapGet("/", x => x.Response.WriteAsync(appOptions.Name));
app.Run();
+
+public partial class Program {}
diff --git a/src/Services/Identity/src/Identity.Api/appsettings.test.json b/src/Services/Identity/src/Identity.Api/appsettings.test.json
new file mode 100644
index 0000000..1243108
--- /dev/null
+++ b/src/Services/Identity/src/Identity.Api/appsettings.test.json
@@ -0,0 +1,19 @@
+{
+ "ConnectionStrings": {
+ "DefaultConnection": "Server=.\\sqlexpress;Database=IdentityDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true"
+ },
+ "RabbitMq": {
+ "HostName": "localhost",
+ "ExchangeName": "identity",
+ "UserName": "guest",
+ "Password": "guest"
+ },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "Microsoft": "Debug",
+ "Microsoft.Hosting.Lifetime": "Debug",
+ "Microsoft.EntityFrameworkCore.Database.Command": "Debug"
+ }
+ }
+}
diff --git a/src/Services/Identity/src/Identity/Data/IdentityDataSeeder.cs b/src/Services/Identity/src/Identity/Data/IdentityDataSeeder.cs
index 65f72a6..d6556f4 100644
--- a/src/Services/Identity/src/Identity/Data/IdentityDataSeeder.cs
+++ b/src/Services/Identity/src/Identity/Data/IdentityDataSeeder.cs
@@ -35,14 +35,14 @@ public class IdentityDataSeeder : IDataSeeder
private async Task SeedUsers()
{
- if (await _userManager.FindByNameAsync("meysamh") == null)
+ if (await _userManager.FindByNameAsync("samh") == null)
{
var user = new ApplicationUser
{
- FirstName = "Meysam",
- LastName = "Hadeli",
- UserName = "meysamh",
- Email = "meysam@test.com",
+ FirstName = "Sam",
+ LastName = "H",
+ UserName = "samh",
+ Email = "sam@test.com",
SecurityStamp = Guid.NewGuid().ToString()
};
@@ -56,10 +56,10 @@ public class IdentityDataSeeder : IDataSeeder
{
var user = new ApplicationUser
{
- FirstName = "Meysam",
- LastName = "Hadeli",
- UserName = "meysamh2",
- Email = "meysam2@test.com",
+ FirstName = "Sam",
+ LastName = "H",
+ UserName = "samh2",
+ Email = "sam2@test.com",
SecurityStamp = Guid.NewGuid().ToString()
};
diff --git a/src/Services/Identity/tests/IntegrationTest/Fakes/FakeRegisterNewUserCommand.cs b/src/Services/Identity/tests/IntegrationTest/Fakes/FakeRegisterNewUserCommand.cs
new file mode 100644
index 0000000..111e34d
--- /dev/null
+++ b/src/Services/Identity/tests/IntegrationTest/Fakes/FakeRegisterNewUserCommand.cs
@@ -0,0 +1,14 @@
+using AutoBogus;
+using Identity.Identity.Features.RegisterNewUser;
+
+namespace Integration.Test.Fakes;
+
+public class FakeRegisterNewUserCommand : AutoFaker
+{
+ public FakeRegisterNewUserCommand()
+ {
+ RuleFor(r => r.Password, _ => "Password@123");
+ RuleFor(r => r.ConfirmPassword, _ => "Password@123");
+ RuleFor(r => r.Email, _ => "test@test.com");
+ }
+}
diff --git a/src/Services/Identity/tests/IntegrationTest/Identity/Features/RegisterNewUserTests.cs b/src/Services/Identity/tests/IntegrationTest/Identity/Features/RegisterNewUserTests.cs
new file mode 100644
index 0000000..5c2c6e3
--- /dev/null
+++ b/src/Services/Identity/tests/IntegrationTest/Identity/Features/RegisterNewUserTests.cs
@@ -0,0 +1,38 @@
+using System.Threading.Tasks;
+using BuildingBlocks.Contracts.EventBus.Messages;
+using FluentAssertions;
+using Integration.Test.Fakes;
+using MassTransit;
+using MassTransit.Testing;
+using Xunit;
+
+namespace Integration.Test.Identity.Features;
+
+[Collection(nameof(TestFixture))]
+public class RegisterNewUserTests
+{
+ private readonly TestFixture _fixture;
+ private readonly ITestHarness _testHarness;
+
+ public RegisterNewUserTests(TestFixture fixture)
+ {
+ _fixture = fixture;
+ _testHarness = _fixture.TestHarness;
+ }
+
+ [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 _testHarness.Published.Any>()).Should().BeFalse();
+ (await _testHarness.Published.Any()).Should().BeTrue();
+ }
+}
diff --git a/src/Services/Identity/tests/IntegrationTest/Integration.Test.csproj b/src/Services/Identity/tests/IntegrationTest/Integration.Test.csproj
new file mode 100644
index 0000000..959edd3
--- /dev/null
+++ b/src/Services/Identity/tests/IntegrationTest/Integration.Test.csproj
@@ -0,0 +1,30 @@
+
+
+
+ net6.0
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
diff --git a/src/Services/Identity/tests/IntegrationTest/TestFixture.cs b/src/Services/Identity/tests/IntegrationTest/TestFixture.cs
new file mode 100644
index 0000000..4eb9531
--- /dev/null
+++ b/src/Services/Identity/tests/IntegrationTest/TestFixture.cs
@@ -0,0 +1,271 @@
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+using BuildingBlocks.Domain.Model;
+using BuildingBlocks.EFCore;
+using BuildingBlocks.MassTransit;
+using BuildingBlocks.Web;
+using Identity.Data;
+using MassTransit;
+using MassTransit.Testing;
+using MediatR;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc.Testing;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Hosting;
+using NSubstitute;
+using Respawn;
+using Serilog;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Integration.Test;
+
+[CollectionDefinition(nameof(TestFixture))]
+public class TestFixtureCollection : ICollectionFixture
+{
+}
+
+// ref: https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-6.0
+// ref: https://github.com/jbogard/ContosoUniversityDotNetCore-Pages/blob/master/ContosoUniversity.IntegrationTests/SliceFixture.cs
+// ref: https://github.com/jasontaylordev/CleanArchitecture/blob/main/tests/Application.IntegrationTests/Testing.cs
+// ref: https://github.com/MassTransit/MassTransit/blob/00d6992286911a437b63b93c89a56e920b053c11/src/MassTransit.TestFramework/InMemoryTestFixture.cs
+public class TestFixture : IAsyncLifetime
+{
+ private Checkpoint _checkpoint;
+ private IConfiguration _configuration;
+ private WebApplicationFactory _factory;
+ private HttpClient _httpClient;
+ private IServiceScopeFactory _scopeFactory;
+
+ public ITestHarness TestHarness { get; private set; }
+
+
+ public async Task InitializeAsync()
+ {
+ Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "test");
+
+ _factory = new WebApplicationFactory()
+ .WithWebHostBuilder(builder => builder.ConfigureServices(services =>
+ {
+ services.RemoveAll(typeof(IHostedService));
+ services.ReplaceSingleton(AddHttpContextAccessorMock);
+ services.ReplaceScoped();
+ services.AddMassTransitTestHarness(x =>
+ {
+ x.UsingRabbitMq((context, cfg) =>
+ {
+ var rabbitMqOptions = services.GetOptions("RabbitMq");
+ var host = rabbitMqOptions.HostName;
+
+ cfg.Host(host, h =>
+ {
+ h.Username(rabbitMqOptions.UserName);
+ h.Password(rabbitMqOptions.Password);
+ });
+ cfg.ConfigureEndpoints(context);
+ });
+ });
+ }));
+
+ TestHarness = _factory.Services.GetTestHarness();
+
+ await TestHarness.Start();
+
+ _configuration = _factory.Services.GetRequiredService();
+ _scopeFactory = _factory.Services.GetRequiredService();
+
+ _httpClient = _factory.CreateClient(new WebApplicationFactoryClientOptions {AllowAutoRedirect = false});
+
+ _checkpoint = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
+
+ await EnsureDatabaseAsync();
+ }
+
+ public async Task DisposeAsync()
+ {
+ TestHarness.Cancel();
+ await _factory.DisposeAsync();
+ await _checkpoint.Reset(_configuration.GetConnectionString("DefaultConnection"));
+ }
+
+ // ref: https://github.com/trbenning/serilog-sinks-xunit
+ public ILogger CreateLogger(ITestOutputHelper output)
+ {
+ if (output != null)
+ return new LoggerConfiguration()
+ .WriteTo.TestOutput(output)
+ .CreateLogger();
+
+ return null;
+ }
+
+ public HttpClient CreateClient()
+ {
+ return _httpClient;
+ }
+
+ public async Task ExecuteScopeAsync(Func action)
+ {
+ using var scope = _scopeFactory.CreateScope();
+ await action(scope.ServiceProvider);
+ }
+
+ public async Task ExecuteScopeAsync(Func> action)
+ {
+ using var scope = _scopeFactory.CreateScope();
+
+ var result = await action(scope.ServiceProvider);
+
+ return result;
+ }
+
+ public Task ExecuteDbContextAsync(Func action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService()));
+ }
+
+ public Task ExecuteDbContextAsync(Func action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService()).AsTask());
+ }
+
+ public Task ExecuteDbContextAsync(Func action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService(), sp.GetService()));
+ }
+
+ public Task ExecuteDbContextAsync(Func> action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService()));
+ }
+
+ public Task ExecuteDbContextAsync(Func> action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService()).AsTask());
+ }
+
+ public Task ExecuteDbContextAsync(Func> action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService(), sp.GetService()));
+ }
+
+ public Task InsertAsync(params T[] entities) where T : class
+ {
+ return ExecuteDbContextAsync(db =>
+ {
+ foreach (var entity in entities) db.Set().Add(entity);
+
+ return db.SaveChangesAsync();
+ });
+ }
+
+ public Task InsertAsync(TEntity entity) where TEntity : class
+ {
+ return ExecuteDbContextAsync(db =>
+ {
+ db.Set().Add(entity);
+
+ return db.SaveChangesAsync();
+ });
+ }
+
+ public Task InsertAsync(TEntity entity, TEntity2 entity2)
+ where TEntity : class
+ where TEntity2 : class
+ {
+ return ExecuteDbContextAsync(db =>
+ {
+ db.Set().Add(entity);
+ db.Set().Add(entity2);
+
+ return db.SaveChangesAsync();
+ });
+ }
+
+ public Task InsertAsync(TEntity entity, TEntity2 entity2, TEntity3 entity3)
+ where TEntity : class
+ where TEntity2 : class
+ where TEntity3 : class
+ {
+ return ExecuteDbContextAsync(db =>
+ {
+ db.Set().Add(entity);
+ db.Set().Add(entity2);
+ db.Set().Add(entity3);
+
+ return db.SaveChangesAsync();
+ });
+ }
+
+ public Task InsertAsync(TEntity entity, TEntity2 entity2, TEntity3 entity3,
+ TEntity4 entity4)
+ where TEntity : class
+ where TEntity2 : class
+ where TEntity3 : class
+ where TEntity4 : class
+ {
+ return ExecuteDbContextAsync(db =>
+ {
+ db.Set().Add(entity);
+ db.Set().Add(entity2);
+ db.Set().Add(entity3);
+ db.Set().Add(entity4);
+
+ return db.SaveChangesAsync();
+ });
+ }
+
+ public Task FindAsync(long id)
+ where T : class, IEntity
+ {
+ return ExecuteDbContextAsync(db => db.Set().FindAsync(id).AsTask());
+ }
+
+ public Task SendAsync(IRequest request)
+ {
+ return ExecuteScopeAsync(sp =>
+ {
+ var mediator = sp.GetRequiredService();
+
+ return mediator.Send(request);
+ });
+ }
+
+ public Task SendAsync(IRequest request)
+ {
+ return ExecuteScopeAsync(sp =>
+ {
+ var mediator = sp.GetRequiredService();
+
+ return mediator.Send(request);
+ });
+ }
+
+ private async Task EnsureDatabaseAsync()
+ {
+ using var scope = _scopeFactory.CreateScope();
+
+ var context = scope.ServiceProvider.GetRequiredService();
+ var seeders = scope.ServiceProvider.GetServices();
+
+ await context.Database.MigrateAsync();
+
+ foreach (var seeder in seeders) await seeder.SeedAllAsync();
+ }
+
+ private IHttpContextAccessor AddHttpContextAccessorMock(IServiceProvider serviceProvider)
+ {
+ var httpContextAccessorMock = Substitute.For();
+ using var scope = serviceProvider.CreateScope();
+ httpContextAccessorMock.HttpContext = new DefaultHttpContext {RequestServices = scope.ServiceProvider};
+
+ httpContextAccessorMock.HttpContext.Request.Host = new HostString("localhost", 6005);
+ httpContextAccessorMock.HttpContext.Request.Scheme = "http";
+
+ return httpContextAccessorMock;
+ }
+}
diff --git a/src/Services/Passenger/src/Passenger.Api/Program.cs b/src/Services/Passenger/src/Passenger.Api/Program.cs
index 9bc1bc5..a27aeb0 100644
--- a/src/Services/Passenger/src/Passenger.Api/Program.cs
+++ b/src/Services/Passenger/src/Passenger.Api/Program.cs
@@ -80,3 +80,5 @@ app.UseEndpoints(endpoints =>
app.MapGet("/", x => x.Response.WriteAsync(appOptions.Name));
app.Run();
+
+public partial class Program {}
diff --git a/src/Services/Passenger/src/Passenger.Api/appsettings.test.json b/src/Services/Passenger/src/Passenger.Api/appsettings.test.json
new file mode 100644
index 0000000..0d920ea
--- /dev/null
+++ b/src/Services/Passenger/src/Passenger.Api/appsettings.test.json
@@ -0,0 +1,19 @@
+{
+ "ConnectionStrings": {
+ "DefaultConnection": "Server=.\\sqlexpress;Database=PassengerDB_Test;Trusted_Connection=True;MultipleActiveResultSets=true"
+ },
+ "RabbitMq": {
+ "HostName": "localhost",
+ "ExchangeName": "passenger",
+ "UserName": "guest",
+ "Password": "guest"
+ },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "Microsoft": "Debug",
+ "Microsoft.Hosting.Lifetime": "Debug",
+ "Microsoft.EntityFrameworkCore.Database.Command": "Debug"
+ }
+ }
+}
diff --git a/src/Services/Passenger/tests/IntegrationTest/Integration.Test.csproj b/src/Services/Passenger/tests/IntegrationTest/Integration.Test.csproj
new file mode 100644
index 0000000..ff3abdc
--- /dev/null
+++ b/src/Services/Passenger/tests/IntegrationTest/Integration.Test.csproj
@@ -0,0 +1,34 @@
+
+
+
+ net6.0
+ enable
+
+ false
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Services/Passenger/tests/IntegrationTest/TestFixture.cs b/src/Services/Passenger/tests/IntegrationTest/TestFixture.cs
new file mode 100644
index 0000000..9efe577
--- /dev/null
+++ b/src/Services/Passenger/tests/IntegrationTest/TestFixture.cs
@@ -0,0 +1,270 @@
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+using BuildingBlocks.Domain.Model;
+using BuildingBlocks.EFCore;
+using BuildingBlocks.MassTransit;
+using BuildingBlocks.Web;
+using MassTransit;
+using MassTransit.Testing;
+using MediatR;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc.Testing;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Hosting;
+using NSubstitute;
+using Passenger.Data;
+using Respawn;
+using Serilog;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Integration.Test;
+
+[CollectionDefinition(nameof(TestFixture))]
+public class TestFixtureCollection : ICollectionFixture
+{
+}
+
+// ref: https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-6.0
+// ref: https://github.com/jbogard/ContosoUniversityDotNetCore-Pages/blob/master/ContosoUniversity.IntegrationTests/SliceFixture.cs
+// ref: https://github.com/jasontaylordev/CleanArchitecture/blob/main/tests/Application.IntegrationTests/Testing.cs
+// ref: https://github.com/MassTransit/MassTransit/blob/00d6992286911a437b63b93c89a56e920b053c11/src/MassTransit.TestFramework/InMemoryTestFixture.cs
+public class TestFixture : IAsyncLifetime
+{
+ private Checkpoint _checkpoint;
+ private IConfiguration _configuration;
+ private WebApplicationFactory _factory;
+ private HttpClient _httpClient;
+ private IServiceScopeFactory _scopeFactory;
+
+ public ITestHarness TestHarness { get; private set; }
+
+
+ public async Task InitializeAsync()
+ {
+ Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "test");
+
+ _factory = new WebApplicationFactory()
+ .WithWebHostBuilder(builder => builder.ConfigureServices(services =>
+ {
+ services.RemoveAll(typeof(IHostedService));
+ services.ReplaceSingleton(AddHttpContextAccessorMock);
+ services.AddMassTransitTestHarness(x =>
+ {
+ x.UsingRabbitMq((context, cfg) =>
+ {
+ var rabbitMqOptions = services.GetOptions("RabbitMq");
+ var host = rabbitMqOptions.HostName;
+
+ cfg.Host(host, h =>
+ {
+ h.Username(rabbitMqOptions.UserName);
+ h.Password(rabbitMqOptions.Password);
+ });
+ cfg.ConfigureEndpoints(context);
+ });
+ });
+ }));
+
+ TestHarness = _factory.Services.GetTestHarness();
+
+ await TestHarness.Start();
+
+ _configuration = _factory.Services.GetRequiredService();
+ _scopeFactory = _factory.Services.GetRequiredService();
+
+ _httpClient = _factory.CreateClient(new WebApplicationFactoryClientOptions {AllowAutoRedirect = false});
+
+ _checkpoint = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
+
+ await EnsureDatabaseAsync();
+ }
+
+ public async Task DisposeAsync()
+ {
+ TestHarness.Cancel();
+ await _factory.DisposeAsync();
+ await _checkpoint.Reset(_configuration.GetConnectionString("DefaultConnection"));
+ }
+
+ // ref: https://github.com/trbenning/serilog-sinks-xunit
+ public ILogger CreateLogger(ITestOutputHelper output)
+ {
+ if (output != null)
+ return new LoggerConfiguration()
+ .WriteTo.TestOutput(output)
+ .CreateLogger();
+
+ return null;
+ }
+
+ public HttpClient CreateClient()
+ {
+ return _httpClient;
+ }
+
+ public async Task ExecuteScopeAsync(Func action)
+ {
+ using var scope = _scopeFactory.CreateScope();
+ await action(scope.ServiceProvider);
+ }
+
+ public async Task ExecuteScopeAsync(Func> action)
+ {
+ using var scope = _scopeFactory.CreateScope();
+
+ var result = await action(scope.ServiceProvider);
+
+ return result;
+ }
+
+ public Task ExecuteDbContextAsync(Func action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService()));
+ }
+
+ public Task ExecuteDbContextAsync(Func action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService()).AsTask());
+ }
+
+ public Task ExecuteDbContextAsync(Func action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService(), sp.GetService()));
+ }
+
+ public Task ExecuteDbContextAsync(Func> action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService()));
+ }
+
+ public Task ExecuteDbContextAsync(Func> action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService()).AsTask());
+ }
+
+ public Task ExecuteDbContextAsync(Func> action)
+ {
+ return ExecuteScopeAsync(sp => action(sp.GetService(), sp.GetService()));
+ }
+
+ public Task InsertAsync(params T[] entities) where T : class
+ {
+ return ExecuteDbContextAsync(db =>
+ {
+ foreach (var entity in entities) db.Set().Add(entity);
+
+ return db.SaveChangesAsync();
+ });
+ }
+
+ public Task InsertAsync(TEntity entity) where TEntity : class
+ {
+ return ExecuteDbContextAsync(db =>
+ {
+ db.Set().Add(entity);
+
+ return db.SaveChangesAsync();
+ });
+ }
+
+ public Task InsertAsync(TEntity entity, TEntity2 entity2)
+ where TEntity : class
+ where TEntity2 : class
+ {
+ return ExecuteDbContextAsync(db =>
+ {
+ db.Set().Add(entity);
+ db.Set().Add(entity2);
+
+ return db.SaveChangesAsync();
+ });
+ }
+
+ public Task InsertAsync(TEntity entity, TEntity2 entity2, TEntity3 entity3)
+ where TEntity : class
+ where TEntity2 : class
+ where TEntity3 : class
+ {
+ return ExecuteDbContextAsync(db =>
+ {
+ db.Set().Add(entity);
+ db.Set().Add(entity2);
+ db.Set().Add(entity3);
+
+ return db.SaveChangesAsync();
+ });
+ }
+
+ public Task InsertAsync(TEntity entity, TEntity2 entity2, TEntity3 entity3,
+ TEntity4 entity4)
+ where TEntity : class
+ where TEntity2 : class
+ where TEntity3 : class
+ where TEntity4 : class
+ {
+ return ExecuteDbContextAsync(db =>
+ {
+ db.Set().Add(entity);
+ db.Set().Add(entity2);
+ db.Set().Add(entity3);
+ db.Set().Add(entity4);
+
+ return db.SaveChangesAsync();
+ });
+ }
+
+ public Task FindAsync(long id)
+ where T : class, IEntity
+ {
+ return ExecuteDbContextAsync(db => db.Set().FindAsync(id).AsTask());
+ }
+
+ public Task SendAsync(IRequest request)
+ {
+ return ExecuteScopeAsync(sp =>
+ {
+ var mediator = sp.GetRequiredService();
+
+ return mediator.Send(request);
+ });
+ }
+
+ public Task SendAsync(IRequest request)
+ {
+ return ExecuteScopeAsync(sp =>
+ {
+ var mediator = sp.GetRequiredService();
+
+ return mediator.Send(request);
+ });
+ }
+
+ private async Task EnsureDatabaseAsync()
+ {
+ using var scope = _scopeFactory.CreateScope();
+
+ var context = scope.ServiceProvider.GetRequiredService();
+ var seeders = scope.ServiceProvider.GetServices();
+
+ await context.Database.MigrateAsync();
+
+ foreach (var seeder in seeders) await seeder.SeedAllAsync();
+ }
+
+ private IHttpContextAccessor AddHttpContextAccessorMock(IServiceProvider serviceProvider)
+ {
+ var httpContextAccessorMock = Substitute.For();
+ using var scope = serviceProvider.CreateScope();
+ httpContextAccessorMock.HttpContext = new DefaultHttpContext {RequestServices = scope.ServiceProvider};
+
+ httpContextAccessorMock.HttpContext.Request.Host = new HostString("localhost", 6012);
+ httpContextAccessorMock.HttpContext.Request.Scheme = "http";
+
+ return httpContextAccessorMock;
+ }
+}
diff --git a/src/Services/Passenger/tests/IntegrationTest/UnitTest1.cs b/src/Services/Passenger/tests/IntegrationTest/UnitTest1.cs
new file mode 100644
index 0000000..3b10395
--- /dev/null
+++ b/src/Services/Passenger/tests/IntegrationTest/UnitTest1.cs
@@ -0,0 +1,12 @@
+using Xunit;
+
+namespace Integration.Test;
+
+public class UnitTest1
+{
+ [Fact]
+ public void Test1()
+ {
+
+ }
+}
\ No newline at end of file