Files
KArtSell.Aegis/tests/KArtSell.IdentityAccess.UnitTests/ManageIdentityAndRoles/RegisterIdentityHandlerTests.cs
T
kjh2064 b3cb9032ac feat(wbs): AEG-VS-01-04 BE Vertical Slice - Endpoints & Handlers (Part 1)
- RegisterIdentity endpoint (POST /api/identities)
- RequestMfaSetup endpoint (PUT /api/identities/{id}/request-mfa)
- SQL repositories w/ optimistic concurrency (revision tracking)
- Application handlers (IEndpointHandler pattern)
- ValidationException + ProblemDetails error handling
- Unit tests: RegisterIdentityHandlerTests (4), RequestMfaSetupHandlerTests (4)
- Domain state machines integrated (IdentityState lifecycle)
- AGENTS.md v16.0: endpoint authority, idempotency, correlation ID ready

DI registration & integration tests deferred to next session.
17 new files, 500+ LOC, 8/8 unit tests ready to run

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-17 17:43:31 +09:00

82 lines
2.8 KiB
C#

using Xunit;
using Moq;
using KArtSell.Modules.IdentityAccess.ManageIdentityAndRoles.Features.RegisterIdentity;
namespace KArtSell.IdentityAccess.UnitTests.ManageIdentityAndRoles;
public class RegisterIdentityHandlerTests
{
private readonly Mock<IRegisterIdentitySql> _sqlMock;
private readonly RegisterIdentityHandler _handler;
public RegisterIdentityHandlerTests()
{
_sqlMock = new Mock<IRegisterIdentitySql>();
_handler = new RegisterIdentityHandler(_sqlMock.Object);
}
[Fact]
public async Task HandleAsync_ValidRequest_CreatesIdentity()
{
var request = new RegisterIdentityRequest
{
Email = "test@example.com",
DisplayName = "Test User"
};
var identityId = Guid.NewGuid();
_sqlMock.Setup(s => s.EmailExistsAsync("test@example.com", It.IsAny<CancellationToken>()))
.ReturnsAsync(false);
_sqlMock.Setup(s => s.CreateIdentityAsync(It.IsAny<Guid>(), "test@example.com", "Test User", It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(identityId);
_sqlMock.Setup(s => s.GetIdentityAsync(identityId, It.IsAny<CancellationToken>()))
.ReturnsAsync((identityId, "test@example.com", "Test User", Domain.IdentityState.Active));
var response = await _handler.HandleAsync(request, CancellationToken.None);
Assert.NotNull(response);
Assert.Equal(identityId, response.Id);
Assert.Equal("test@example.com", response.Email);
Assert.Equal(Domain.IdentityState.Active, response.State);
}
[Fact]
public async Task HandleAsync_InvalidEmail_ThrowsValidationException()
{
var request = new RegisterIdentityRequest
{
Email = "invalid-email",
DisplayName = "Test User"
};
await Assert.ThrowsAsync<ValidationException>(() => _handler.HandleAsync(request, CancellationToken.None));
}
[Fact]
public async Task HandleAsync_EmailExists_ThrowsValidationException()
{
var request = new RegisterIdentityRequest
{
Email = "existing@example.com",
DisplayName = "Test User"
};
_sqlMock.Setup(s => s.EmailExistsAsync("existing@example.com", It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
await Assert.ThrowsAsync<ValidationException>(() => _handler.HandleAsync(request, CancellationToken.None));
}
[Fact]
public async Task HandleAsync_EmptyDisplayName_ThrowsValidationException()
{
var request = new RegisterIdentityRequest
{
Email = "test@example.com",
DisplayName = ""
};
await Assert.ThrowsAsync<ValidationException>(() => _handler.HandleAsync(request, CancellationToken.None));
}
}