using FluentAssertions; using FnbEngine.API.Application.Commands; using FnbEngine.Domain.AggregatesModel.TableAggregate; using FnbEngine.Domain.Exceptions; using FnbEngine.Domain.SeedWork; using Microsoft.Extensions.Logging; using Moq; using Xunit; namespace FnbEngine.UnitTests.Application.Commands; /// /// EN: Unit tests for ChangeTableStatusCommandHandler. /// VI: Unit tests cho ChangeTableStatusCommandHandler. /// public class ChangeTableStatusCommandHandlerTests { private readonly Mock _repoMock; private readonly Mock> _loggerMock; private readonly ChangeTableStatusCommandHandler _handler; public ChangeTableStatusCommandHandlerTests() { _repoMock = new Mock(); _loggerMock = new Mock>(); _repoMock.Setup(r => r.UnitOfWork.SaveEntitiesAsync(It.IsAny())) .ReturnsAsync(true); _handler = new ChangeTableStatusCommandHandler(_repoMock.Object, _loggerMock.Object); } [Theory] [InlineData("available")] [InlineData("Available")] public async Task Handle_WithAvailableStatus_ShouldMarkTableAsAvailable(string status) { // Arrange var tableId = Guid.NewGuid(); var table = new Table(Guid.NewGuid(), "A-01", 4); table.MarkAsOccupied(); _repoMock.Setup(r => r.GetByIdAsync(tableId, It.IsAny())) .ReturnsAsync(table); var command = new ChangeTableStatusCommand(tableId, status); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.Should().BeTrue(); table.Status.Should().Be(TableStatus.Available); } [Fact] public async Task Handle_WithOccupiedStatus_ShouldMarkTableAsOccupied() { // Arrange var tableId = Guid.NewGuid(); var table = new Table(Guid.NewGuid(), "A-01", 4); _repoMock.Setup(r => r.GetByIdAsync(tableId, It.IsAny())) .ReturnsAsync(table); var command = new ChangeTableStatusCommand(tableId, "occupied"); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.Should().BeTrue(); table.Status.Should().Be(TableStatus.Occupied); } [Fact] public async Task Handle_WithCleaningStatus_ShouldMarkTableAsCleaning() { // Arrange var tableId = Guid.NewGuid(); var table = new Table(Guid.NewGuid(), "A-01", 4); _repoMock.Setup(r => r.GetByIdAsync(tableId, It.IsAny())) .ReturnsAsync(table); var command = new ChangeTableStatusCommand(tableId, "cleaning"); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.Should().BeTrue(); table.Status.Should().Be(TableStatus.Cleaning); } [Fact] public async Task Handle_WithNonExistentTable_ShouldThrowInvalidOperationException() { // Arrange var tableId = Guid.NewGuid(); _repoMock.Setup(r => r.GetByIdAsync(tableId, It.IsAny())) .ReturnsAsync((Table?)null); var command = new ChangeTableStatusCommand(tableId, "available"); // Act var action = () => _handler.Handle(command, CancellationToken.None); // Assert await action.Should().ThrowAsync() .WithMessage($"*{tableId}*not found*"); } [Fact] public async Task Handle_WithInvalidStatus_ShouldThrowArgumentException() { // Arrange var tableId = Guid.NewGuid(); var table = new Table(Guid.NewGuid(), "A-01", 4); _repoMock.Setup(r => r.GetByIdAsync(tableId, It.IsAny())) .ReturnsAsync(table); var command = new ChangeTableStatusCommand(tableId, "invalid"); // Act var action = () => _handler.Handle(command, CancellationToken.None); // Assert await action.Should().ThrowAsync() .WithMessage("*Invalid status*"); } }