Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
testes corrigidos
  • Loading branch information
Filipe Frigini committed Nov 11, 2025
commit f417b2dbcfe51697fbc01e4ec4318c066b717415
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public class RateLimitingMiddleware(
RequestDelegate next,
IMemoryCache cache,
IOptionsMonitor<RateLimitOptions> options,
ILogger<RateLimitingMiddleware> logger)
ILogger<RateLimitingMiddleware> logger,
IConfiguration configuration)
Comment thread
frigini marked this conversation as resolved.
Outdated
{
/// <summary>
/// Classe contador simples para rate limiting.
Expand All @@ -30,6 +31,17 @@ private sealed class Counter
}
public async Task InvokeAsync(HttpContext context)
{
// Bypass rate limiting if explicitly disabled for testing
var rateLimitEnabled = configuration.GetValue<bool?>("AdvancedRateLimit:Enabled") ??
configuration.GetValue<bool?>("RateLimit:Enabled") ??
true; // Default to enabled

if (!rateLimitEnabled)
{
await next(context);
return;
}
Comment thread
frigini marked this conversation as resolved.
Outdated

var clientIp = GetClientIpAddress(context);
var isAuthenticated = context.User.Identity?.IsAuthenticated == true;

Expand Down
8 changes: 4 additions & 4 deletions src/Modules/Providers/API/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace MeAjudaAi.Modules.Providers.API;
Expand Down Expand Up @@ -54,10 +55,9 @@ private static void EnsureDatabaseMigrations(WebApplication app)
var context = scope.ServiceProvider.GetService<Infrastructure.Persistence.ProvidersDbContext>();
if (context == null) return;

// Verificar se estamos em ambiente de teste (TestContainers ou similar)
var isTestEnvironment = app.Environment.EnvironmentName == "Test" ||
app.Environment.EnvironmentName == "Testing" ||
context.Database.GetConnectionString()?.Contains("localhost") == true;
// Verificar se estamos em ambiente de teste
var isTestEnvironment = app.Environment.IsEnvironment("Test") ||
app.Environment.IsEnvironment("Testing");

if (isTestEnvironment)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ public async Task<Result<PagedResult<ProviderDto>>> HandleAsync(
"Erro ao buscar prestadores - Página: {Page}, Filtros: Nome='{Name}', Tipo={Type}, Status={Status}",
query.Page, query.Name, query.Type, query.VerificationStatus);

return Result<PagedResult<ProviderDto>>.Failure(Error.Internal(
"Erro interno ao buscar prestadores"));
return Result<PagedResult<ProviderDto>>.Failure(Error.Internal("Erro interno ao buscar prestadores"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,21 @@ public async Task HandleAsync(ProviderProfileUpdatedDomainEvent domainEvent, Can
{
logger.LogInformation("Handling ProviderProfileUpdatedDomainEvent for provider {ProviderId}", domainEvent.AggregateId);

// Busca o prestador para garantir que temos os dados mais recentes
var provider = await context.Providers
// Busca apenas o UserId do prestador
var userId = await context.Providers
.AsNoTracking()
.FirstOrDefaultAsync(p => p.Id == new Domain.ValueObjects.ProviderId(domainEvent.AggregateId), cancellationToken);
.Where(p => p.Id == new Domain.ValueObjects.ProviderId(domainEvent.AggregateId))
.Select(p => (Guid?)p.UserId)
.FirstOrDefaultAsync(cancellationToken);

if (provider == null)
if (!userId.HasValue)
{
logger.LogWarning("Provider {ProviderId} not found when handling ProviderProfileUpdatedDomainEvent", domainEvent.AggregateId);
return;
}

// Cria evento de integração para sistemas externos usando mapper
var integrationEvent = domainEvent.ToIntegrationEvent(provider.UserId, domainEvent.UpdatedFields);
var integrationEvent = domainEvent.ToIntegrationEvent(userId.Value, domainEvent.UpdatedFields);

await messageBus.PublishAsync(integrationEvent, cancellationToken: cancellationToken);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ public void Configure(EntityTypeBuilder<Provider> builder)
builder.Property(p => p.DeletedAt)
.HasColumnName("deleted_at");

// Configuração das propriedades de auditoria da BaseEntity
builder.Property(p => p.CreatedAt)
.IsRequired()
.HasColumnName("CreatedAt");

builder.Property(p => p.UpdatedAt)
.HasColumnName("UpdatedAt");
Comment thread
frigini marked this conversation as resolved.
Outdated

// Configuração do BusinessProfile como owned builder
builder.OwnsOne(p => p.BusinessProfile, bp =>
{
Expand Down Expand Up @@ -150,6 +158,8 @@ public void Configure(EntityTypeBuilder<Provider> builder)
doc.HasKey("ProviderId", "Id");
doc.ToTable("document", "providers");
doc.WithOwner().HasForeignKey("ProviderId");
doc.Property("ProviderId").HasColumnName("ProviderId");
doc.Property("Id").HasColumnName("Id");
Comment thread
frigini marked this conversation as resolved.
Outdated
doc.HasIndex("ProviderId", "DocumentType").IsUnique();
});

Expand Down Expand Up @@ -182,6 +192,8 @@ public void Configure(EntityTypeBuilder<Provider> builder)
qual.HasKey("ProviderId", "Id");
qual.ToTable("qualification", "providers");
qual.WithOwner().HasForeignKey("ProviderId");
qual.Property("ProviderId").HasColumnName("ProviderId");
qual.Property("Id").HasColumnName("Id");
Comment thread
frigini marked this conversation as resolved.
Outdated
});

// Índices
Expand Down
7 changes: 7 additions & 0 deletions src/Modules/Users/API/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace MeAjudaAi.Modules.Users.API;
Expand Down Expand Up @@ -57,6 +58,12 @@ private static void EnsureDatabaseMigrations(WebApplication app)
// Só aplica migrações se não estivermos em ambiente de testes unitários
if (app?.Services == null) return;

// Em ambiente de teste E2E, pular migrações automáticas - elas são gerenciadas pelo TestContainer
if (app.Environment.IsEnvironment("Test") || app.Environment.IsEnvironment("Testing"))
{
return;
}

try
{
// Criar um escopo para obter o context e aplicar migrações
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace MeAjudaAi.Modules.Users.Application.Handlers.Commands;
/// <param name="userDomainService">Serviço de domínio para operações de usuário</param>
/// <param name="userRepository">Repositório para persistência de usuários</param>
/// <param name="logger">Logger estruturado para auditoria e debugging</param>
public sealed class CreateUserCommandHandler(
internal sealed class CreateUserCommandHandler(
IUserDomainService userDomainService,
IUserRepository userRepository,
ILogger<CreateUserCommandHandler> logger
Expand Down Expand Up @@ -88,7 +88,7 @@ public async Task<Result<UserDto>> HandleAsync(
stopwatch.Stop();
logger.LogError(ex, "Unexpected error creating user for email {Email} after {ElapsedMs}ms",
command.Email, stopwatch.ElapsedMilliseconds);
return Result<UserDto>.Failure($"Failed to create user: {ex.Message}");
return Result<UserDto>.Failure("Failed to create user due to an unexpected error");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace MeAjudaAi.Modules.Users.Application.Handlers.Commands;
/// <param name="userDomainService">Serviço de domínio para operações complexas de usuário</param>
/// <param name="dateTimeProvider">Provedor de data/hora para testabilidade</param>
/// <param name="logger">Logger estruturado para auditoria e debugging</param>
public sealed class DeleteUserCommandHandler(
internal sealed class DeleteUserCommandHandler(
IUserRepository userRepository,
IUserDomainService userDomainService,
IDateTimeProvider dateTimeProvider,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace MeAjudaAi.Modules.Users.Application.Handlers.Queries;
/// </remarks>
/// <param name="userRepository">Repositório para consultas de usuários</param>
/// <param name="logger">Logger para auditoria e rastreamento das operações</param>
public sealed class GetUserByEmailQueryHandler(
internal sealed class GetUserByEmailQueryHandler(
IUserRepository userRepository,
ILogger<GetUserByEmailQueryHandler> logger
) : IQueryHandler<GetUserByEmailQuery, Result<UserDto>>
Expand Down Expand Up @@ -79,7 +79,7 @@ public async Task<Result<UserDto>> HandleAsync(
"Failed to retrieve user by email. CorrelationId: {CorrelationId}, Email: {Email}",
correlationId, query.Email);

return Result<UserDto>.Failure($"Failed to retrieve user: {ex.Message}");
return Result<UserDto>.Failure(Error.Internal("Failed to retrieve user"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ public async Task<Result<UserDto>> HandleAsync(
}

logger.LogInformation(
"User found successfully (cache hit/miss handled). CorrelationId: {CorrelationId}, UserId: {UserId}, Email: {Email}",
correlationId, query.UserId, userDto.Email);
"User found successfully (cache hit/miss handled). CorrelationId: {CorrelationId}, UserId: {UserId}",
correlationId, query.UserId);

return Result<UserDto>.Success(userDto);
}
Expand All @@ -90,7 +90,7 @@ public async Task<Result<UserDto>> HandleAsync(
"Failed to retrieve user by ID. CorrelationId: {CorrelationId}, UserId: {UserId}",
correlationId, query.UserId);

return Result<UserDto>.Failure($"Failed to retrieve user: {ex.Message}");
return Result<UserDto>.Failure(Error.Internal("Failed to retrieve user"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace MeAjudaAi.Modules.Users.Application.Handlers.Queries;
/// </remarks>
/// <param name="userRepository">Repositório para consultas de usuários</param>
/// <param name="logger">Logger para auditoria e rastreamento das operações</param>
public sealed class GetUsersQueryHandler(
internal sealed class GetUsersQueryHandler(
IUserRepository userRepository,
ILogger<GetUsersQueryHandler> logger
) : IQueryHandler<GetUsersQuery, Result<PagedResult<UserDto>>>
Expand Down
3 changes: 2 additions & 1 deletion src/Modules/Users/Application/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("MeAjudaAi.Modules.Users.Tests")]
[assembly: InternalsVisibleTo("MeAjudaAi.Modules.Users.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
3 changes: 2 additions & 1 deletion src/Modules/Users/Infrastructure/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("MeAjudaAi.Modules.Users.Tests")]
[assembly: InternalsVisibleTo("MeAjudaAi.Modules.Users.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace MeAjudaAi.Modules.Users.Infrastructure.Services;

public class KeycloakAuthenticationDomainService(IKeycloakService keycloakService) : IAuthenticationDomainService
internal class KeycloakAuthenticationDomainService(IKeycloakService keycloakService) : IAuthenticationDomainService
{
public async Task<Result<AuthenticationResult>> AuthenticateAsync(
string usernameOrEmail,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace MeAjudaAi.Modules.Users.Infrastructure.Services;
/// entre o domínio local e o sistema de autenticação.
/// </remarks>
/// <param name="keycloakService">Serviço de integração com Keycloak</param>
public class KeycloakUserDomainService(IKeycloakService keycloakService) : IUserDomainService
internal class KeycloakUserDomainService(IKeycloakService keycloakService) : IUserDomainService
{
/// <summary>
/// Cria um novo usuário com sincronização automática no Keycloak.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace MeAjudaAi.Modules.Users.Infrastructure.Services;
/// Mock implementation of IAuthenticationDomainService for environments where Keycloak is not available.
/// Provides basic authentication logic for testing and development scenarios.
/// </summary>
public class MockAuthenticationDomainService : IAuthenticationDomainService
internal class MockAuthenticationDomainService : IAuthenticationDomainService
{
/// <summary>
/// Authenticates users with mock credentials for testing purposes.
Expand Down Expand Up @@ -52,11 +52,6 @@ public Task<Result<TokenValidationResult>> ValidateTokenAsync(
return Task.FromResult(Result<TokenValidationResult>.Success(result));
}

var invalidResult = new TokenValidationResult(
UserId: null,
Roles: [],
Claims: []
);
return Task.FromResult(Result<TokenValidationResult>.Success(invalidResult));
return Task.FromResult(Result<TokenValidationResult>.Failure("Invalid token"));
}
Comment thread
frigini marked this conversation as resolved.
}
Loading
Loading