mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-04-10 17:59:38 +08:00
fix: fix ci failed
This commit is contained in:
parent
2a5909bdbd
commit
a62177a6c4
@ -19,6 +19,12 @@
|
||||
"commands": [
|
||||
"aspire"
|
||||
]
|
||||
},
|
||||
"csharpier": {
|
||||
"version": "0.30.6",
|
||||
"commands": [
|
||||
"dotnet-csharpier"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,8 +7,8 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"prepare": "husky && dotnet tool restore",
|
||||
"format": "dotnet format booking-microservices.sln --severity error --verbosity detailed",
|
||||
"ci-format": "dotnet format booking-microservices.sln --verify-no-changes --severity error --verbosity detailed",
|
||||
"format": "dotnet tool run dotnet-csharpier booking-microservices.sln",
|
||||
"ci-format": "dotnet tool run dotnet-csharpier booking-microservices.sln --check",
|
||||
"upgrade-packages": "dotnet outdated --upgrade"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -136,23 +136,10 @@ public class TestFixture<TEntryPoint> : IAsyncLifetime
|
||||
{
|
||||
CancellationTokenSource = new CancellationTokenSource();
|
||||
await StartTestContainerAsync();
|
||||
|
||||
if (ServiceProvider.GetService<ITestHarness>() is { } harness)
|
||||
{
|
||||
await harness.Start();
|
||||
|
||||
// Add a small delay to ensure harness is ready
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DisposeAsync()
|
||||
{
|
||||
if (ServiceProvider.GetService<ITestHarness>() is { } harness)
|
||||
{
|
||||
await harness.Stop();
|
||||
}
|
||||
|
||||
await StopTestContainerAsync();
|
||||
await _factory.DisposeAsync();
|
||||
await CancellationTokenSource.CancelAsync();
|
||||
@ -312,13 +299,6 @@ public class TestFixture<TEntryPoint> : IAsyncLifetime
|
||||
// Start RabbitMQ last and wait extra time
|
||||
await RabbitMqTestContainer.StartAsync();
|
||||
await Task.Delay(5000); // Give RabbitMQ extra time to initialize
|
||||
|
||||
// Verify RabbitMQ is healthy
|
||||
var healthCheck = await RabbitMqTestContainer.ExecAsync(new[] { "rabbitmq-diagnostics", "ping" });
|
||||
if (healthCheck.ExitCode != 0)
|
||||
{
|
||||
await Task.Delay(5000); // Wait more if not healthy
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StopTestContainerAsync()
|
||||
@ -743,4 +723,4 @@ public abstract class TestBase<TEntryPoint, TWContext, TRContext> : TestFixtureC
|
||||
}
|
||||
|
||||
public TestFixture<TEntryPoint, TWContext, TRContext> Fixture { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,154 +2,38 @@ using BuildingBlocks.Contracts.EventBus.Messages;
|
||||
using BuildingBlocks.TestBase;
|
||||
using FluentAssertions;
|
||||
using Integration.Test.Fakes;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Passenger.Data;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Integration.Test.Passenger.Features;
|
||||
|
||||
public class CompleteRegisterPassengerTests : PassengerIntegrationTestBase
|
||||
{
|
||||
public CompleteRegisterPassengerTests(
|
||||
TestFixture<Program, PassengerDbContext, PassengerReadDbContext> integrationTestFactory,
|
||||
ITestOutputHelper outputHelper
|
||||
TestFixture<Program, PassengerDbContext, PassengerReadDbContext> integrationTestFactory
|
||||
)
|
||||
: base(integrationTestFactory)
|
||||
{
|
||||
Fixture.Logger = Fixture.CreateLogger(outputHelper);
|
||||
}
|
||||
: base(integrationTestFactory) { }
|
||||
|
||||
[Fact]
|
||||
public async Task should_complete_register_passenger_and_update_to_db()
|
||||
{
|
||||
// Arrange
|
||||
Fixture.Logger?.LogInformation("Starting CompleteRegisterPassenger test at {Time}", DateTime.UtcNow);
|
||||
var userCreated = new FakeUserCreated().Generate();
|
||||
|
||||
try
|
||||
{
|
||||
// Generate and publish UserCreated event
|
||||
var userCreated = new FakeUserCreated().Generate();
|
||||
Fixture.Logger?.LogInformation(
|
||||
"Generated UserCreated event with PassportNumber: {PassportNumber}",
|
||||
userCreated.PassportNumber
|
||||
);
|
||||
await Fixture.Publish(userCreated);
|
||||
(await Fixture.WaitForPublishing<UserCreated>()).Should().Be(true);
|
||||
(await Fixture.WaitForConsuming<UserCreated>()).Should().Be(true);
|
||||
|
||||
await Fixture.Publish(userCreated);
|
||||
Fixture.Logger?.LogInformation("Published UserCreated event");
|
||||
var command = new FakeCompleteRegisterPassengerCommand(userCreated.PassportNumber).Generate();
|
||||
|
||||
// Wait for publishing with retry logic
|
||||
var published = await WaitForWithRetry(
|
||||
async () => await Fixture.WaitForPublishing<UserCreated>(),
|
||||
"publishing",
|
||||
maxRetries: 3
|
||||
);
|
||||
// Act
|
||||
var response = await Fixture.SendAsync(command);
|
||||
|
||||
published.Should().BeTrue("UserCreated event should be published to message broker");
|
||||
Fixture.Logger?.LogInformation("UserCreated event published successfully");
|
||||
|
||||
// Wait for consuming with retry logic
|
||||
var consumed = await WaitForWithRetry(
|
||||
async () => await Fixture.WaitForConsuming<UserCreated>(),
|
||||
"consuming",
|
||||
maxRetries: 5
|
||||
);
|
||||
|
||||
consumed.Should().BeTrue("UserCreated event should be consumed by the passenger service");
|
||||
Fixture.Logger?.LogInformation("UserCreated event consumed successfully");
|
||||
|
||||
// Small delay to ensure event processing is complete
|
||||
await Task.Delay(1000);
|
||||
|
||||
// Generate and send complete registration command
|
||||
var command = new FakeCompleteRegisterPassengerCommand(userCreated.PassportNumber).Generate();
|
||||
Fixture.Logger?.LogInformation(
|
||||
"Sending CompleteRegisterPassenger command for PassportNumber: {PassportNumber}",
|
||||
command.PassportNumber
|
||||
);
|
||||
|
||||
// Act
|
||||
var response = await Fixture.SendAsync(command);
|
||||
Fixture.Logger?.LogInformation("Received response for CompleteRegisterPassenger command");
|
||||
|
||||
// Assert with detailed logging
|
||||
response.Should().NotBeNull("Response should not be null");
|
||||
Fixture.Logger?.LogInformation("Response is not null");
|
||||
|
||||
response?.PassengerDto.Should().NotBeNull("PassengerDto should not be null");
|
||||
|
||||
response
|
||||
?.PassengerDto?.Name.Should()
|
||||
.Be(
|
||||
userCreated.Name,
|
||||
$"Passenger name should be '{userCreated.Name}' but was '{response?.PassengerDto?.Name}'"
|
||||
);
|
||||
|
||||
response
|
||||
?.PassengerDto?.PassportNumber.Should()
|
||||
.Be(
|
||||
command.PassportNumber,
|
||||
$"Passport number should be '{command.PassportNumber}' but was '{response?.PassengerDto?.PassportNumber}'"
|
||||
);
|
||||
|
||||
response
|
||||
?.PassengerDto?.PassengerType.ToString()
|
||||
.Should()
|
||||
.Be(
|
||||
command.PassengerType.ToString(),
|
||||
$"Passenger type should be '{command.PassengerType}' but was '{response?.PassengerDto?.PassengerType}'"
|
||||
);
|
||||
|
||||
response
|
||||
?.PassengerDto?.Age.Should()
|
||||
.Be(command.Age, $"Age should be {command.Age} but was {response?.PassengerDto?.Age}");
|
||||
|
||||
Fixture.Logger?.LogInformation("All assertions passed successfully");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Fixture.Logger?.LogError(ex, "Test failed with exception: {Message}", ex.Message);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Fixture.Logger?.LogInformation("Test completed at {Time}", DateTime.UtcNow);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
private async Task<bool> WaitForWithRetry(Func<Task<bool>> waitCondition, string operation, int maxRetries = 3)
|
||||
{
|
||||
for (int i = 0; i < maxRetries; i++)
|
||||
{
|
||||
Fixture.Logger?.LogInformation(
|
||||
"Attempt {Attempt}/{MaxRetries} for {Operation}",
|
||||
i + 1,
|
||||
maxRetries,
|
||||
operation
|
||||
);
|
||||
|
||||
var result = await waitCondition();
|
||||
|
||||
if (result)
|
||||
{
|
||||
Fixture.Logger?.LogInformation("{Operation} successful on attempt {Attempt}", operation, i + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i < maxRetries - 1)
|
||||
{
|
||||
var delaySeconds = (i + 1) * 2; // Exponential backoff: 2, 4, 6 seconds
|
||||
Fixture.Logger?.LogWarning(
|
||||
"{Operation} failed on attempt {Attempt}, waiting {Delay}s before retry",
|
||||
operation,
|
||||
i + 1,
|
||||
delaySeconds
|
||||
);
|
||||
await Task.Delay(TimeSpan.FromSeconds(delaySeconds));
|
||||
}
|
||||
}
|
||||
|
||||
Fixture.Logger?.LogError("{Operation} failed after {MaxRetries} attempts", operation, maxRetries);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user