Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: 🧪 refactor identity integration tests #237

Merged
merged 1 commit into from
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ resharper_web_config_module_not_resolved_highlighting = warning
resharper_web_config_type_not_resolved_highlighting = warning
resharper_web_config_wrong_module_highlighting = warning

# https://www.jetbrains.com/help/rider/ClassNeverInstantiated.Global.html
resharper_class_never_instantiated_global_highlighting = none

##################################################################################
## https://github.com/DotNetAnalyzers/StyleCopAnalyzers/tree/master/documentation
Expand Down Expand Up @@ -375,6 +377,8 @@ dotnet_diagnostic.sa1101.severity = None
# The keywords within the declaration of an element do not follow a standard ordering scheme.
dotnet_diagnostic.SA1206.severity = None

dotnet_diagnostic.SA1404.severity = None

##################################################################################
## https://github.com/meziantou/Meziantou.Analyzer/tree/main/docs
## Meziantou.Analyzer
Expand Down
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@

# dotnet format --verbosity diagnostic
dotnet csharpier . && git add -A .
dotnet csharpier --check .
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<ItemGroup>
<PackageReference Include="Duende.BFF.Yarp" />
<PackageReference Include="Serilog.AspNetCore" />
<PackageReference Include="Serilog.Sinks.SpectreConsole" />
<PackageReference Include="Serilog.Sinks.Spectre" />
<PackageReference Include="Yarp.ReverseProxy" />
</ItemGroup>

Expand Down
9 changes: 2 additions & 7 deletions src/ApiGateway/FoodDelivery.ApiGateway/Program.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
using System.IdentityModel.Tokens.Jwt;
using BuildingBlocks.Core.Messaging;
using BuildingBlocks.Logging;
using MassTransit;
using Microsoft.IdentityModel.Logging;
using Serilog;
using Serilog.Events;
using Serilog.Sinks.SpectreConsole;
using Serilog.Sinks.Spectre;
using Yarp.ReverseProxy.Transforms;
using MessageHeaders = BuildingBlocks.Core.Messaging.MessageHeaders;

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.SpectreConsole(
"{Timestamp:HH:mm:ss} [{Level:u4}] {Message:lj}{NewLine}{Exception}",
LogEventLevel.Information
)
.WriteTo.Spectre("{Timestamp:HH:mm:ss} [{Level:u4}] {Message:lj}{NewLine}{Exception}", LogEventLevel.Information)
.CreateLogger();

var builder = WebApplication.CreateBuilder(args);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace BuildingBlocks.Abstractions.Persistence;

public interface ITestDataSeeder
{
int Order { get; }
Task SeedAllAsync();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using AutoMapper.QueryableExtensions;
using BuildingBlocks.Abstractions.Core.Paging;
using BuildingBlocks.Core.Paging;
using Microsoft.EntityFrameworkCore;
using Sieve.Models;
using Sieve.Services;

Expand All @@ -29,10 +30,13 @@ CancellationToken cancellationToken

// https://github.com/Biarity/Sieve/issues/34#issuecomment-403817573
var result = sieveProcessor.Apply(sieveModel, queryable, applyPagination: false);
#pragma warning disable AsyncFixer02
// The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations.
var total = result.Count();
#pragma warning restore AsyncFixer02
result = sieveProcessor.Apply(sieveModel, queryable, applyFiltering: false, applySorting: false);

var items = await result.ToAsyncEnumerable().ToListAsync(cancellationToken: cancellationToken);
var items = await result.AsNoTracking().ToAsyncEnumerable().ToListAsync(cancellationToken: cancellationToken);

return PageList<TEntity>.Create(items.AsReadOnly(), pageRequest.PageNumber, pageRequest.PageSize, total);
}
Expand All @@ -57,12 +61,18 @@ CancellationToken cancellationToken

// https://github.com/Biarity/Sieve/issues/34#issuecomment-403817573
var result = sieveProcessor.Apply(sieveModel, queryable, applyPagination: false);
#pragma warning disable AsyncFixer02
// The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations.
var total = result.Count();
#pragma warning restore AsyncFixer02
result = sieveProcessor.Apply(sieveModel, queryable, applyFiltering: false, applySorting: false); // Only applies pagination

var projectedQuery = result.ProjectTo<TResult>(configurationProvider);

var items = await projectedQuery.ToAsyncEnumerable().ToListAsync(cancellationToken: cancellationToken);
var items = await projectedQuery
.AsNoTracking()
.ToAsyncEnumerable()
.ToListAsync(cancellationToken: cancellationToken);

return PageList<TResult>.Create(items.AsReadOnly(), pageRequest.PageNumber, pageRequest.PageSize, total);
}
Expand All @@ -87,12 +97,18 @@ CancellationToken cancellationToken

// https://github.com/Biarity/Sieve/issues/34#issuecomment-403817573
var result = sieveProcessor.Apply(sieveModel, queryable, applyPagination: false);
#pragma warning disable AsyncFixer02
// The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations.
var total = result.Count();
#pragma warning restore AsyncFixer02
result = sieveProcessor.Apply(sieveModel, queryable, applyFiltering: false, applySorting: false); // Only applies pagination

var projectedQuery = projectionFunc(result);

var items = await projectedQuery.ToAsyncEnumerable().ToListAsync(cancellationToken: cancellationToken);
var items = await projectedQuery
.AsNoTracking()
.ToAsyncEnumerable()
.ToListAsync(cancellationToken: cancellationToken);

