using Thalos.Bff.Application.Adapters; using Thalos.Bff.Application.Handlers; using Thalos.Bff.Application.Security; using Thalos.Bff.Contracts.Api; using BuildingBlock.Identity.Contracts.Requests; using BuildingBlock.Identity.Contracts.Responses; namespace Thalos.Bff.Application.UnitTests; public class IssueTokenHandlerTests { [Fact] public async Task HandleAsync_WhenPermissionAllowed_DelegatesToServiceClient() { var handler = new IssueTokenHandler( new FakeThalosServiceClient(), new FakeIdentityEdgeContractAdapter(), new AllowPermissionGuard()); var response = await handler.HandleAsync(new IssueTokenApiRequest("user-1", "tenant-1", "corr-123")); Assert.Equal("token-xyz", response.AccessToken); Assert.Equal(1800, response.ExpiresInSeconds); } private sealed class FakeThalosServiceClient : IThalosServiceClient { public Task IssueTokenAsync(IssueIdentityTokenRequest request) { return Task.FromResult(new IssueIdentityTokenResponse("token-xyz", 1800)); } public Task EvaluatePolicyAsync(EvaluateIdentityPolicyRequest request) { return Task.FromResult(new EvaluateIdentityPolicyResponse(request.SubjectId, request.PermissionCode, true)); } public Task RefreshSessionAsync(RefreshIdentitySessionRequest request) { return Task.FromResult(new RefreshIdentitySessionResponse("token-refreshed", 1800)); } } private sealed class FakeIdentityEdgeContractAdapter : IIdentityEdgeContractAdapter { public EvaluateIdentityPolicyRequest ToPolicyRequest(IssueTokenApiRequest request, string permissionCode) { return new EvaluateIdentityPolicyRequest(request.SubjectId, request.TenantId, permissionCode); } public IssueIdentityTokenRequest ToIssueTokenRequest(IssueTokenApiRequest request) { return new IssueIdentityTokenRequest(request.SubjectId, request.TenantId); } public IssueTokenApiResponse ToIssueTokenApiResponse(IssueIdentityTokenResponse response) { return new IssueTokenApiResponse(response.Token, response.ExpiresInSeconds); } public RefreshIdentitySessionRequest ToRefreshSessionRequest(RefreshSessionApiRequest request) { return new RefreshIdentitySessionRequest(request.RefreshToken, request.CorrelationId); } public RefreshSessionApiResponse ToRefreshSessionApiResponse(RefreshIdentitySessionResponse response) { return new RefreshSessionApiResponse(response.Token, response.ExpiresInSeconds); } } private sealed class AllowPermissionGuard : IPermissionGuard { public bool CanAccess(EvaluateIdentityPolicyResponse policyResponse) => policyResponse.IsAllowed; } }