using FluentAssertions;
using FnbEngine.API.Application.Commands;
using FnbEngine.Domain.AggregatesModel.KitchenAggregate;
using FnbEngine.Domain.SeedWork;
using Moq;
using Xunit;
namespace FnbEngine.UnitTests.Application.Commands;
///
/// EN: Unit tests for CreateKitchenTicketCommandHandler.
/// VI: Unit tests cho CreateKitchenTicketCommandHandler.
///
public class CreateKitchenTicketCommandHandlerTests
{
private readonly Mock _repoMock;
private readonly CreateKitchenTicketCommandHandler _handler;
public CreateKitchenTicketCommandHandlerTests()
{
_repoMock = new Mock();
_repoMock.Setup(r => r.UnitOfWork.SaveEntitiesAsync(It.IsAny()))
.ReturnsAsync(true);
_repoMock.Setup(r => r.AddAsync(It.IsAny(), It.IsAny()))
.ReturnsAsync((KitchenTicket t, CancellationToken _) => t);
_handler = new CreateKitchenTicketCommandHandler(_repoMock.Object);
}
[Fact]
public async Task Handle_WithValidCommand_ShouldCreateTicketAndReturnId()
{
// Arrange
var command = new CreateKitchenTicketCommand(
SessionId: Guid.NewGuid(),
OrderItemId: Guid.NewGuid(),
ItemName: "Pho Bo",
Station: "Kitchen",
Priority: 1);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.Should().NotBeEmpty();
_repoMock.Verify(r => r.AddAsync(It.IsAny(), It.IsAny()), Times.Once);
_repoMock.Verify(r => r.UnitOfWork.SaveEntitiesAsync(It.IsAny()), Times.Once);
}
[Fact]
public async Task Handle_WithProductIdAndQuantity_ShouldPassToEntity()
{
// Arrange
var productId = Guid.NewGuid();
var command = new CreateKitchenTicketCommand(
SessionId: Guid.NewGuid(),
OrderItemId: Guid.NewGuid(),
ItemName: "Bun Cha",
ProductId: productId,
Quantity: 3);
KitchenTicket? capturedTicket = null;
_repoMock.Setup(r => r.AddAsync(It.IsAny(), It.IsAny()))
.Callback((t, _) => capturedTicket = t)
.ReturnsAsync((KitchenTicket t, CancellationToken _) => t);
// Act
await _handler.Handle(command, CancellationToken.None);
// Assert
capturedTicket.Should().NotBeNull();
capturedTicket!.ProductId.Should().Be(productId);
capturedTicket.Quantity.Should().Be(3);
}
[Fact]
public async Task Handle_WithoutProductId_ShouldUseOrderItemIdAsProductId()
{
// Arrange
var orderItemId = Guid.NewGuid();
var command = new CreateKitchenTicketCommand(
SessionId: Guid.NewGuid(),
OrderItemId: orderItemId,
ItemName: "Ca Phe");
KitchenTicket? capturedTicket = null;
_repoMock.Setup(r => r.AddAsync(It.IsAny(), It.IsAny()))
.Callback((t, _) => capturedTicket = t)
.ReturnsAsync((KitchenTicket t, CancellationToken _) => t);
// Act
await _handler.Handle(command, CancellationToken.None);
// Assert
capturedTicket.Should().NotBeNull();
capturedTicket!.ProductId.Should().Be(orderItemId);
}
[Fact]
public void Constructor_WithNullRepository_ShouldThrowArgumentNullException()
{
// Act
var action = () => new CreateKitchenTicketCommandHandler(null!);
// Assert
action.Should().Throw();
}
}