Files
prefab-page-detail/Prefab.Tests/Unit/Web/Pricing/FromPriceCalculatorShould.cs
2025-10-27 17:39:18 -04:00

119 lines
3.8 KiB
C#

using Prefab.Catalog.Domain.Entities;
using Prefab.Catalog.Domain.Services;
using Prefab.Tests;
using Prefab.Web.Pricing;
using Shouldly;
namespace Prefab.Tests.Unit.Web.Pricing;
[Trait(TraitName.Category, TraitCategory.Unit)]
public sealed class FromPriceCalculatorShould
{
private readonly FromPriceCalculator _calculator = new();
private readonly IUniqueChecker _uniqueChecker = new AlwaysUniqueChecker();
[Fact]
public async Task UseModelPriceWhenAvailable()
{
var cancellationToken = TestContext.Current.CancellationToken;
var product = await Product.CreateModel(
name: "Model A",
slug: "model-a",
description: null,
uniqueChecker: _uniqueChecker,
cancellationToken: cancellationToken);
product.SetBasePrice(199.99m);
var variant = await Product.CreateVariant(
product.Id,
sku: "SKU-1",
name: "Variant 1",
price: 149.99m,
uniqueChecker: _uniqueChecker,
cancellationToken: cancellationToken);
product.AttachVariant(variant);
var result = _calculator.Compute(product);
result.IsPriced.ShouldBeTrue();
result.Amount.ShouldBe(199.99m);
result.Currency.ShouldBe("USD");
}
[Fact]
public async Task UseLowestVariantPriceWhenModelPriceMissing()
{
var cancellationToken = TestContext.Current.CancellationToken;
var product = await Product.CreateModel(
name: "Model B",
slug: "model-b",
description: null,
uniqueChecker: _uniqueChecker,
cancellationToken: cancellationToken);
var highVariant = await Product.CreateVariant(
product.Id,
sku: "HIGH",
name: "High Variant",
price: 249.50m,
uniqueChecker: _uniqueChecker,
cancellationToken: cancellationToken);
var lowVariant = await Product.CreateVariant(
product.Id,
sku: "LOW",
name: "Low Variant",
price: 125.25m,
uniqueChecker: _uniqueChecker,
cancellationToken: cancellationToken);
product.AttachVariant(highVariant);
product.AttachVariant(lowVariant);
var result = _calculator.Compute(product);
result.IsPriced.ShouldBeTrue();
result.Amount.ShouldBe(125.25m);
result.Currency.ShouldBe("USD");
}
[Fact]
public async Task ReturnUnpricedWhenNoPricesAvailable()
{
var cancellationToken = TestContext.Current.CancellationToken;
var product = await Product.CreateModel(
name: "Model C",
slug: "model-c",
description: null,
uniqueChecker: _uniqueChecker,
cancellationToken: cancellationToken);
var result = _calculator.Compute(product);
result.IsPriced.ShouldBeFalse();
result.Amount.ShouldBeNull();
result.Currency.ShouldBeNull();
}
private sealed class AlwaysUniqueChecker : IUniqueChecker
{
public Task<bool> CategoryNameIsUnique(string name, CancellationToken cancellationToken = default) =>
Task.FromResult(true);
public Task<bool> ProductModelNameIsUnique(string name, CancellationToken cancellationToken = default) =>
Task.FromResult(true);
public Task<bool> ProductSlugIsUnique(string? slug, CancellationToken cancellationToken = default) =>
Task.FromResult(true);
public Task<bool> ProductSkuIsUnique(string sku, CancellationToken cancellationToken = default) =>
Task.FromResult(true);
public Task<bool> OptionCodeIsUniqueForProduct(Guid productId, string code, CancellationToken cancellationToken = default) =>
Task.FromResult(true);
}
}