using System.Linq; using Prefab.Web.Client.Models.Home; using Prefab.Web.Client.Models.Shared; using Prefab.Web.Client.Pages; using Prefab.Web.Client.Services; using Prefab.Web.Client.ViewModels.Catalog; using Shouldly; using Telerik.Blazor.Components; namespace Prefab.Tests.Web.Client.Pages; [Trait(TraitName.Category, TraitCategory.Unit)] public sealed class HomeComponentShould { [Fact] public async Task LoadHomeContentPopulatesProductsAndCategories() { var payload = new HomePageModel { FeaturedProducts = Enumerable.Range(0, 3) .Select(index => new ProductCardModel { Title = $"Product {index}", Url = $"/product/{index}", FromPrice = new MoneyModel { Amount = index, Currency = "USD" }, IsPriced = true, Sku = $"SKU-{index}", LastModifiedOn = DateTimeOffset.UtcNow }) .ToList(), LatestCategories = new List { new() { Title = "Leaf A", Url = "/catalog/category?category-slug=leaf-a", SecondaryText = "2 Products" } } }; var service = new FakeHomePageService(Result.Success(payload)); var component = new TestableHomeComponent(); component.ConfigureServices(service, new NoopNotificationService()); await component.InitializeAsync(); component.IsProductsLoading.ShouldBeFalse(); component.IsCategoriesLoading.ShouldBeFalse(); component.FeaturedProductsView.Count.ShouldBe(3); component.CategoriesView.Count.ShouldBe(1); } [Fact] public async Task LeaveCollectionsEmptyWhenServiceReturnsNoData() { var service = new FakeHomePageService(Result.Success(new HomePageModel())); var component = new TestableHomeComponent(); component.ConfigureServices(service, new NoopNotificationService()); await component.InitializeAsync(); component.FeaturedProductsView.ShouldBeEmpty(); component.CategoriesView.ShouldBeEmpty(); component.HasFeaturedProducts.ShouldBeFalse(); component.HasCategories.ShouldBeFalse(); } private sealed class FakeHomePageService(Result result) : IHomePageService { private Result Result { get; set; } = result; public Task> Get(CancellationToken cancellationToken) => Task.FromResult(Result); } private sealed class NoopNotificationService : INotificationService { public void Attach(TelerikNotification notification) { } public void ShowError(string message) { } public void ShowSuccess(string message) { } public void ShowWarning(string message) { } } private sealed class TestableHomeComponent : HomeComponent { public void ConfigureServices(IHomePageService homePageService, INotificationService notificationService) { HomePageService = homePageService; NotificationService = notificationService; } public Task InitializeAsync() => OnInitializedAsync(); public IReadOnlyList FeaturedProductsView => base.FeaturedProducts; public IReadOnlyList CategoriesView => base.LatestCategories; public bool IsProductsLoading => IsFeaturedProductsLoading; public bool IsCategoriesLoading => base.AreCategoriesLoading; public bool HasFeaturedProducts => FeaturedProductsHaveItemsToShow; public bool HasCategories => CategoriesHaveItemsToShow; } }