149 lines
4.7 KiB
C#
149 lines
4.7 KiB
C#
using FluentAssertions;
|
|
using MembershipService.API.Application.Commands;
|
|
using MembershipService.Domain.AggregatesModel.LevelAggregate;
|
|
using MembershipService.Domain.SeedWork;
|
|
using Microsoft.Extensions.Logging;
|
|
using NSubstitute;
|
|
using Xunit;
|
|
|
|
namespace MembershipService.UnitTests.Handlers;
|
|
|
|
/// <summary>
|
|
/// EN: Unit tests for CreateLevelDefinitionCommandHandler.
|
|
/// VI: Unit tests cho CreateLevelDefinitionCommandHandler.
|
|
/// </summary>
|
|
public class CreateLevelDefinitionCommandHandlerTests
|
|
{
|
|
private readonly ILevelDefinitionRepository _repository;
|
|
private readonly IUnitOfWork _unitOfWork;
|
|
private readonly ILogger<CreateLevelDefinitionCommandHandler> _logger;
|
|
private readonly CreateLevelDefinitionCommandHandler _handler;
|
|
|
|
public CreateLevelDefinitionCommandHandlerTests()
|
|
{
|
|
_repository = Substitute.For<ILevelDefinitionRepository>();
|
|
_unitOfWork = Substitute.For<IUnitOfWork>();
|
|
_logger = Substitute.For<ILogger<CreateLevelDefinitionCommandHandler>>();
|
|
|
|
_repository.UnitOfWork.Returns(_unitOfWork);
|
|
|
|
_handler = new CreateLevelDefinitionCommandHandler(_repository, _logger);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_ValidCommand_ShouldCreateLevelDefinition()
|
|
{
|
|
// Arrange
|
|
var command = new CreateLevelDefinitionCommand
|
|
{
|
|
LevelNumber = 6,
|
|
Name = "Master",
|
|
RequiredExp = 2000,
|
|
Description = "Master level",
|
|
BadgeColor = "#8B00FF"
|
|
};
|
|
|
|
_repository.ExistsByLevelNumberAsync(command.LevelNumber)
|
|
.Returns(false);
|
|
_repository.Add(Arg.Any<LevelDefinition>())
|
|
.Returns(x => x.Arg<LevelDefinition>());
|
|
_unitOfWork.SaveEntitiesAsync(Arg.Any<CancellationToken>())
|
|
.Returns(true);
|
|
|
|
// Act
|
|
var result = await _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.LevelNumber.Should().Be(6);
|
|
result.Name.Should().Be("Master");
|
|
result.RequiredExp.Should().Be(2000);
|
|
result.Id.Should().NotBeEmpty();
|
|
|
|
_repository.Received(1).Add(Arg.Any<LevelDefinition>());
|
|
await _unitOfWork.Received(1).SaveEntitiesAsync(Arg.Any<CancellationToken>());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_DuplicateLevelNumber_ShouldThrowInvalidOperationException()
|
|
{
|
|
// Arrange
|
|
var command = new CreateLevelDefinitionCommand
|
|
{
|
|
LevelNumber = 1,
|
|
Name = "Duplicate",
|
|
RequiredExp = 0
|
|
};
|
|
|
|
_repository.ExistsByLevelNumberAsync(command.LevelNumber)
|
|
.Returns(true);
|
|
|
|
// Act
|
|
var act = () => _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
await act.Should().ThrowAsync<InvalidOperationException>()
|
|
.WithMessage("*already exists*");
|
|
|
|
_repository.DidNotReceive().Add(Arg.Any<LevelDefinition>());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_WithOptionalFields_ShouldCreateWithAllFields()
|
|
{
|
|
// Arrange
|
|
var command = new CreateLevelDefinitionCommand
|
|
{
|
|
LevelNumber = 7,
|
|
Name = "Legend",
|
|
RequiredExp = 5000,
|
|
Description = "Legend tier for elite members",
|
|
IconUrl = "https://example.com/legend.png",
|
|
BadgeColor = "#FFD700"
|
|
};
|
|
|
|
_repository.ExistsByLevelNumberAsync(command.LevelNumber)
|
|
.Returns(false);
|
|
_repository.Add(Arg.Any<LevelDefinition>())
|
|
.Returns(x => x.Arg<LevelDefinition>());
|
|
_unitOfWork.SaveEntitiesAsync(Arg.Any<CancellationToken>())
|
|
.Returns(true);
|
|
|
|
// Act
|
|
var result = await _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.LevelNumber.Should().Be(7);
|
|
result.Name.Should().Be("Legend");
|
|
result.RequiredExp.Should().Be(5000);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_MinimalCommand_ShouldCreateWithDefaults()
|
|
{
|
|
// Arrange
|
|
var command = new CreateLevelDefinitionCommand
|
|
{
|
|
LevelNumber = 8,
|
|
Name = "Minimal",
|
|
RequiredExp = 100
|
|
};
|
|
|
|
_repository.ExistsByLevelNumberAsync(command.LevelNumber)
|
|
.Returns(false);
|
|
_repository.Add(Arg.Any<LevelDefinition>())
|
|
.Returns(x => x.Arg<LevelDefinition>());
|
|
_unitOfWork.SaveEntitiesAsync(Arg.Any<CancellationToken>())
|
|
.Returns(true);
|
|
|
|
// Act
|
|
var result = await _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.LevelNumber.Should().Be(8);
|
|
result.Name.Should().Be("Minimal");
|
|
}
|
|
}
|