From 8f3d2b9c8c87f824c075bca375400e78adead2cf Mon Sep 17 00:00:00 2001 From: meysamhadeli Date: Fri, 13 Jan 2023 01:37:42 +0330 Subject: [PATCH] fix: Fix bug reset rabbitmq in test base --- .editorconfig | 4 +- src/BuildingBlocks/EFCore/Extensions.cs | 4 +- src/BuildingBlocks/MassTransit/Extensions.cs | 10 +-- src/BuildingBlocks/Mongo/Extensions.cs | 6 +- .../PersistMessageProcessor/Extensions.cs | 4 +- src/BuildingBlocks/TestBase/TestBase.cs | 85 +++++++++++-------- .../Web/ConfigurationExtensions.cs | 12 +++ .../Fakes/FakeRegisterNewUserCommand.cs | 3 +- 8 files changed, 73 insertions(+), 55 deletions(-) diff --git a/.editorconfig b/.editorconfig index bebe7c4..18b259f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,7 +13,6 @@ root = true [*] charset = utf-8 indent_style = space -indent_size = 2 insert_final_newline = true trim_trailing_whitespace = true @@ -310,7 +309,7 @@ dotnet_naming_symbols.other_public_protected_fields_group.applicable_accessibili dotnet_naming_symbols.other_public_protected_fields_group.applicable_kinds = field dotnet_naming_rule.other_public_protected_fields_disallowed_rule.symbols = other_public_protected_fields_group dotnet_naming_rule.other_public_protected_fields_disallowed_rule.style = disallowed_style -dotnet_naming_rule.other_public_protected_fields_disallowed_rule.severity = error +dotnet_naming_rule.other_public_protected_fields_disallowed_rule.severity = none ########################################## # StyleCop Field Naming Rules @@ -351,7 +350,6 @@ dotnet_naming_symbols.stylecop_private_fields_group.applicable_accessibilities = dotnet_naming_symbols.stylecop_private_fields_group.applicable_kinds = field dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.symbols = stylecop_private_fields_group dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.style = camel_case_style -dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.severity = warning # Local variables must be camelCase # https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1312.md diff --git a/src/BuildingBlocks/EFCore/Extensions.cs b/src/BuildingBlocks/EFCore/Extensions.cs index b3474e2..f61fe85 100644 --- a/src/BuildingBlocks/EFCore/Extensions.cs +++ b/src/BuildingBlocks/EFCore/Extensions.cs @@ -18,9 +18,7 @@ public static class Extensions where TContext : DbContext, IDbContext { - services.AddOptions() - .BindConfiguration(nameof(DatabaseOptions)) - .ValidateDataAnnotations(); + services.AddValidateOptions(); services.AddDbContext((sp, options) => { diff --git a/src/BuildingBlocks/MassTransit/Extensions.cs b/src/BuildingBlocks/MassTransit/Extensions.cs index bc5fdb9..a4fa73f 100644 --- a/src/BuildingBlocks/MassTransit/Extensions.cs +++ b/src/BuildingBlocks/MassTransit/Extensions.cs @@ -1,6 +1,5 @@ using System.Reflection; using BuildingBlocks.Core.Event; -using BuildingBlocks.Utils; using BuildingBlocks.Web; using Humanizer; using MassTransit; @@ -21,9 +20,7 @@ public static class Extensions public static IServiceCollection AddCustomMassTransit(this IServiceCollection services, IWebHostEnvironment env, Assembly assembly) { - services.AddOptions() - .BindConfiguration(nameof(RabbitMqOptions)) - .ValidateDataAnnotations(); + services.AddValidateOptions(); if (env.IsEnvironment("test")) { @@ -34,10 +31,7 @@ public static class Extensions } else { - services.AddMassTransit(configure => - { - SetupMasstransitConfigurations(services, configure, assembly); - }); + services.AddMassTransit(configure => { SetupMasstransitConfigurations(services, configure, assembly); }); } return services; diff --git a/src/BuildingBlocks/Mongo/Extensions.cs b/src/BuildingBlocks/Mongo/Extensions.cs index a59b110..4841fdb 100644 --- a/src/BuildingBlocks/Mongo/Extensions.cs +++ b/src/BuildingBlocks/Mongo/Extensions.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection; namespace BuildingBlocks.Mongo { + using Web; + public static class Extensions { public static IServiceCollection AddMongoDbContext( @@ -18,14 +20,14 @@ namespace BuildingBlocks.Mongo where TContextImplementation : MongoDbContext, TContextService { services.Configure(configuration.GetSection(nameof(MongoOptions))); + if (configurator is { }) { services.Configure(nameof(MongoOptions), configurator); } else { - services.AddOptions().Bind(configuration.GetSection(nameof(MongoOptions))) - .ValidateDataAnnotations(); + services.AddValidateOptions(); } services.AddScoped(typeof(TContextService), typeof(TContextImplementation)); diff --git a/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs b/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs index b30b68d..ddcac04 100644 --- a/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs +++ b/src/BuildingBlocks/PersistMessageProcessor/Extensions.cs @@ -9,9 +9,7 @@ public static class Extensions { public static IServiceCollection AddPersistMessageProcessor(this IServiceCollection services) { - services.AddOptions() - .BindConfiguration(nameof(PersistMessageOptions)) - .ValidateDataAnnotations(); + services.AddValidateOptions(); services.AddDbContext(options => { diff --git a/src/BuildingBlocks/TestBase/TestBase.cs b/src/BuildingBlocks/TestBase/TestBase.cs index a1c272b..d2f4cf6 100644 --- a/src/BuildingBlocks/TestBase/TestBase.cs +++ b/src/BuildingBlocks/TestBase/TestBase.cs @@ -2,7 +2,6 @@ using BuildingBlocks.Core.Event; using BuildingBlocks.Core.Model; using BuildingBlocks.EFCore; -using BuildingBlocks.MassTransit; using BuildingBlocks.Mongo; using BuildingBlocks.PersistMessageProcessor; using BuildingBlocks.Web; @@ -19,7 +18,6 @@ using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; using MongoDB.Driver; using NSubstitute; using Respawn; @@ -28,44 +26,49 @@ using Serilog; using Xunit; using Xunit.Abstractions; using ILogger = Serilog.ILogger; - -namespace BuildingBlocks.TestBase; - using System.Net; using System.Security.Claims; using WebMotions.Fake.Authentication.JwtBearer; +namespace BuildingBlocks.TestBase; + + + public class TestFixture : IAsyncLifetime where TEntryPoint : class { private readonly WebApplicationFactory _factory; private int Timeout => 120; // Second - - public MsSqlTestcontainer MsSqlTestContainer; - public MsSqlTestcontainer MsSqlPersistTestContainer; + private ITestHarness TestHarness => ServiceProvider?.GetTestHarness(); + private Action TestRegistrationServices { get; set; } + private MsSqlTestcontainer MsSqlTestContainer; + private MsSqlTestcontainer MsSqlPersistTestContainer; public RabbitMqTestcontainer RabbitMqTestContainer; public MongoDbTestcontainer MongoDbTestContainer; - private ITestHarness TestHarness => ServiceProvider?.GetTestHarness(); - public HttpClient HttpClient { get { - var claims = new Dictionary { { ClaimTypes.Name, "test@sample.com" }, { ClaimTypes.Role, "admin" }, }; + var claims = + new Dictionary + { + { ClaimTypes.Name, "test@sample.com" }, { ClaimTypes.Role, "admin" }, + }; var httpClient = _factory?.CreateClient(); httpClient.SetFakeBearerToken(claims); return httpClient; } } - public GrpcChannel Channel => GrpcChannel.ForAddress(HttpClient.BaseAddress!, new GrpcChannelOptions { HttpClient = HttpClient }); - public Action TestRegistrationServices { get; set; } + public GrpcChannel Channel => + GrpcChannel.ForAddress(HttpClient.BaseAddress!, new GrpcChannelOptions { HttpClient = HttpClient }); + public IServiceProvider ServiceProvider => _factory?.Services; public IConfiguration Configuration => _factory?.Services.GetRequiredService(); public ILogger Logger { get; set; } - public TestFixture() + protected TestFixture() { _factory = new WebApplicationFactory() .WithWebHostBuilder(builder => @@ -98,7 +101,7 @@ public class TestFixture : IAsyncLifetime public async Task DisposeAsync() { await StopTestContainerAsync(); - _factory?.DisposeAsync(); + await _factory.DisposeAsync(); } public virtual void RegisterServices(Action services) @@ -119,13 +122,13 @@ public class TestFixture : IAsyncLifetime return null; } - public async Task ExecuteScopeAsync(Func action) + protected async Task ExecuteScopeAsync(Func action) { using var scope = ServiceProvider.CreateScope(); await action(scope.ServiceProvider); } - public async Task ExecuteScopeAsync(Func> action) + protected async Task ExecuteScopeAsync(Func> action) { using var scope = ServiceProvider.CreateScope(); @@ -157,7 +160,7 @@ public class TestFixture : IAsyncLifetime public async Task Publish(TMessage message, CancellationToken cancellationToken = default) where TMessage : class, IEvent { - await TestHarness.Bus.Publish(message, cancellationToken); + await TestHarness.Bus.Publish(message, cancellationToken); } public async Task WaitForPublishing(CancellationToken cancellationToken = default) @@ -188,7 +191,7 @@ public class TestFixture : IAsyncLifetime } // Ref: https://tech.energyhelpline.com/in-memory-testing-with-masstransit/ - public async Task WaitUntilConditionMet(Func> conditionToMet, int? timeoutSecond = null) + private async Task WaitUntilConditionMet(Func> conditionToMet, int? timeoutSecond = null) { var time = timeoutSecond ?? Timeout; @@ -197,7 +200,10 @@ public class TestFixture : IAsyncLifetime var meet = await conditionToMet.Invoke(); while (!meet) { - if (timeoutExpired) return false; + if (timeoutExpired) + { + return false; + } await Task.Delay(100); meet = await conditionToMet.Invoke(); @@ -257,9 +263,13 @@ public class TestFixture : IAsyncLifetime configuration.AddInMemoryCollection(new KeyValuePair[] { new("DatabaseOptions:DefaultConnection", MsSqlTestContainer.ConnectionString + "TrustServerCertificate=True"), - new("PersistMessageOptions:ConnectionString", MsSqlPersistTestContainer.ConnectionString + "TrustServerCertificate=True"), new("RabbitMqOptions:HostName", RabbitMqTestContainer.Hostname), - new("RabbitMqOptions:UserName", RabbitMqTestContainer.Username), new("RabbitMqOptions:Password", RabbitMqTestContainer.Password), new("RabbitMqOptions:Port", RabbitMqTestContainer.Port.ToString()), - new("MongoOptions:ConnectionString", MongoDbTestContainer.ConnectionString), new("MongoOptions:DatabaseName", MongoDbTestContainer.Database) + new("PersistMessageOptions:ConnectionString", MsSqlPersistTestContainer.ConnectionString + "TrustServerCertificate=True"), + new("RabbitMqOptions:HostName", RabbitMqTestContainer.Hostname), + new("RabbitMqOptions:UserName", RabbitMqTestContainer.Username), + new("RabbitMqOptions:Password", RabbitMqTestContainer.Password), + new("RabbitMqOptions:Port", RabbitMqTestContainer.Port.ToString()), + new("MongoOptions:ConnectionString", MongoDbTestContainer.ConnectionString), + new("MongoOptions:DatabaseName", MongoDbTestContainer.Database) }); } @@ -314,7 +324,10 @@ public class TestWriteFixture : TestFixture { return ExecuteDbContextAsync(db => { - foreach (var entity in entities) db.Set().Add(entity); + foreach (var entity in entities) + { + db.Set().Add(entity); + } return db.SaveChangesAsync(); }); @@ -446,10 +459,8 @@ public class TestFixtureCore : IAsyncLifetime private async Task InitSqlAsync() { - await ResetSqlAsync(); - - var databaseOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; - var persistOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; + var databaseOptions = Fixture.ServiceProvider.GetRequiredService(); + var persistOptions = Fixture.ServiceProvider.GetRequiredService(); if (!string.IsNullOrEmpty(persistOptions?.ConnectionString)) { @@ -475,15 +486,20 @@ public class TestFixtureCore : IAsyncLifetime private async Task ResetSqlAsync() { if (PersistDbConnection is not null) + { await _reSpawnerPersistDb.ResetAsync(PersistDbConnection); + } + if (DefaultDbConnection is not null) + { await _reSpawnerDefaultDb.ResetAsync(DefaultDbConnection); + } } private async Task ResetMongoAsync(CancellationToken cancellationToken = default) { //https://stackoverflow.com/questions/3366397/delete-everything-in-a-mongodb-database - MongoClient dbClient = new MongoClient(Fixture.MongoDbTestContainer?.ConnectionString); + var dbClient = new MongoClient(Fixture.MongoDbTestContainer?.ConnectionString); var collections = await dbClient.GetDatabase(Fixture.MongoDbTestContainer?.Database) .ListCollectionsAsync(cancellationToken: cancellationToken); @@ -498,10 +514,8 @@ public class TestFixtureCore : IAsyncLifetime { var port = Fixture.RabbitMqTestContainer?.GetMappedPublicPort(15672) ?? 15672; - var rabbitmqOptions = Fixture.ServiceProvider.GetRequiredService>()?.Value; - - var managementClient = new ManagementClient(rabbitmqOptions?.HostName, rabbitmqOptions?.UserName, - rabbitmqOptions?.Password, port); + var managementClient = new ManagementClient(Fixture.RabbitMqTestContainer?.Hostname, Fixture.RabbitMqTestContainer?.Username, + Fixture.RabbitMqTestContainer?.Password, port); var bd = await managementClient.GetBindingsAsync(cancellationToken); var bindings = bd.Where(x => !string.IsNullOrEmpty(x.Source) && !string.IsNullOrEmpty(x.Destination)); @@ -528,7 +542,10 @@ public class TestFixtureCore : IAsyncLifetime using var scope = Fixture.ServiceProvider.CreateScope(); var seeders = scope.ServiceProvider.GetServices(); - foreach (var seeder in seeders) await seeder.SeedAllAsync(); + foreach (var seeder in seeders) + { + await seeder.SeedAllAsync(); + } } } diff --git a/src/BuildingBlocks/Web/ConfigurationExtensions.cs b/src/BuildingBlocks/Web/ConfigurationExtensions.cs index 76c437e..7090539 100644 --- a/src/BuildingBlocks/Web/ConfigurationExtensions.cs +++ b/src/BuildingBlocks/Web/ConfigurationExtensions.cs @@ -4,6 +4,9 @@ using Microsoft.Extensions.DependencyInjection; namespace BuildingBlocks.Web; +using MassTransit; +using Microsoft.Extensions.Options; + public static class ConfigurationExtensions { public static TModel GetOptions(this IConfiguration configuration, string section) where TModel : new() @@ -27,4 +30,13 @@ public static class ConfigurationExtensions app.Configuration?.GetSection(section).Bind(model); return model; } + + public static void AddValidateOptions(this IServiceCollection service) where TModel : class, new() + { + service.AddOptions() + .BindConfiguration(typeof(TModel).Name) + .ValidateDataAnnotations(); + + service.AddSingleton(x => x.GetRequiredService>().Value); + } } diff --git a/src/Services/Identity/tests/IntegrationTest/Fakes/FakeRegisterNewUserCommand.cs b/src/Services/Identity/tests/IntegrationTest/Fakes/FakeRegisterNewUserCommand.cs index d4ffff3..afe7171 100644 --- a/src/Services/Identity/tests/IntegrationTest/Fakes/FakeRegisterNewUserCommand.cs +++ b/src/Services/Identity/tests/IntegrationTest/Fakes/FakeRegisterNewUserCommand.cs @@ -1,5 +1,4 @@ using AutoBogus; -using Identity.Identity.Features.RegisterNewUser; using Identity.Identity.Features.RegisterNewUser.Commands.V1; namespace Integration.Test.Fakes; @@ -8,7 +7,7 @@ public class FakeRegisterNewUserCommand : AutoFaker { public FakeRegisterNewUserCommand() { - RuleFor(r => r.Username, _ => "TestUser"); + RuleFor(r => r.Username, x => x.Random.Uuid().ToString()); RuleFor(r => r.Password, _ => "Password@123"); RuleFor(r => r.ConfirmPassword, _ => "Password@123"); RuleFor(r => r.Email, _ => "test@test.com");