using FluentAssertions; using OrderService.Domain.AggregatesModel.OrderAggregate; using OrderService.Domain.Exceptions; using Xunit; namespace OrderService.UnitTests.Domain; /// /// EN: Unit tests for Order aggregate domain behavior. /// VI: Unit tests cho hành vi domain của aggregate Order. /// public class OrderAggregateTests { [Fact] public void CreateOrder_WithValidShopId_ShouldStartInDraftStatus() { // Arrange var shopId = Guid.NewGuid(); // Act var order = new Order(shopId); // Assert order.Id.Should().NotBe(Guid.Empty); order.ShopId.Should().Be(shopId); order.Status.Should().Be(OrderStatus.Draft); order.TotalAmount.Should().Be(0m); order.DomainEvents.Should().NotBeEmpty(); } [Fact] public void AddItem_InDraftStatus_ShouldRecalculateTotalAmount() { // Arrange var order = new Order(Guid.NewGuid()); var firstItem = new OrderItem(Guid.NewGuid(), "Coffee", "PreparedFood", 2, 30_000m); var secondItem = new OrderItem(Guid.NewGuid(), "Cake", "PreparedFood", 1, 45_000m); // Act order.AddItem(firstItem); order.AddItem(secondItem); // Assert order.Items.Should().HaveCount(2); order.TotalAmount.Should().Be(105_000m); } [Fact] public void MarkAsValidated_WithoutItems_ShouldThrowDomainException() { // Arrange var order = new Order(Guid.NewGuid()); // Act var act = () => order.MarkAsValidated(); // Assert act.Should().Throw() .WithMessage("Cannot validate order with no items"); } [Fact] public void FullLifecycle_DraftToCompleted_ShouldUpdateStatusSequentially() { // Arrange var order = new Order(Guid.NewGuid()); order.AddItem(new OrderItem(Guid.NewGuid(), "Shoes", "Physical", 1, 1_200_000m)); // Act order.MarkAsValidated(); order.MarkAsPaid("cash", "TXN-TEST-001"); order.MarkAsProcessing(); order.MarkAsCompleted(); // Assert order.Status.Should().Be(OrderStatus.Completed); } [Fact] public void Cancel_CompletedOrder_ShouldThrowDomainException() { // Arrange var order = new Order(Guid.NewGuid()); order.AddItem(new OrderItem(Guid.NewGuid(), "Laptop", "Physical", 1, 25_000_000m)); order.MarkAsValidated(); order.MarkAsPaid("cash", "TXN-TEST-001"); order.MarkAsProcessing(); order.MarkAsCompleted(); // Act var act = () => order.Cancel("Customer changed mind"); // Assert act.Should().Throw() .WithMessage("Cannot cancel completed order"); } }