119 lines
3.8 KiB
C#
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);
|
|
}
|
|
}
|