using NSubstitute; using PnvPanel.Application.Common.Interfaces; using PnvPanel.Application.Support; using PnvPanel.Application.Support.CreateRoleRequest; using PnvPanel.Application.Tests.TestSupport; using PnvPanel.Domain.Support; using Xunit; namespace PnvPanel.Application.Tests.Support; public class CreateRoleRequestTicketCommandHandlerTests { private readonly IRoleService _roleService = Substitute.For(); private readonly IRealtimeNotifier _notifier = Substitute.For(); private readonly ITelegramNotifier _telegramNotifier = Substitute.For(); [Fact] public async Task Handle_ForExistingRole_CreatesTicket() { using var dbContext = InMemoryDbContextFactory.Create(); var userId = Guid.NewGuid(); var roleId = Guid.NewGuid(); var currentUser = FakeCurrentUser.Authenticated(userId, "alice"); _roleService .ListRolesAsync(Arg.Any()) .Returns(new List { new(roleId, "premium", 5, 2, false, false) }); var handler = new CreateRoleRequestTicketCommandHandler( dbContext, _roleService, _notifier, _telegramNotifier, currentUser ); var result = await handler.Handle( new CreateRoleRequestTicketCommand(roleId, null, null, null, "нужно больше конфигов"), CancellationToken.None ); await dbContext.SaveChangesAsync(CancellationToken.None); Assert.True(result.IsSuccess); Assert.Equal(roleId, result.Value.RequestedRoleId); Assert.Equal("premium", result.Value.RequestedRoleName); await _telegramNotifier .Received(1) .NotifyAdminsRoleRequestCreatedAsync( Arg.Any(), "alice", "premium", "нужно больше конфигов", Arg.Any() ); } [Fact] public async Task Handle_ForAdminRole_ReturnsForbidden() { using var dbContext = InMemoryDbContextFactory.Create(); var roleId = Guid.NewGuid(); var currentUser = FakeCurrentUser.Authenticated(Guid.NewGuid()); _roleService .ListRolesAsync(Arg.Any()) .Returns(new List { new(roleId, "admin", -1, -1, true, false) }); var handler = new CreateRoleRequestTicketCommandHandler( dbContext, _roleService, _notifier, _telegramNotifier, currentUser ); var result = await handler.Handle( new CreateRoleRequestTicketCommand(roleId, null, null, null, "хочу быть админом"), CancellationToken.None ); Assert.False(result.IsSuccess); Assert.Equal(SupportErrors.CannotRequestAdminRole, result.Error); } [Fact] public async Task Handle_ForNewRole_SetsProposedFields() { using var dbContext = InMemoryDbContextFactory.Create(); var currentUser = FakeCurrentUser.Authenticated(Guid.NewGuid(), "bob"); var handler = new CreateRoleRequestTicketCommandHandler( dbContext, _roleService, _notifier, _telegramNotifier, currentUser ); var result = await handler.Handle( new CreateRoleRequestTicketCommand(null, "custom", 10, 4, "нужна кастомная роль"), CancellationToken.None ); Assert.True(result.IsSuccess); Assert.Equal("custom", result.Value.ProposedRoleName); Assert.Equal(10, result.Value.ProposedMaxConfigs); Assert.Equal(4, result.Value.ProposedMaxIpLimit); } [Fact] public async Task Handle_WhenPendingRoleRequestExists_ReturnsConflict() { using var dbContext = InMemoryDbContextFactory.Create(); var userId = Guid.NewGuid(); dbContext.SupportTickets.Add(SupportTicket.CreateRoleRequestForNewRole(userId, "x", 1, 1)); await dbContext.SaveChangesAsync(CancellationToken.None); var currentUser = FakeCurrentUser.Authenticated(userId); var handler = new CreateRoleRequestTicketCommandHandler( dbContext, _roleService, _notifier, _telegramNotifier, currentUser ); var result = await handler.Handle( new CreateRoleRequestTicketCommand(null, "y", 2, 2, "ещё заявка"), CancellationToken.None ); Assert.False(result.IsSuccess); Assert.Equal(SupportErrors.RoleRequestAlreadyPending, result.Error); } }