129 lines
4.1 KiB
C#
129 lines
4.1 KiB
C#
using System.Globalization;
|
|
using Bunit;
|
|
using Prefab.Web.Client.Components.Catalog;
|
|
using Prefab.Web.Client.Models.Shared;
|
|
using Prefab.Web.Client.ViewModels.Catalog;
|
|
using Shouldly;
|
|
|
|
namespace Prefab.Tests.Web.Client.Components.Catalog;
|
|
|
|
[Trait(TraitName.Category, TraitCategory.Unit)]
|
|
public sealed class ProductCardShould : BunitContext
|
|
{
|
|
[Fact]
|
|
public void RenderSaleBadgeOldPriceAndRating()
|
|
{
|
|
var model = CreateModel(m =>
|
|
{
|
|
m.IsOnSale = true;
|
|
m.OldPrice = 419m;
|
|
m.Rating = 4;
|
|
m.ReviewCount = 15;
|
|
m.Badges.Add("New");
|
|
});
|
|
|
|
var cut = Render<ProductCard>(parameters =>
|
|
{
|
|
parameters.Add(p => p.Product, model);
|
|
parameters.Add(p => p.ShowPrice, true);
|
|
});
|
|
|
|
var root = cut.Find($".{TemplateCss.ProductCardRoot}");
|
|
root.ClassList.ShouldContain(TemplateCss.ProductCardGridModifier);
|
|
|
|
cut.FindAll($".{TemplateCss.ProductCardBadgeSale}").Count.ShouldBe(1);
|
|
cut.FindAll($".{TemplateCss.ProductCardBadge}").Count.ShouldBe(2);
|
|
|
|
var newPrice = cut.Find($".{TemplateCss.ProductCardPriceNew}");
|
|
var expectedNewPrice = model.FromPrice?.Amount ?? throw new InvalidOperationException("Expected from price to be set.");
|
|
newPrice.TextContent.Trim().ShouldBe(expectedNewPrice.ToString("C", CultureInfo.CurrentCulture));
|
|
|
|
var oldPrice = cut.Find($".{TemplateCss.ProductCardPriceOld}");
|
|
var expectedOldPrice = model.OldPrice ?? throw new InvalidOperationException("Expected old price to be set for sale items.");
|
|
oldPrice.TextContent.Trim().ShouldBe(expectedOldPrice.ToString("C", CultureInfo.CurrentCulture));
|
|
|
|
var rating = cut.Find($".{TemplateCss.ProductCardRating}");
|
|
var ratingLabel = rating.QuerySelector($".{TemplateCss.Rating}")!;
|
|
ratingLabel.GetAttribute("aria-label").ShouldBe("4 out of 5");
|
|
}
|
|
|
|
[Fact]
|
|
public void NotRenderSaleBadgeOrOldPriceWhenAbsent()
|
|
{
|
|
var model = CreateModel(m =>
|
|
{
|
|
m.IsOnSale = false;
|
|
m.OldPrice = null;
|
|
m.Rating = 0;
|
|
m.ReviewCount = 0;
|
|
});
|
|
|
|
var cut = Render<ProductCard>(parameters =>
|
|
{
|
|
parameters.Add(p => p.Product, model);
|
|
parameters.Add(p => p.ShowPrice, true);
|
|
});
|
|
|
|
cut.FindAll($".{TemplateCss.ProductCardBadgeSale}").ShouldBeEmpty();
|
|
cut.Markup.ShouldNotContain(TemplateCss.ProductCardPriceOld);
|
|
cut.Markup.ShouldNotContain(TemplateCss.ProductCardRating);
|
|
}
|
|
|
|
[Fact]
|
|
public void NotRenderPricesByDefault()
|
|
{
|
|
var model = CreateModel();
|
|
|
|
var cut = Render<ProductCard>(parameters =>
|
|
{
|
|
parameters.Add(p => p.Product, model);
|
|
// ShowPrice is false by default
|
|
});
|
|
|
|
cut.Markup.ShouldNotContain(TemplateCss.ProductCardPrice);
|
|
}
|
|
|
|
[Fact]
|
|
public void NotRenderActionButtons()
|
|
{
|
|
var model = CreateModel();
|
|
|
|
var cut = Render<ProductCard>(parameters =>
|
|
{
|
|
parameters.Add(p => p.Product, model);
|
|
});
|
|
|
|
cut.Markup.ShouldNotContain("product-card__actions");
|
|
cut.Markup.ShouldNotContain("product-card__buttons");
|
|
}
|
|
|
|
private static ProductCardModel CreateModel(Action<ProductCardModel>? configure = null)
|
|
{
|
|
var model = new ProductCardModel
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Title = "Aluminum Chandelier",
|
|
Url = "/browse/product?slug=aluminum-chandelier",
|
|
Slug = "aluminum-chandelier",
|
|
CategoryName = "Chandeliers",
|
|
CategoryUrl = "/catalog/chandeliers",
|
|
PrimaryImageUrl = "/images/products/product1.jpg",
|
|
FromPrice = new MoneyModel
|
|
{
|
|
Amount = 321.54m,
|
|
Currency = "USD"
|
|
},
|
|
IsPriced = true,
|
|
Rating = 3,
|
|
ReviewCount = 2,
|
|
Sku = "SKU-1001",
|
|
IsOnSale = true,
|
|
OldPrice = 399.99m,
|
|
LastModifiedOn = DateTimeOffset.UtcNow
|
|
};
|
|
|
|
configure?.Invoke(model);
|
|
return model;
|
|
}
|
|
}
|