using CartWise.Application.Services; using CartWise.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace CartWise.Application.Tests; public class ShoppingListServiceTests : IDisposable { private readonly CartWiseDbContext _db; private readonly ShoppingListService _sut; public ShoppingListServiceTests() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; _db = new CartWiseDbContext(options); _sut = new ShoppingListService(_db, TimeProvider.System); } public void Dispose() { _db.Dispose(); GC.SuppressFinalize(this); } [Fact] public async Task CreateListAsync_CreatesActiveList() { var householdId = Guid.NewGuid(); var result = await _sut.CreateListAsync(householdId, "Groceries", "user-1"); Assert.True(result.IsSuccess); Assert.Equal("Groceries", result.Value!.Name); Assert.Equal(householdId, result.Value.HouseholdId); } [Fact] public async Task CreateListAsync_FailsWhenHouseholdAlreadyHasAnActiveList() { var householdId = Guid.NewGuid(); await _sut.CreateListAsync(householdId, "Groceries", "user-1"); var result = await _sut.CreateListAsync(householdId, "Second List", "user-1"); Assert.False(result.IsSuccess); Assert.NotNull(result.Error); } [Fact] public async Task CreateListAsync_FailsWhenNameIsMissing() { var result = await _sut.CreateListAsync(Guid.NewGuid(), " ", "user-1"); Assert.False(result.IsSuccess); } [Fact] public async Task GetActiveListAsync_ReturnsNullWhenHouseholdHasNoList() { var list = await _sut.GetActiveListAsync(Guid.NewGuid()); Assert.Null(list); } [Fact] public async Task GetActiveListAsync_ReturnsTheActiveList() { var householdId = Guid.NewGuid(); var created = await _sut.CreateListAsync(householdId, "Groceries", "user-1"); var list = await _sut.GetActiveListAsync(householdId); Assert.NotNull(list); Assert.Equal(created.Value!.ShoppingListId, list!.ShoppingListId); } [Fact] public async Task GetActiveListAsync_DoesNotReturnAnotherHouseholdsList() { var householdA = Guid.NewGuid(); var householdB = Guid.NewGuid(); await _sut.CreateListAsync(householdA, "Household A's List", "user-1"); var list = await _sut.GetActiveListAsync(householdB); Assert.Null(list); } [Fact] public async Task AddItemAsync_AddsItemAndPersistsIt() { var created = await _sut.CreateListAsync(Guid.NewGuid(), "Groceries", "user-1"); var result = await _sut.AddItemAsync(created.Value!.ShoppingListId, "Milk", 2m, "gal", "user-1"); Assert.True(result.IsSuccess); Assert.Equal("Milk", result.Value!.DisplayName); var reloaded = await _sut.GetActiveListAsync(created.Value.HouseholdId); Assert.Single(reloaded!.Items); Assert.Equal("Milk", reloaded.Items.Single().DisplayName); } [Fact] public async Task AddItemAsync_FailsWhenListDoesNotExist() { var result = await _sut.AddItemAsync(Guid.NewGuid(), "Milk", null, null, "user-1"); Assert.False(result.IsSuccess); } [Fact] public async Task AddItemAsync_FailsWhenDisplayNameIsMissing() { var created = await _sut.CreateListAsync(Guid.NewGuid(), "Groceries", "user-1"); var result = await _sut.AddItemAsync(created.Value!.ShoppingListId, " ", null, null, "user-1"); Assert.False(result.IsSuccess); } }