using FluentAssertions; using MiningService.API.Application.Commands; using MiningService.Domain.AggregatesModel.MinerAggregate; using MiningService.Domain.Exceptions; using MiningService.Domain.SeedWork; using NSubstitute; using Xunit; namespace MiningService.UnitTests.Application.Commands; /// /// EN: Unit tests for ClaimMiningRewardCommandHandler. /// VI: Unit tests cho ClaimMiningRewardCommandHandler. /// public class ClaimMiningRewardCommandHandlerTests { private readonly IMinerRepository _minerRepository; private readonly IUnitOfWork _unitOfWork; private readonly ClaimMiningRewardCommandHandler _handler; public ClaimMiningRewardCommandHandlerTests() { _unitOfWork = Substitute.For(); _unitOfWork.SaveEntitiesAsync(Arg.Any()).Returns(true); _minerRepository = Substitute.For(); _minerRepository.UnitOfWork.Returns(_unitOfWork); _handler = new ClaimMiningRewardCommandHandler(_minerRepository); } [Fact(Skip = "Session requires 24h wait - cannot test immediate claim without time manipulation")] public async Task Handle_ReadySession_ReturnsReward() { // Session needs 24 hours to be ready for claim. // This would require time manipulation techniques to test properly. await Task.CompletedTask; } [Fact] public async Task Handle_MinerNotFound_ThrowsNotFoundException() { // Arrange var userId = Guid.NewGuid(); var command = new ClaimMiningRewardCommand(userId); _minerRepository.GetByUserIdAsync(userId, Arg.Any()) .Returns((Miner?)null); // Act & Assert await Assert.ThrowsAsync(() => _handler.Handle(command, CancellationToken.None)); } [Fact] public async Task Handle_NoActiveSession_ThrowsDomainException() { // Arrange var userId = Guid.NewGuid(); var miner = Miner.Create(userId); // No session started var command = new ClaimMiningRewardCommand(userId); _minerRepository.GetByUserIdAsync(userId, Arg.Any()) .Returns(miner); // Act & Assert await Assert.ThrowsAsync(() => _handler.Handle(command, CancellationToken.None)); } }