|
- using CartWise.Application.Services;
- using CartWise.Infrastructure.Data;
- using Microsoft.EntityFrameworkCore;
-
- namespace CartWise.Application.Tests;
-
- public class PurchaseServiceTests : IDisposable
- {
- private static readonly DateTime Now = new(2026, 8, 10, 12, 0, 0, DateTimeKind.Utc);
-
- private readonly CartWiseDbContext _db;
- private readonly PurchaseService _sut;
-
- public PurchaseServiceTests()
- {
- var options = new DbContextOptionsBuilder<CartWiseDbContext>()
- .UseInMemoryDatabase(Guid.NewGuid().ToString())
- .Options;
-
- _db = new CartWiseDbContext(options);
- _sut = new PurchaseService(_db, TimeProvider.System);
- }
-
- public void Dispose()
- {
- _db.Dispose();
- GC.SuppressFinalize(this);
- }
-
- [Fact]
- public async Task StartPurchaseAsync_CreatesPurchase()
- {
- var householdId = Guid.NewGuid();
-
- var result = await _sut.StartPurchaseAsync(householdId, "user-1", Now);
-
- Assert.True(result.IsSuccess);
- Assert.Equal(householdId, result.Value!.HouseholdId);
- Assert.False(result.Value.IsCompleted);
- }
-
- [Fact]
- public async Task AddPurchaseItemAsync_AddsItemAndPersistsIt()
- {
- var started = await _sut.StartPurchaseAsync(Guid.NewGuid(), "user-1", Now);
-
- var result = await _sut.AddPurchaseItemAsync(started.Value!.HouseholdId, started.Value.PurchaseId, "Milk", 3.99m);
-
- Assert.True(result.IsSuccess);
- Assert.Equal("Milk", result.Value!.Description);
-
- var reloaded = await _sut.GetPurchaseAsync(started.Value.HouseholdId, started.Value.PurchaseId);
- Assert.Single(reloaded!.Items);
- }
-
- [Fact]
- public async Task AddPurchaseItemAsync_FailsForPurchaseInAnotherHousehold()
- {
- var started = await _sut.StartPurchaseAsync(Guid.NewGuid(), "user-1", Now);
-
- var result = await _sut.AddPurchaseItemAsync(Guid.NewGuid(), started.Value!.PurchaseId, "Milk", 3.99m);
-
- Assert.False(result.IsSuccess);
- }
-
- [Fact]
- public async Task AddPurchaseItemAsync_FailsWhenPurchaseAlreadyCompleted()
- {
- var started = await _sut.StartPurchaseAsync(Guid.NewGuid(), "user-1", Now);
- await _sut.AddPurchaseItemAsync(started.Value!.HouseholdId, started.Value.PurchaseId, "Milk", 3.99m);
- await _sut.CompletePurchaseAsync(started.Value.HouseholdId, started.Value.PurchaseId);
-
- var result = await _sut.AddPurchaseItemAsync(started.Value.HouseholdId, started.Value.PurchaseId, "Bread", 2.5m);
-
- Assert.False(result.IsSuccess);
- }
-
- [Fact]
- public async Task CompletePurchaseAsync_ComputesSubtotalAndTotal()
- {
- var started = await _sut.StartPurchaseAsync(Guid.NewGuid(), "user-1", Now);
- await _sut.AddPurchaseItemAsync(started.Value!.HouseholdId, started.Value.PurchaseId, "Milk", 3.99m);
- await _sut.AddPurchaseItemAsync(started.Value.HouseholdId, started.Value.PurchaseId, "Bread", 2.50m);
-
- var result = await _sut.CompletePurchaseAsync(started.Value.HouseholdId, started.Value.PurchaseId, tax: 0.50m);
-
- Assert.True(result.IsSuccess);
- Assert.Equal(6.49m, result.Value!.Subtotal);
- Assert.Equal(0.50m, result.Value.Tax);
- Assert.Equal(6.99m, result.Value.Total);
- }
-
- [Fact]
- public async Task CompletePurchaseAsync_FailsForPurchaseInAnotherHousehold()
- {
- var started = await _sut.StartPurchaseAsync(Guid.NewGuid(), "user-1", Now);
-
- var result = await _sut.CompletePurchaseAsync(Guid.NewGuid(), started.Value!.PurchaseId);
-
- Assert.False(result.IsSuccess);
- }
-
- [Fact]
- public async Task GetHouseholdPurchasesAsync_ReturnsOnlyThatHouseholdsPurchasesNewestFirst()
- {
- var householdA = Guid.NewGuid();
- var householdB = Guid.NewGuid();
- await _sut.StartPurchaseAsync(householdA, "user-1", Now.AddDays(-1));
- await _sut.StartPurchaseAsync(householdA, "user-1", Now);
- await _sut.StartPurchaseAsync(householdB, "user-2", Now);
-
- var results = await _sut.GetHouseholdPurchasesAsync(householdA);
-
- Assert.Equal(2, results.Count);
- Assert.True(results[0].PurchasedUtc >= results[1].PurchasedUtc);
- }
- }
|