using FluentAssertions; using MiningService.API.Application.Commands; using MiningService.Domain.AggregatesModel.MinerAggregate; using MiningService.Domain.Exceptions; using NSubstitute; using Xunit; namespace MiningService.UnitTests.Application.Commands; /// /// EN: Unit tests for Admin Command Handlers. /// VI: Unit tests cho Admin Command Handlers. /// public class AdminCommandHandlerTests { private readonly IMinerRepository _minerRepository; public AdminCommandHandlerTests() { _minerRepository = Substitute.For(); } #region BanMinerCommandHandler Tests [Fact] public async Task BanMiner_ExistingMiner_BansSuccessfully() { // Arrange var minerId = Guid.NewGuid(); var miner = Miner.Create(Guid.NewGuid()); var command = new BanMinerCommand(minerId, "Violation"); var handler = new BanMinerCommandHandler(_minerRepository); _minerRepository.GetByIdAsync(minerId, Arg.Any()) .Returns(miner); _minerRepository.UnitOfWork.SaveEntitiesAsync(Arg.Any()) .Returns(true); // Act var result = await handler.Handle(command, CancellationToken.None); // Assert result.Should().NotBeNull(); result.Success.Should().BeTrue(); miner.Status.Should().Be(MinerStatus.Suspended); } [Fact] public async Task BanMiner_MinerNotFound_ThrowsException() { // Arrange var minerId = Guid.NewGuid(); var command = new BanMinerCommand(minerId, "Violation"); var handler = new BanMinerCommandHandler(_minerRepository); _minerRepository.GetByIdAsync(minerId, Arg.Any()) .Returns((Miner?)null); // Act & Assert await Assert.ThrowsAsync(() => handler.Handle(command, CancellationToken.None)); } #endregion #region AdjustMinerPointsCommandHandler Tests [Fact] public async Task AdjustPoints_PositiveAmount_AddsPoints() { // Arrange var minerId = Guid.NewGuid(); var miner = Miner.Create(Guid.NewGuid()); var command = new AdjustMinerPointsCommand(minerId, 100m, "Admin bonus"); var handler = new AdjustMinerPointsCommandHandler(_minerRepository); _minerRepository.GetByIdAsync(minerId, Arg.Any()) .Returns(miner); _minerRepository.UnitOfWork.SaveEntitiesAsync(Arg.Any()) .Returns(true); // Act var result = await handler.Handle(command, CancellationToken.None); // Assert result.Should().NotBeNull(); result.Success.Should().BeTrue(); result.NewBalance.Should().Be(100m); } [Fact] public async Task AdjustPoints_MinerNotFound_ThrowsException() { // Arrange var minerId = Guid.NewGuid(); var command = new AdjustMinerPointsCommand(minerId, 100m, "Bonus"); var handler = new AdjustMinerPointsCommandHandler(_minerRepository); _minerRepository.GetByIdAsync(minerId, Arg.Any()) .Returns((Miner?)null); // Act & Assert await Assert.ThrowsAsync(() => handler.Handle(command, CancellationToken.None)); } #endregion #region ResetMinerStreakCommandHandler Tests [Fact] public async Task ResetStreak_ValidMiner_ResetsSuccessfully() { // Arrange var minerId = Guid.NewGuid(); var miner = Miner.Create(Guid.NewGuid()); var command = new ResetMinerStreakCommand(minerId, "Admin reset"); var handler = new ResetMinerStreakCommandHandler(_minerRepository); _minerRepository.GetByIdAsync(minerId, Arg.Any()) .Returns(miner); _minerRepository.UnitOfWork.SaveEntitiesAsync(Arg.Any()) .Returns(true); // Act var result = await handler.Handle(command, CancellationToken.None); // Assert result.Should().NotBeNull(); result.Success.Should().BeTrue(); } #endregion }