return PageList<TResult>.Create(items.AsReadOnly(), pageRequest.PageNumber, pageRequest.PageSize, total);
}
Expand Down Expand Up @@ -120,12 +136,7 @@ public static async Task<IPageList<TResult>> ApplyPagingAsync<TEntity, TResult,
query = query.OrderByDescending(sortExpression);
}

return await query.ApplyPagingAsync<TEntity, TResult>(
pageRequest,
sieveProcessor,
projectionFunc,
cancellationToken
);
return await query.ApplyPagingAsync(pageRequest, sieveProcessor, projectionFunc, cancellationToken);
}

public static async Task<IPageList<TResult>> ApplyPagingAsync<TEntity, TResult>(
Expand All @@ -148,11 +159,15 @@ CancellationToken cancellationToken

// https://github.com/Biarity/Sieve/issues/34#issuecomment-403817573
var result = sieveProcessor.Apply(sieveModel, queryable, applyPagination: false);
#pragma warning disable AsyncFixer02
// The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations.
var total = result.Count();
#pragma warning restore AsyncFixer02
result = sieveProcessor.Apply(sieveModel, queryable, applyFiltering: false, applySorting: false); // Only applies pagination

var items = await result
.Select(x => map(x))
.AsNoTracking()
.ToAsyncEnumerable()
.ToListAsync(cancellationToken: cancellationToken);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ namespace BuildingBlocks.Core.Messaging;

public static class MessagingConstants
{
public const string PrimaryExchangePostfix = "_primary_exchange";
public const string PrimaryExchangePostfix = ".primary_exchange";
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace BuildingBlocks.Core.Persistence.Extensions;

internal static class DependencyInjectionExtensions
public static class DependencyInjectionExtensions
{
internal static IServiceCollection AddPersistenceCore(
this IServiceCollection services,
Expand All @@ -12,9 +12,24 @@ params Assembly[] assembliesToScan
{
services.ScanAndRegisterDbExecutors(assembliesToScan);

services.RegisterDataSeeders(assembliesToScan);

services.AddHostedService<SeedWorker>();
services.AddScoped<IMigrationManager, MigrationManager>();

return services;
}

public static void RegisterDataSeeders(this IServiceCollection services, Assembly[] assembliesToScan)
{
services.Scan(scan =>
scan.FromAssemblies(assembliesToScan)
.AddClasses(classes => classes.AssignableTo<IDataSeeder>())
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo<ITestDataSeeder>())
.AsImplementedInterfaces()
.WithScopedLifetime()
);
}
}
30 changes: 19 additions & 11 deletions src/BuildingBlocks/BuildingBlocks.Core/Persistence/SeedWorker.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using BuildingBlocks.Abstractions.Persistence;
using BuildingBlocks.Core.Web.Extensions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
Expand All @@ -15,15 +16,25 @@ IWebHostEnvironment webHostEnvironment
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (!webHostEnvironment.IsEnvironment("test"))
{
logger.LogInformation("Seed worker started");
logger.LogInformation("Seed worker started");

// https://stackoverflow.com/questions/38238043/how-and-where-to-call-database-ensurecreated-and-database-migrate
// https://www.michalbialecki.com/2020/07/20/adding-entity-framework-core-5-migrations-to-net-5-project/
using var serviceScope = serviceScopeFactory.CreateScope();
var seeders = serviceScope.ServiceProvider.GetServices<IDataSeeder>();
using var serviceScope = serviceScopeFactory.CreateScope();

// https://stackoverflow.com/questions/38238043/how-and-where-to-call-database-ensurecreated-and-database-migrate
// https://www.michalbialecki.com/2020/07/20/adding-entity-framework-core-5-migrations-to-net-5-project/
var testSeeders = serviceScope.ServiceProvider.GetServices<ITestDataSeeder>();
var seeders = serviceScope.ServiceProvider.GetServices<IDataSeeder>();
if (webHostEnvironment.IsTest())
{
foreach (var testDataSeeder in testSeeders.OrderBy(x => x.Order))
{
logger.LogInformation("Seeding '{Seed}' started...", testDataSeeder.GetType().Name);
await testDataSeeder.SeedAllAsync();
logger.LogInformation("Seeding '{Seed}' ended...", testDataSeeder.GetType().Name);
}
}
else
{
foreach (var seeder in seeders.OrderBy(x => x.Order))
{
logger.LogInformation("Seeding '{Seed}' started...", seeder.GetType().Name);
Expand All @@ -35,10 +46,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)

public override Task StopAsync(CancellationToken cancellationToken)
{
if (!webHostEnvironment.IsEnvironment("test"))
{
logger.LogInformation("Seed worker stopped");
}
logger.LogInformation("Seed worker stopped");

return base.StopAsync(cancellationToken);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,23 @@ public string FormatEntityName<T>()
return $"{typeof(T).Name.Underscore()}{MessagingConstants.PrimaryExchangePostfix}";
}
}

public class CustomEntityNameFormatter<TMessage> : IMessageEntityNameFormatter<TMessage>
where TMessage : class
{
public string FormatEntityName()
{
// Check if T implements IEventEnvelope
if (typeof(IEventEnvelope).IsAssignableFrom(typeof(TMessage)))
{
var messageProperty = typeof(TMessage).GetProperty(nameof(IEventEnvelope.Message));
if (typeof(IMessage).IsAssignableFrom(messageProperty!.PropertyType))
{
return $"{messageProperty.PropertyType.Name.Underscore()}{MessagingConstants.PrimaryExchangePostfix}";
}
}

// Return a default value if T does not implement IEventEnvelop or Message property is not found
return $"{typeof(TMessage).Name.Underscore()}{MessagingConstants.PrimaryExchangePostfix}";
}
}
Loading
Loading