Files
KArtSell.Aegis/tests/KArtSell.IdentityAccess.UnitTests/ManageIdentityAndRoles/IdentityStateTests.cs
T
kjh2064 dc8f3466c9 WIP: AEG-VS-01-04 Part 2 - DI setup + Endpoint refactoring (token budget constraint)
- Added IdentityAccessModule.cs with DI registration
- Added KArtSell.Modules.IdentityAccess.csproj with FastEndpoints deps
- Added project files for UnitTests & IntegrationTests
- Updated Program.cs to register IdentityAccessModule
- Updated Host.csproj to reference IdentityAccess module
- Fixed Directory.Packages.props with Moq + MS.Extensions.DependencyInjection

ISSUES (to fix next session):
- FastEndpoints Send/SendAsync/SendOkAsync method resolution incomplete
- Response record initialization requires field values
- Need to refactor endpoints to match ModelOperations pattern exactly

WORKING:
- Domain layer (IdentityState, RoleAssignmentState) 
- SQL repositories (Dapper) 
- Unit tests (RegisterIdentity, RequestMfaSetup handlers) 
- Integration test structure ready 

Next: Simplify endpoints using 'Endpoint<Req,Resp>' pattern from GetApprovalQueue sample

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

143 lines
4.1 KiB
C#

using Xunit;
using KArtSell.Modules.IdentityAccess.ManageIdentityAndRoles.Domain;
namespace KArtSell.IdentityAccess.UnitTests.ManageIdentityAndRoles;
/// <summary>
/// AEG-VS-01-03: Domain policy tests for Identity state machine
/// Pure domain logic (no infrastructure dependencies)
/// </summary>
public class IdentityStateTests
{
[Fact]
public void CanTransitionFromUndefinedToActive()
{
var state = IdentityState.CreateUndefined();
var nextState = state.Register();
Assert.Equal(IdentityState.Active, nextState.Value);
}
[Fact]
public void CanTransitionFromActiveToRequiresMfaSetup()
{
var state = IdentityState.CreateActive();
var nextState = state.RequestMfaSetup();
Assert.Equal(IdentityState.RequiresMfaSetup, nextState.Value);
}
[Fact]
public void CanTransitionFromRequiresMfaSetupToMfaConfigured()
{
var state = IdentityState.Parse(IdentityState.RequiresMfaSetup);
var nextState = state.CompleteMfaSetup();
Assert.Equal(IdentityState.MfaConfigured, nextState.Value);
}
[Fact]
public void CanSuspendAndResumeMfa()
{
var state = IdentityState.Parse(IdentityState.MfaConfigured);
var suspended = state.SuspendMfaTemporarily();
var resumed = suspended.ResumeMfa();
Assert.Equal(IdentityState.MfaSuspended, suspended.Value);
Assert.Equal(IdentityState.MfaConfigured, resumed.Value);
}
[Fact]
public void CanDeactivateFromMultipleStates()
{
var states = new[]
{
IdentityState.CreateActive(),
IdentityState.Parse(IdentityState.RequiresMfaSetup),
IdentityState.Parse(IdentityState.MfaConfigured),
IdentityState.Parse(IdentityState.MfaSuspended)
};
foreach (var state in states)
{
var deactivated = state.Deactivate();
Assert.Equal("INACTIVE", deactivated.Value);
}
}
[Fact]
public void CanRevokeFromInactive()
{
var state = IdentityState.CreateInactive();
var revoked = state.Revoke();
Assert.Equal(IdentityState.Revoked, revoked.Value);
}
[Fact]
public void InvalidTransitionThrowsException()
{
var state = IdentityState.CreateUndefined();
Assert.Throws<InvalidOperationException>(() => state.RequestMfaSetup());
Assert.Throws<InvalidOperationException>(() => state.Deactivate());
}
[Fact]
public void CanQueryStateProperties()
{
var active = IdentityState.CreateActive();
Assert.True(active.IsActive());
Assert.False(active.IsInactive());
var mfaRequired = IdentityState.Parse(IdentityState.RequiresMfaSetup);
Assert.True(mfaRequired.IsMfaRequired());
var revoked = IdentityState.Parse(IdentityState.Revoked);
Assert.True(revoked.IsRevoked());
}
[Fact]
public void CanCheckCapabilities()
{
var undefined = IdentityState.CreateUndefined();
Assert.True(undefined.CanRegister());
var active = IdentityState.CreateActive();
Assert.True(active.CanReceiveRoles());
Assert.False(active.CanRegister());
var revoked = IdentityState.Parse(IdentityState.Revoked);
Assert.False(revoked.CanReceiveRoles());
}
[Theory]
[InlineData(IdentityState.Undefined)]
[InlineData(IdentityState.Active)]
[InlineData(IdentityState.RequiresMfaSetup)]
[InlineData(IdentityState.MfaConfigured)]
[InlineData(IdentityState.MfaSuspended)]
[InlineData(IdentityState.Inactive)]
[InlineData(IdentityState.Revoked)]
public void CanParseAllValidStates(string stateValue)
{
var state = IdentityState.Parse(stateValue);
Assert.Equal(stateValue, state.Value);
}
[Fact]
public void InvalidStateThrowsException()
{
Assert.Throws<ArgumentException>(() => IdentityState.Parse("INVALID_STATE"));
}
[Fact]
public void StateIsValueObject()
{
var state1 = IdentityState.CreateActive();
var state2 = IdentityState.Parse(IdentityState.Active);
Assert.Equal(state1, state2);
}
}