using NSubstitute; using PnvPanel.Application.Activation; using PnvPanel.Application.Admin.Activation; using PnvPanel.Application.Auth; using PnvPanel.Application.Common.Interfaces; using PnvPanel.Application.Common.Models; using PnvPanel.Application.Tests.TestSupport; using PnvPanel.Domain.Activation; using Xunit; namespace PnvPanel.Application.Tests.Activation; public class ApproveActivationCommandHandlerTests { private readonly IIdentityService _identityService = Substitute.For(); private readonly IRealtimeNotifier _notifier = Substitute.For(); private readonly ITelegramNotifier _telegramNotifier = Substitute.For(); private readonly ICurrentUser _currentUser = Substitute.For(); [Fact] public async Task Handle_WhenPending_ApprovesActivatesUserAndNotifies() { using var dbContext = InMemoryDbContextFactory.Create(); var adminId = Guid.NewGuid(); var request = ActivationRequest.Create(Guid.NewGuid(), "please"); dbContext.ActivationRequests.Add(request); await dbContext.SaveChangesAsync(CancellationToken.None); _currentUser.UserId.Returns(adminId); _identityService.ActivateUserAsync(request.UserId, adminId, Arg.Any()).Returns(Result.Success()); var handler = new ApproveActivationCommandHandler(dbContext, _identityService, _notifier, _telegramNotifier, _currentUser); var result = await handler.Handle(new ApproveActivationCommand(request.Id), CancellationToken.None); Assert.True(result.IsSuccess); Assert.Equal(ActivationStatus.Approved, request.Status); await _notifier.Received(1).NotifyUserActivatedAsync(request.UserId, Arg.Any()); } [Fact] public async Task Handle_WhenRequestNotFound_ReturnsNotFound() { using var dbContext = InMemoryDbContextFactory.Create(); _currentUser.UserId.Returns(Guid.NewGuid()); var handler = new ApproveActivationCommandHandler(dbContext, _identityService, _notifier, _telegramNotifier, _currentUser); var result = await handler.Handle(new ApproveActivationCommand(Guid.NewGuid()), CancellationToken.None); Assert.False(result.IsSuccess); Assert.Equal(ActivationErrors.NotFound, result.Error); } [Fact] public async Task Handle_WhenAlreadyDecided_ReturnsConflict() { using var dbContext = InMemoryDbContextFactory.Create(); var request = ActivationRequest.Create(Guid.NewGuid(), null); request.Approve(Guid.NewGuid()); dbContext.ActivationRequests.Add(request); await dbContext.SaveChangesAsync(CancellationToken.None); _currentUser.UserId.Returns(Guid.NewGuid()); var handler = new ApproveActivationCommandHandler(dbContext, _identityService, _notifier, _telegramNotifier, _currentUser); var result = await handler.Handle(new ApproveActivationCommand(request.Id), CancellationToken.None); Assert.False(result.IsSuccess); Assert.Equal(ActivationErrors.AlreadyDecided, result.Error); } [Fact] public async Task Handle_WhenActivateUserFails_PropagatesFailureWithoutNotifying() { using var dbContext = InMemoryDbContextFactory.Create(); var adminId = Guid.NewGuid(); var request = ActivationRequest.Create(Guid.NewGuid(), null); dbContext.ActivationRequests.Add(request); await dbContext.SaveChangesAsync(CancellationToken.None); _currentUser.UserId.Returns(adminId); var failure = Error.NotFound("User.NotFound", "Пользователь не найден."); _identityService.ActivateUserAsync(request.UserId, adminId, Arg.Any()).Returns(Result.Failure(failure)); var handler = new ApproveActivationCommandHandler(dbContext, _identityService, _notifier, _telegramNotifier, _currentUser); var result = await handler.Handle(new ApproveActivationCommand(request.Id), CancellationToken.None); Assert.False(result.IsSuccess); Assert.Equal(failure, result.Error); await _notifier.DidNotReceive().NotifyUserActivatedAsync(Arg.Any(), Arg.Any()); } }