using NSubstitute; using PnvPanel.Application.Auth; using PnvPanel.Application.Common.Behaviors; using PnvPanel.Application.Common.Interfaces; using PnvPanel.Application.Common.Messaging; using PnvPanel.Application.Common.Models; using Xunit; namespace PnvPanel.Application.Tests.Common.Behaviors; public class RequireActivationBehaviorTests { private sealed record DummyRequest : IRequiresActivation; private readonly ICurrentUser _currentUser = Substitute.For(); private readonly IIdentityService _identityService = Substitute.For(); private RequireActivationBehavior> CreateBehavior() => new(_currentUser, _identityService); private static CurrentUserProfile CreateProfile(Guid userId, bool isActivated) => new( userId, "alice", Guid.NewGuid(), "user", IsActivated: isActivated, IsBlocked: false, MaxConfigs: 3, MaxIpLimit: RoleQuota.Unlimited, SubscriptionToken: "sub-token", BillingEnabled: false, BillingPaidUntil: null, BillingSuspended: false ); [Fact] public async Task Handle_WhenActivated_CallsNext() { var userId = Guid.NewGuid(); _currentUser.UserId.Returns(userId); _identityService .GetProfileAsync(userId, Arg.Any()) .Returns(CreateProfile(userId, isActivated: true)); var result = await CreateBehavior() .Handle( new DummyRequest(), () => Task.FromResult(Result.Success("ok")), CancellationToken.None ); Assert.True(result.IsSuccess); Assert.Equal("ok", result.Value); } [Fact] public async Task Handle_WhenNotActivated_ReturnsNotActivatedWithoutCallingNext() { var userId = Guid.NewGuid(); _currentUser.UserId.Returns(userId); _identityService .GetProfileAsync(userId, Arg.Any()) .Returns(CreateProfile(userId, isActivated: false)); var nextCalled = false; var result = await CreateBehavior() .Handle( new DummyRequest(), () => { nextCalled = true; return Task.FromResult(Result.Success("ok")); }, CancellationToken.None ); Assert.False(result.IsSuccess); Assert.Equal(AuthErrors.NotActivated, result.Error); Assert.False(nextCalled); } [Fact] public async Task Handle_WhenNoCurrentUser_ReturnsUnauthorized() { _currentUser.UserId.Returns((Guid?)null); var result = await CreateBehavior() .Handle( new DummyRequest(), () => Task.FromResult(Result.Success("ok")), CancellationToken.None ); Assert.False(result.IsSuccess); Assert.Equal(AuthErrors.Unauthorized, result.Error); } [Fact] public async Task Handle_WhenProfileMissing_ReturnsUnauthorized() { var userId = Guid.NewGuid(); _currentUser.UserId.Returns(userId); _identityService .GetProfileAsync(userId, Arg.Any()) .Returns((CurrentUserProfile?)null); var result = await CreateBehavior() .Handle( new DummyRequest(), () => Task.FromResult(Result.Success("ok")), CancellationToken.None ); Assert.False(result.IsSuccess); Assert.Equal(AuthErrors.Unauthorized, result.Error); } }