97 lines
3.1 KiB
C#
97 lines
3.1 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(Skip = "Handler requires existing miner - auto-create has been removed")]
|
|
public async Task Handle_NewUser_CreatesMinerAndStartsSession()
|
|
{
|
|
// This test is skipped because StartMiningCommandHandler
|
|
// now requires an existing miner - it throws MinerNotFoundException
|
|
// for new users. Miner creation happens during registration.
|
|
await Task.CompletedTask;
|
|
}
|
|
|
|
[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));
|
|
}
|
|
}
|
|
|