Files
pos-system/services/membership-service-net/tests/MembershipService.UnitTests/Handlers/UpdateLevelDefinitionCommandHandlerTests.cs

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");
}
}