using CartWise.Application.Services; using CartWise.Domain.Entities; using CartWise.Domain.Enums; using CartWise.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace CartWise.Application.Tests; public class ProductServiceTests : IDisposable { private static readonly DateTime Now = new(2026, 8, 10, 12, 0, 0, DateTimeKind.Utc); private readonly CartWiseDbContext _db; private readonly ProductService _sut; public ProductServiceTests() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; _db = new CartWiseDbContext(options); _sut = new ProductService(_db); } public void Dispose() { _db.Dispose(); GC.SuppressFinalize(this); } [Fact] public async Task SearchAsync_ReturnsMatchingProductsWithBrandName() { var brand = new Brand("Jif"); var product = new Product("Jif Creamy Peanut Butter", ProductSourceType.Manual, Now, brandId: brand.BrandId, sizeValue: 16m, sizeUnit: "oz"); _db.Brands.Add(brand); _db.Products.Add(product); await _db.SaveChangesAsync(); var results = await _sut.SearchAsync("peanut"); var result = Assert.Single(results); Assert.Equal("Jif Creamy Peanut Butter", result.Name); Assert.Equal("Jif", result.BrandName); Assert.Equal("16 oz", result.PackageDisplay); } [Fact] public async Task SearchAsync_ReturnsEmptyForBlankQuery() { var results = await _sut.SearchAsync(" "); Assert.Empty(results); } [Fact] public async Task SearchAsync_ReturnsEmptyWhenNothingMatches() { _db.Products.Add(new Product("Whole Milk", ProductSourceType.Manual, Now)); await _db.SaveChangesAsync(); var results = await _sut.SearchAsync("cereal"); Assert.Empty(results); } [Fact] public async Task GetDetailsAsync_ReturnsNullWhenProductDoesNotExist() { var details = await _sut.GetDetailsAsync(Guid.NewGuid()); Assert.Null(details); } [Fact] public async Task GetDetailsAsync_ReturnsBrandConceptAndIdentifiers() { var brand = new Brand("Jif"); var concept = new GroceryConcept("Peanut Butter", Now); var product = new Product("Jif Creamy 16 oz", ProductSourceType.Manual, Now, groceryConceptId: concept.GroceryConceptId, brandId: brand.BrandId); product.AddIdentifier(ProductIdentifierType.UpcA, "051500255516"); _db.Brands.Add(brand); _db.GroceryConcepts.Add(concept); _db.Products.Add(product); await _db.SaveChangesAsync(); var details = await _sut.GetDetailsAsync(product.ProductId); Assert.NotNull(details); Assert.Equal("Jif", details!.BrandName); Assert.Equal("Peanut Butter", details.ConceptName); Assert.Equal("051500255516", Assert.Single(details.BarcodeIdentifiers)); } }