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