|
- using CartWise.Domain.Entities;
- using CartWise.Domain.Enums;
-
- namespace CartWise.Domain.Tests;
-
- public class PurchaseTests
- {
- private static readonly DateTime Now = new(2026, 8, 10, 12, 0, 0, DateTimeKind.Utc);
-
- [Fact]
- public void Constructor_DefaultsToManualSourceAndNoStore()
- {
- var purchase = new Purchase(Guid.NewGuid(), "user-1", Now, Now);
-
- Assert.Equal(PurchaseSourceType.Manual, purchase.SourceType);
- Assert.Null(purchase.StoreLocationId);
- Assert.Empty(purchase.Items);
- Assert.False(purchase.IsCompleted);
- }
-
- [Fact]
- public void Constructor_ThrowsWhenHouseholdIdIsEmpty()
- {
- Assert.Throws<ArgumentException>(() => new Purchase(Guid.Empty, "user-1", Now, Now));
- }
-
- [Theory]
- [InlineData("")]
- [InlineData(" ")]
- [InlineData(null)]
- public void Constructor_ThrowsWhenPurchasedByUserIdIsMissing(string? userId)
- {
- Assert.Throws<ArgumentException>(() => new Purchase(Guid.NewGuid(), userId!, Now, Now));
- }
-
- [Fact]
- public void AddItem_DefaultsQuantityToOne()
- {
- var purchase = new Purchase(Guid.NewGuid(), "user-1", Now, Now);
-
- var item = purchase.AddItem("Milk", 3.99m, Now);
-
- Assert.Equal(1m, item.Quantity);
- Assert.Equal(3.99m, item.LinePrice);
- Assert.Single(purchase.Items);
- }
-
- [Theory]
- [InlineData("")]
- [InlineData(" ")]
- [InlineData(null)]
- public void AddItem_ThrowsWhenDescriptionIsMissing(string? description)
- {
- var purchase = new Purchase(Guid.NewGuid(), "user-1", Now, Now);
-
- Assert.Throws<ArgumentException>(() => purchase.AddItem(description!, 3.99m, Now));
- }
-
- [Fact]
- public void AddItem_ThrowsWhenQuantityIsZeroOrNegative()
- {
- var purchase = new Purchase(Guid.NewGuid(), "user-1", Now, Now);
-
- Assert.Throws<ArgumentOutOfRangeException>(() => purchase.AddItem("Milk", 3.99m, Now, quantity: 0));
- Assert.Throws<ArgumentOutOfRangeException>(() => purchase.AddItem("Milk", 3.99m, Now, quantity: -1));
- }
-
- [Fact]
- public void AddItem_ThrowsWhenLinePriceIsNegative()
- {
- var purchase = new Purchase(Guid.NewGuid(), "user-1", Now, Now);
-
- Assert.Throws<ArgumentOutOfRangeException>(() => purchase.AddItem("Milk", -1m, Now));
- }
-
- [Fact]
- public void AddItem_ThrowsOnCompletedPurchase()
- {
- var purchase = new Purchase(Guid.NewGuid(), "user-1", Now, Now);
- purchase.AddItem("Milk", 3.99m, Now);
- purchase.Complete();
-
- Assert.Throws<InvalidOperationException>(() => purchase.AddItem("Bread", 2.5m, Now));
- }
-
- [Fact]
- public void Complete_SumsLinePricesIntoSubtotalAndTotal()
- {
- var purchase = new Purchase(Guid.NewGuid(), "user-1", Now, Now);
- purchase.AddItem("Milk", 3.99m, Now);
- purchase.AddItem("Bread", 2.50m, Now);
-
- purchase.Complete();
-
- Assert.Equal(6.49m, purchase.Subtotal);
- Assert.Equal(6.49m, purchase.Total);
- Assert.Null(purchase.Tax);
- Assert.True(purchase.IsCompleted);
- }
-
- [Fact]
- public void Complete_AddsTaxToTotalWhenProvided()
- {
- var purchase = new Purchase(Guid.NewGuid(), "user-1", Now, Now);
- purchase.AddItem("Milk", 10m, Now);
-
- purchase.Complete(tax: 0.80m);
-
- Assert.Equal(10m, purchase.Subtotal);
- Assert.Equal(0.80m, purchase.Tax);
- Assert.Equal(10.80m, purchase.Total);
- }
-
- [Fact]
- public void Complete_ThrowsWhenAlreadyCompleted()
- {
- var purchase = new Purchase(Guid.NewGuid(), "user-1", Now, Now);
- purchase.AddItem("Milk", 3.99m, Now);
- purchase.Complete();
-
- Assert.Throws<InvalidOperationException>(() => purchase.Complete());
- }
- }
|