using Moq; using Prefab.Shared.Catalog; using Prefab.Shared.Catalog.Products; using Prefab.Tests; using Prefab.Web.Client.Models.Catalog; using Prefab.Web.Gateway; using Shouldly; namespace Prefab.Tests.Unit.Web.Gateway; [Trait(TraitName.Category, TraitCategory.Unit)] public sealed class ProductListingServiceShould { [Fact] public async Task MapPricesAndImagesFromModuleResponse() { var categorySlug = "ceiling-supports"; var moduleClient = new Mock(); var productClient = new Mock(); moduleClient.SetupGet(client => client.Product).Returns(productClient.Object); var category = new GetCategoryModels.CategoryDetailDto( Guid.NewGuid(), "Ceiling Supports", categorySlug, Description: "Fixtures for ceiling support assemblies.", HeroImageUrl: "/media/categories/ceiling.jpg", Icon: null, IsLeaf: true, Children: Array.Empty()); var cardId = Guid.NewGuid(); var response = new GetCategoryModels.CategoryProductsResponse( category, new[] { new GetCategoryModels.ProductCardDto( cardId, "Fan Hanger Assembly", "fan-hanger-assembly", FromPrice: 129.99m, PrimaryImageUrl: "/media/products/fan-hanger.jpg", LastModifiedOn: DateTimeOffset.UtcNow) }, Total: 1, Page: 1, PageSize: 24); productClient .Setup(client => client.GetCategoryModels(categorySlug, null, null, null, null, It.IsAny())) .ReturnsAsync(new GetCategoryModels.Response(response)); var service = new Products.ListingService(moduleClient.Object); var result = await service.GetCategoryProducts(categorySlug, CancellationToken.None); result.IsSuccess.ShouldBeTrue(); result.Value.ShouldNotBeNull(); var model = result.Value; model.Category.Slug.ShouldBe(categorySlug); model.Products.Count.ShouldBe(1); var card = model.Products.Single(); card.Id.ShouldBe(cardId); card.Title.ShouldBe("Fan Hanger Assembly"); card.Slug.ShouldBe("fan-hanger-assembly"); card.PrimaryImageUrl.ShouldBe("/media/products/fan-hanger.jpg"); card.IsPriced.ShouldBeTrue(); card.FromPrice.ShouldNotBeNull(); card.FromPrice!.Amount.ShouldBe(129.99m); } [Fact] public async Task MarkProductsWithoutPriceAsUnpriced() { var categorySlug = "rod-strut-hardware"; var moduleClient = new Mock(); var productClient = new Mock(); moduleClient.SetupGet(client => client.Product).Returns(productClient.Object); var category = new GetCategoryModels.CategoryDetailDto( Guid.NewGuid(), "Rod & Strut Hardware", categorySlug, Description: null, HeroImageUrl: null, Icon: null, IsLeaf: true, Children: Array.Empty()); var response = new GetCategoryModels.CategoryProductsResponse( category, new[] { new GetCategoryModels.ProductCardDto( Guid.NewGuid(), "Unpriced Assembly", "unpriced-assembly", FromPrice: null, PrimaryImageUrl: null, LastModifiedOn: DateTimeOffset.UtcNow) }, Total: 1, Page: 1, PageSize: 12); productClient .Setup(client => client.GetCategoryModels(categorySlug, null, null, null, null, It.IsAny())) .ReturnsAsync(new GetCategoryModels.Response(response)); var service = new Products.ListingService(moduleClient.Object); var result = await service.GetCategoryProducts(categorySlug, CancellationToken.None); result.IsSuccess.ShouldBeTrue(); result.Value.ShouldNotBeNull(); var card = result.Value.Products.Single(); card.IsPriced.ShouldBeFalse(); card.FromPrice.ShouldBeNull(); } }