161 lines
5.1 KiB
C#
161 lines
5.1 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 UpdateLevelDefinitionCommandHandler.
|
|
/// VI: Unit tests cho UpdateLevelDefinitionCommandHandler.
|
|
/// </summary>
|
|
public class UpdateLevelDefinitionCommandHandlerTests
|
|
{
|
|
private readonly ILevelDefinitionRepository _repository;
|
|
private readonly IUnitOfWork _unitOfWork;
|
|
private readonly ILogger<UpdateLevelDefinitionCommandHandler> _logger;
|
|
private readonly UpdateLevelDefinitionCommandHandler _handler;
|
|
|
|
public UpdateLevelDefinitionCommandHandlerTests()
|
|
{
|
|
_repository = Substitute.For<ILevelDefinitionRepository>();
|
|
_unitOfWork = Substitute.For<IUnitOfWork>();
|
|
_logger = Substitute.For<ILogger<UpdateLevelDefinitionCommandHandler>>();
|
|
|
|
_repository.UnitOfWork.Returns(_unitOfWork);
|
|
|
|
_handler = new UpdateLevelDefinitionCommandHandler(_repository, _logger);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_ValidUpdate_ShouldUpdateLevelDefinition()
|
|
{
|
|
// Arrange
|
|
var levelId = Guid.NewGuid();
|
|
var existingLevel = new LevelDefinition(1, "Bronze", 0, "Old description");
|
|
|
|
var command = new UpdateLevelDefinitionCommand
|
|
{
|
|
Id = levelId,
|
|
Name = "Bronze Elite",
|
|
RequiredExp = 50,
|
|
Description = "Updated description"
|
|
};
|
|
|
|
_repository.GetAsync(levelId).Returns(existingLevel);
|
|
_unitOfWork.SaveEntitiesAsync(Arg.Any<CancellationToken>()).Returns(true);
|
|
|
|
// Act
|
|
var result = await _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.Name.Should().Be("Bronze Elite");
|
|
result.RequiredExp.Should().Be(50);
|
|
result.Description.Should().Be("Updated description");
|
|
|
|
_repository.Received(1).Update(Arg.Any<LevelDefinition>());
|
|
await _unitOfWork.Received(1).SaveEntitiesAsync(Arg.Any<CancellationToken>());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_LevelNotFound_ShouldThrowKeyNotFoundException()
|
|
{
|
|
// Arrange
|
|
var command = new UpdateLevelDefinitionCommand
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Name = "NonExistent"
|
|
};
|
|
|
|
_repository.GetAsync(command.Id).Returns((LevelDefinition?)null);
|
|
|
|
// Act
|
|
var act = () => _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
await act.Should().ThrowAsync<KeyNotFoundException>()
|
|
.WithMessage("*not found*");
|
|
|
|
_repository.DidNotReceive().Update(Arg.Any<LevelDefinition>());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_PartialUpdate_ShouldOnlyUpdateProvidedFields()
|
|
{
|
|
// Arrange
|
|
var levelId = Guid.NewGuid();
|
|
var existingLevel = new LevelDefinition(2, "Silver", 100, "Original description", null, "#C0C0C0");
|
|
|
|
var command = new UpdateLevelDefinitionCommand
|
|
{
|
|
Id = levelId,
|
|
Name = "Silver Plus"
|
|
// Not updating RequiredExp, Description, etc.
|
|
};
|
|
|
|
_repository.GetAsync(levelId).Returns(existingLevel);
|
|
_unitOfWork.SaveEntitiesAsync(Arg.Any<CancellationToken>()).Returns(true);
|
|
|
|
// Act
|
|
var result = await _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.Name.Should().Be("Silver Plus");
|
|
result.RequiredExp.Should().Be(100); // Unchanged
|
|
result.BadgeColor.Should().Be("#C0C0C0"); // Unchanged
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_ClearDescription_ShouldSetToNull()
|
|
{
|
|
// Arrange
|
|
var levelId = Guid.NewGuid();
|
|
var existingLevel = new LevelDefinition(3, "Gold", 300, "Has description");
|
|
|
|
var command = new UpdateLevelDefinitionCommand
|
|
{
|
|
Id = levelId,
|
|
ClearDescription = true
|
|
};
|
|
|
|
_repository.GetAsync(levelId).Returns(existingLevel);
|
|
_unitOfWork.SaveEntitiesAsync(Arg.Any<CancellationToken>()).Returns(true);
|
|
|
|
// Act
|
|
var result = await _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.Description.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Handle_UpdateBadgeColor_ShouldUpdateColor()
|
|
{
|
|
// Arrange
|
|
var levelId = Guid.NewGuid();
|
|
var existingLevel = new LevelDefinition(4, "Platinum", 600, null, null, "#E5E4E2");
|
|
|
|
var command = new UpdateLevelDefinitionCommand
|
|
{
|
|
Id = levelId,
|
|
BadgeColor = "#00CED1"
|
|
};
|
|
|
|
_repository.GetAsync(levelId).Returns(existingLevel);
|
|
_unitOfWork.SaveEntitiesAsync(Arg.Any<CancellationToken>()).Returns(true);
|
|
|
|
// Act
|
|
var result = await _handler.Handle(command, CancellationToken.None);
|
|
|
|
// Assert
|
|
result.Should().NotBeNull();
|
|
result.BadgeColor.Should().Be("#00CED1");
|
|
}
|
|
}
|