mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 17:47:22 +00:00
Migrate Auth and Emails to vertical slices (Features.Auth, Features.Emails)
Auth and Emails land together since Auth's registration/resend flows need Emails to exist first. Service.Auth's four services (Register, Login, Confirmation, Token) collapse into MediatR commands/queries in Features.Auth; TokenService stays as a slice-internal service since multiple handlers call it. Auth no longer references Emails directly — it sends SendRegistrationEmailCommand/SendResendConfirmationEmailCommand (defined in Shared.Application) which Features.Emails handles, so neither slice has a project reference on the other. Service.Emails' IEmailService becomes Features.Emails' IEmailDispatcher, simplified to take (firstName, email, token) instead of a full UserAccount since that's all it ever used. API.Specs' TestApiFactory/MockEmailService are updated to swap in the relocated interface. Also deletes Infrastructure.Repository now that Breweries, UserManagement, and Auth have all moved their repos out of it, and replaces the two now-dead docker-compose test services (repository.tests, service.auth.tests, both pointing at deleted Dockerfiles) with a single unit.tests service that runs every Features.*.Tests project via Dockerfile.tests.
This commit is contained in:
@@ -42,5 +42,6 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\API.Core\API.Core.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\Infrastructure.Email\Infrastructure.Email.csproj" />
|
||||
<ProjectReference Include="..\..\Features\Features.Emails\Features.Emails.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,17 +1,32 @@
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
WORKDIR /src
|
||||
|
||||
# See API.Core/Dockerfile for why this copies every project file (with real relative paths) and
|
||||
# restores against Core.slnx rather than hand-listing API.Specs' transitive dependencies.
|
||||
COPY ["Core.slnx", "./"]
|
||||
COPY ["API/API.Core/API.Core.csproj", "API/API.Core/"]
|
||||
COPY ["API/API.Specs/API.Specs.csproj", "API/API.Specs/"]
|
||||
COPY ["Domain/Domain.Entities/Domain.Entities.csproj", "Domain.Entities/"]
|
||||
COPY ["Domain/Domain.Exceptions/Domain.Exceptions.csproj", "Domain.Exceptions/"]
|
||||
COPY ["Infrastructure/Infrastructure.Repository/Infrastructure.Repository.csproj", "Infrastructure/Infrastructure.Repository/"]
|
||||
COPY ["Database/Database.Migrations/Database.Migrations.csproj", "Database/Database.Migrations/"]
|
||||
COPY ["Database/Database.Seed/Database.Seed.csproj", "Database/Database.Seed/"]
|
||||
COPY ["Domain/Domain.Entities/Domain.Entities.csproj", "Domain/Domain.Entities/"]
|
||||
COPY ["Domain/Domain.Exceptions/Domain.Exceptions.csproj", "Domain/Domain.Exceptions/"]
|
||||
COPY ["Features/Features.Auth/Features.Auth.csproj", "Features/Features.Auth/"]
|
||||
COPY ["Features/Features.Auth.Tests/Features.Auth.Tests.csproj", "Features/Features.Auth.Tests/"]
|
||||
COPY ["Features/Features.Breweries/Features.Breweries.csproj", "Features/Features.Breweries/"]
|
||||
COPY ["Features/Features.Breweries.Tests/Features.Breweries.Tests.csproj", "Features/Features.Breweries.Tests/"]
|
||||
COPY ["Features/Features.Emails/Features.Emails.csproj", "Features/Features.Emails/"]
|
||||
COPY ["Features/Features.Emails.Tests/Features.Emails.Tests.csproj", "Features/Features.Emails.Tests/"]
|
||||
COPY ["Features/Features.UserManagement/Features.UserManagement.csproj", "Features/Features.UserManagement/"]
|
||||
COPY ["Features/Features.UserManagement.Tests/Features.UserManagement.Tests.csproj", "Features/Features.UserManagement.Tests/"]
|
||||
COPY ["Infrastructure/Infrastructure.Email/Infrastructure.Email.csproj", "Infrastructure/Infrastructure.Email/"]
|
||||
COPY ["Infrastructure/Infrastructure.Email.Templates/Infrastructure.Email.Templates.csproj", "Infrastructure/Infrastructure.Email.Templates/"]
|
||||
COPY ["Infrastructure/Infrastructure.Jwt/Infrastructure.Jwt.csproj", "Infrastructure/Infrastructure.Jwt/"]
|
||||
COPY ["Infrastructure/Infrastructure.PasswordHashing/Infrastructure.PasswordHashing.csproj", "Infrastructure/Infrastructure.PasswordHashing/"]
|
||||
COPY ["Infrastructure/Infrastructure.Email/Infrastructure.Email.csproj", "Infrastructure/Infrastructure.Email/"]
|
||||
COPY ["Service/Service.Auth/Service.Auth.csproj", "Service/Service.Auth/"]
|
||||
COPY ["Service/Service.UserManagement/Service.UserManagement.csproj", "Service/Service.UserManagement/"]
|
||||
RUN dotnet restore "API/API.Specs/API.Specs.csproj"
|
||||
COPY ["Infrastructure/Infrastructure.Sql/Infrastructure.Sql.csproj", "Infrastructure/Infrastructure.Sql/"]
|
||||
COPY ["Shared/Shared.Application/Shared.Application.csproj", "Shared/Shared.Application/"]
|
||||
COPY ["Shared/Shared.Contracts/Shared.Contracts.csproj", "Shared/Shared.Contracts/"]
|
||||
RUN dotnet restore "Core.slnx"
|
||||
COPY . .
|
||||
WORKDIR "/src/API/API.Specs"
|
||||
RUN dotnet build "./API.Specs.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
using Domain.Entities;
|
||||
using Service.Emails;
|
||||
using Features.Emails.Services;
|
||||
|
||||
namespace API.Specs.Mocks;
|
||||
|
||||
public class MockEmailService : IEmailService
|
||||
public class MockEmailDispatcher : IEmailDispatcher
|
||||
{
|
||||
public List<RegistrationEmail> SentRegistrationEmails { get; } = new();
|
||||
|
||||
public List<ResendConfirmationEmail> SentResendConfirmationEmails { get; } = new();
|
||||
|
||||
public Task SendRegistrationEmailAsync(
|
||||
UserAccount createdUser,
|
||||
string firstName,
|
||||
string email,
|
||||
string confirmationToken
|
||||
)
|
||||
{
|
||||
SentRegistrationEmails.Add(
|
||||
new RegistrationEmail
|
||||
{
|
||||
UserAccount = createdUser,
|
||||
FirstName = firstName,
|
||||
Email = email,
|
||||
ConfirmationToken = confirmationToken,
|
||||
SentAt = DateTime.UtcNow,
|
||||
}
|
||||
@@ -27,14 +28,16 @@ public class MockEmailService : IEmailService
|
||||
}
|
||||
|
||||
public Task SendResendConfirmationEmailAsync(
|
||||
UserAccount user,
|
||||
string firstName,
|
||||
string email,
|
||||
string confirmationToken
|
||||
)
|
||||
{
|
||||
SentResendConfirmationEmails.Add(
|
||||
new ResendConfirmationEmail
|
||||
{
|
||||
UserAccount = user,
|
||||
FirstName = firstName,
|
||||
Email = email,
|
||||
ConfirmationToken = confirmationToken,
|
||||
SentAt = DateTime.UtcNow,
|
||||
}
|
||||
@@ -51,14 +54,16 @@ public class MockEmailService : IEmailService
|
||||
|
||||
public class RegistrationEmail
|
||||
{
|
||||
public UserAccount UserAccount { get; init; } = null!;
|
||||
public string FirstName { get; init; } = string.Empty;
|
||||
public string Email { get; init; } = string.Empty;
|
||||
public string ConfirmationToken { get; init; } = string.Empty;
|
||||
public DateTime SentAt { get; init; }
|
||||
}
|
||||
|
||||
public class ResendConfirmationEmail
|
||||
{
|
||||
public UserAccount UserAccount { get; init; } = null!;
|
||||
public string FirstName { get; init; } = string.Empty;
|
||||
public string Email { get; init; } = string.Empty;
|
||||
public string ConfirmationToken { get; init; } = string.Empty;
|
||||
public DateTime SentAt { get; init; }
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using API.Specs.Mocks;
|
||||
using Features.Emails.Services;
|
||||
using Infrastructure.Email;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Service.Emails;
|
||||
|
||||
namespace API.Specs
|
||||
{
|
||||
@@ -29,17 +29,17 @@ namespace API.Specs
|
||||
|
||||
services.AddScoped<IEmailProvider, MockEmailProvider>();
|
||||
|
||||
// Replace the real email service with mock for testing
|
||||
var emailServiceDescriptor = services.SingleOrDefault(d =>
|
||||
d.ServiceType == typeof(IEmailService)
|
||||
// Replace the real email dispatcher with mock for testing
|
||||
var emailDispatcherDescriptor = services.SingleOrDefault(d =>
|
||||
d.ServiceType == typeof(IEmailDispatcher)
|
||||
);
|
||||
|
||||
if (emailServiceDescriptor != null)
|
||||
if (emailDispatcherDescriptor != null)
|
||||
{
|
||||
services.Remove(emailServiceDescriptor);
|
||||
services.Remove(emailDispatcherDescriptor);
|
||||
}
|
||||
|
||||
services.AddScoped<IEmailService, MockEmailService>();
|
||||
services.AddScoped<IEmailDispatcher, MockEmailDispatcher>();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user