Files
pos-system/services/mining-service-net/tests/MiningService.UnitTests/Application/Commands/StartMiningCommandHandlerTests.cs

108 lines
3.3 KiB
C#

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;
/// <summary>
/// EN: Unit tests for StartMiningCommandHandler.
/// VI: Unit tests cho StartMiningCommandHandler.
/// </summary>
public class StartMiningCommandHandlerTests
{
private readonly IMinerRepository _minerRepository;
private readonly IUnitOfWork _unitOfWork;
private readonly StartMiningCommandHandler _handler;
public StartMiningCommandHandlerTests()
{
_unitOfWork = Substitute.For<IUnitOfWork>();
_unitOfWork.SaveEntitiesAsync(Arg.Any<CancellationToken>()).Returns(true);
_minerRepository = Substitute.For<IMinerRepository>();
_minerRepository.UnitOfWork.Returns(_unitOfWork);
_handler = new StartMiningCommandHandler(_minerRepository);
}
[Fact]
public async Task Handle_ExistingMiner_StartsSession()
{
// Arrange
var userId = Guid.NewGuid();
var miner = Miner.Create(userId);
var command = new StartMiningCommand(userId);
_minerRepository.GetByUserIdAsync(userId, Arg.Any<CancellationToken>())
.Returns(miner);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.Should().NotBeNull();
result.SessionId.Should().NotBeEmpty();
result.HourlyRate.Should().BeGreaterThan(0);
await _unitOfWork.Received(1).SaveEntitiesAsync(Arg.Any<CancellationToken>());
}
[Fact]
public async Task Handle_NewUser_CreatesMinerAndStartsSession()
{
// Arrange
var userId = Guid.NewGuid();
var command = new StartMiningCommand(userId);
_minerRepository.GetByUserIdAsync(userId, Arg.Any<CancellationToken>())
.Returns((Miner?)null);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.Should().NotBeNull();
result.SessionId.Should().NotBeEmpty();
_minerRepository.Received(1).Add(Arg.Is<Miner>(m => m.UserId == userId));
}
[Fact]
public async Task Handle_SuspendedMiner_ThrowsException()
{
// Arrange
var userId = Guid.NewGuid();
var miner = Miner.Create(userId);
miner.Suspend();
var command = new StartMiningCommand(userId);
_minerRepository.GetByUserIdAsync(userId, Arg.Any<CancellationToken>())
.Returns(miner);
// Act & Assert
await Assert.ThrowsAsync<MiningDomainException>(() =>
_handler.Handle(command, CancellationToken.None));
}
[Fact]
public async Task Handle_AlreadyMining_ThrowsException()
{
// Arrange
var userId = Guid.NewGuid();
var miner = Miner.Create(userId);
miner.StartMiningSession();
var command = new StartMiningCommand(userId);
_minerRepository.GetByUserIdAsync(userId, Arg.Any<CancellationToken>())
.Returns(miner);
// Act & Assert
await Assert.ThrowsAsync<MiningDomainException>(() =>
_handler.Handle(command, CancellationToken.None));
}
}