using NSubstitute; using PnvPanel.Application.Auth; using PnvPanel.Application.Common.Interfaces; using PnvPanel.Application.Common.Models; using PnvPanel.Application.Configs.GetMyConfigs; using PnvPanel.Application.Tests.TestSupport; using PnvPanel.Domain.Configs; using PnvPanel.Domain.Inbounds; using Xunit; namespace PnvPanel.Application.Tests.Configs.GetMyConfigs; public class GetMyConfigsQueryHandlerTests { private readonly IIdentityService _identityService = Substitute.For(); [Fact] public async Task Handle_ReturnsOnlyNonRevokedConfigsForCurrentUserWithMaxConfigsFromProfile() { using var dbContext = InMemoryDbContextFactory.Create(); var userId = Guid.NewGuid(); var otherUserId = Guid.NewGuid(); var inbound = Inbound.FromRemote(Guid.NewGuid(), "1", VpnProtocol.Vless, "remark", 443); inbound.Publish("My inbound", []); var activeConfig = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "Active"); var revokedConfig = VpnConfig.Create(userId, inbound.Id, VpnProtocol.Vless, "Revoked"); revokedConfig.Revoke(); var otherUsersConfig = VpnConfig.Create( otherUserId, inbound.Id, VpnProtocol.Vless, "Other" ); dbContext.Inbounds.Add(inbound); dbContext.VpnConfigs.AddRange(activeConfig, revokedConfig, otherUsersConfig); await dbContext.SaveChangesAsync(CancellationToken.None); var profile = new CurrentUserProfile( userId, "alice", Guid.NewGuid(), "user", true, false, 5, RoleQuota.Unlimited, "sub-token" ); _identityService.GetProfileAsync(userId, Arg.Any()).Returns(profile); var handler = new GetMyConfigsQueryHandler( dbContext, _identityService, FakeCurrentUser.Authenticated(userId) ); var result = await handler.Handle(new GetMyConfigsQuery(), CancellationToken.None); Assert.True(result.IsSuccess); Assert.Single(result.Value.Configs); Assert.Equal(activeConfig.Id, result.Value.Configs[0].Id); Assert.Equal(5, result.Value.MaxConfigs); } [Fact] public async Task Handle_WhenNotAuthenticated_ReturnsUnauthorized() { using var dbContext = InMemoryDbContextFactory.Create(); var handler = new GetMyConfigsQueryHandler( dbContext, _identityService, FakeCurrentUser.Anonymous() ); var result = await handler.Handle(new GetMyConfigsQuery(), CancellationToken.None); Assert.False(result.IsSuccess); Assert.Equal(AuthErrors.Unauthorized, result.Error); } [Fact] public async Task Handle_WhenProfileMissing_ReturnsUnauthorized() { using var dbContext = InMemoryDbContextFactory.Create(); var userId = Guid.NewGuid(); _identityService .GetProfileAsync(userId, Arg.Any()) .Returns((CurrentUserProfile?)null); var handler = new GetMyConfigsQueryHandler( dbContext, _identityService, FakeCurrentUser.Authenticated(userId) ); var result = await handler.Handle(new GetMyConfigsQuery(), CancellationToken.None); Assert.False(result.IsSuccess); Assert.Equal(AuthErrors.Unauthorized, result.Error); } }