231 lines
9.3 KiB
C#
231 lines
9.3 KiB
C#
using ShippingCosts.Contracts;
|
|
using ShippingCosts.Implementations;
|
|
|
|
namespace ShippingCosts.Test;
|
|
|
|
public sealed class LPSShippingCostCalculatorTests : ShippingCostCalculatorBaseTestBase
|
|
{
|
|
private readonly ICountryDistanceProvider _defaultDistanceProvider = ConfigureDefaultCountryProvider();
|
|
private readonly IMeasuredBox _sampleBox = ConfigureDefaultBox();
|
|
|
|
[Fact]
|
|
public void CarrierName()
|
|
{
|
|
new LPSShippingCostCalculator(_defaultDistanceProvider).CarrierName.Should()
|
|
.NotBeNullOrWhiteSpace()
|
|
.And.Be("Leonding Parcel Service");
|
|
}
|
|
|
|
[Fact]
|
|
public void CalculateShippingCosts_ValidCountry()
|
|
{
|
|
var calculator = new LPSShippingCostCalculator(_defaultDistanceProvider);
|
|
|
|
calculator.CalculateShippingCosts(CountryNotNeighborEu, _sampleBox)
|
|
.Should().NotBeNull("country is known, shipping price can be calculated");
|
|
}
|
|
|
|
[Fact]
|
|
public void CalculateShippingCosts_InvalidCountry()
|
|
{
|
|
var calculator = new LPSShippingCostCalculator(_defaultDistanceProvider);
|
|
|
|
calculator.CalculateShippingCosts("Atlantis", _sampleBox)
|
|
.Should().BeNull("country is not known, shipping price cannot be calculated");
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(CalculateShippingCostsWeightData))]
|
|
public void CalculateShippingCosts_Weight(double weight, decimal? expectedPrice)
|
|
{
|
|
var distanceProvider = Substitute.For<ICountryDistanceProvider>();
|
|
distanceProvider.IsPossibleCountry(Arg.Any<string>()).ReturnsForAnyArgs(true);
|
|
distanceProvider.GetDistanceTo(Arg.Any<string>())
|
|
.ReturnsForAnyArgs(new CountryDistanceInformation(0, true, true));
|
|
var minSizeBox = Substitute.For<IMeasuredBox>();
|
|
minSizeBox.Width.Returns(1);
|
|
minSizeBox.Height.Returns(1);
|
|
minSizeBox.Depth.Returns(1);
|
|
minSizeBox.Weight.Returns(weight);
|
|
|
|
var calculator = new LPSShippingCostCalculator(distanceProvider);
|
|
|
|
calculator.CalculateShippingCosts(string.Empty, minSizeBox)
|
|
.Should().Be(expectedPrice + BasePriceDistance, "weight cost + base price distance");
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(CalculateShippingCostsSizeData))]
|
|
public void CalculateShippingCosts_Size(int boxSize, decimal? expectedPrice)
|
|
{
|
|
var distanceProvider = Substitute.For<ICountryDistanceProvider>();
|
|
distanceProvider.IsPossibleCountry(Arg.Any<string>()).ReturnsForAnyArgs(true);
|
|
distanceProvider.GetDistanceTo(Arg.Any<string>())
|
|
.ReturnsForAnyArgs(new CountryDistanceInformation(0, true, true));
|
|
var minWeightBox = Substitute.For<IMeasuredBox>();
|
|
minWeightBox.Width.Returns(1);
|
|
minWeightBox.Height.Returns(1);
|
|
minWeightBox.Depth.Returns(boxSize - 1); // size sum will be longest + shortest => 1 + (boxSize - 1) = boxSize
|
|
minWeightBox.Weight.Returns(0.1D);
|
|
|
|
var calculator = new LPSShippingCostCalculator(distanceProvider);
|
|
|
|
calculator.CalculateShippingCosts(string.Empty, minWeightBox)
|
|
.Should().Be(expectedPrice + BasePriceDistance, "size cost + base price distance");
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(CalculateShippingCostsDistanceData))]
|
|
public void CalculateShippingCosts_Distance(CountryDistanceInformation distance, decimal expectedPrice)
|
|
{
|
|
var distanceProvider = Substitute.For<ICountryDistanceProvider>();
|
|
distanceProvider.IsPossibleCountry(Arg.Any<string>()).ReturnsForAnyArgs(true);
|
|
distanceProvider.GetDistanceTo(Arg.Any<string>()).ReturnsForAnyArgs(distance);
|
|
var minimalBox = Substitute.For<IMeasuredBox>();
|
|
minimalBox.Width.Returns(1);
|
|
minimalBox.Height.Returns(1);
|
|
minimalBox.Depth.Returns(1);
|
|
minimalBox.Weight.Returns(0.1D);
|
|
|
|
var calculator = new LPSShippingCostCalculator(distanceProvider);
|
|
|
|
calculator.CalculateShippingCosts(string.Empty, minimalBox)
|
|
.Should().Be(expectedPrice + BasePriceDistance, "distance cost + base price distance");
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(CalculateShippingCostsData))]
|
|
public void CalculateShippingCosts(CountryDistanceInformation distance, IMeasuredBox box, decimal expectedPrice)
|
|
{
|
|
var distanceProvider = Substitute.For<ICountryDistanceProvider>();
|
|
distanceProvider.IsPossibleCountry(Arg.Any<string>()).ReturnsForAnyArgs(true);
|
|
distanceProvider.GetDistanceTo(Arg.Any<string>()).ReturnsForAnyArgs(distance);
|
|
|
|
var calculator = new LPSShippingCostCalculator(distanceProvider);
|
|
|
|
calculator.CalculateShippingCosts(string.Empty, box)
|
|
.Should().Be(expectedPrice);
|
|
}
|
|
|
|
[Fact]
|
|
public void InterfaceAndClassHierarchy()
|
|
{
|
|
var calculator = new LPSShippingCostCalculator(_defaultDistanceProvider);
|
|
|
|
calculator.Should().BeAssignableTo<ShippingCostCalculatorBase>()
|
|
.And.BeAssignableTo<IShippingCostCalculator>();
|
|
}
|
|
|
|
#region Test Data
|
|
|
|
private const string CountryNeighborEu = "A";
|
|
private const string CountryNeighborNotEu = "B";
|
|
private const string CountryNotNeighborEu = "C";
|
|
private const string CountryNotNeighborNotEu = "D";
|
|
private const decimal BasePriceDistance = 2.99M;
|
|
|
|
public static TheoryData<double, decimal?> CalculateShippingCostsWeightData() =>
|
|
new()
|
|
{
|
|
{ 0.4D, 0M },
|
|
{ 1.1D, 0M },
|
|
{ 1.49D, 0M },
|
|
{ 1.5D, 0.5M },
|
|
{ 1.85D, 0.5M },
|
|
{ 2.8D, 1.5M },
|
|
{ 3D, 1.65M },
|
|
{ 4.22D, 2.321M },
|
|
{ 34.9D, 19.195M },
|
|
{ 38D, 20M },
|
|
{ 51.3D, 20M },
|
|
{ -2D, null },
|
|
{ 0, null }
|
|
};
|
|
|
|
public static TheoryData<int, decimal?> CalculateShippingCostsSizeData() =>
|
|
new()
|
|
{
|
|
{ 40, 0M },
|
|
{ 120, 0M },
|
|
{ 249, 0M },
|
|
{ 250, 0.75M },
|
|
{ 399, 0.75M },
|
|
{ 400, 1.25M },
|
|
{ 581, 1.25M },
|
|
{ 677, 2.6M },
|
|
{ 901, 3.5M },
|
|
{ 1492, 3.5M },
|
|
{ -1, null },
|
|
{ 0, null }
|
|
};
|
|
|
|
public static TheoryData<CountryDistanceInformation, decimal> CalculateShippingCostsDistanceData() =>
|
|
new()
|
|
{
|
|
{ new CountryDistanceInformation(200, true, false), 3.315M },
|
|
{ new CountryDistanceInformation(415, true, true), 0.825M },
|
|
{ new CountryDistanceInformation(857, false, true), 2.2M },
|
|
{ new CountryDistanceInformation(1549, false, false), 6.89M },
|
|
{ new CountryDistanceInformation(2087, true, false), 6.615M },
|
|
{ new CountryDistanceInformation(2796, true, true), 4.95M },
|
|
{ new CountryDistanceInformation(3448, false, true), 7.7M },
|
|
{ new CountryDistanceInformation(4179, false, false), 12.39M },
|
|
{ new CountryDistanceInformation(5028, true, false), 11.565M },
|
|
{ new CountryDistanceInformation(5886, true, true), 9.9M },
|
|
{ new CountryDistanceInformation(6632, false, true), 15.4M },
|
|
{ new CountryDistanceInformation(7356, false, false), 18.99M },
|
|
{ new CountryDistanceInformation(8223, true, false), 16.515M },
|
|
{ new CountryDistanceInformation(9010, true, true), 15.675M },
|
|
{ new CountryDistanceInformation(9671, false, true), 22M },
|
|
{ new CountryDistanceInformation(10463, false, false), 25.59M }
|
|
};
|
|
|
|
public static TheoryData<CountryDistanceInformation, IMeasuredBox, decimal> CalculateShippingCostsData() =>
|
|
new()
|
|
{
|
|
{
|
|
new CountryDistanceInformation(857, false, true),
|
|
CreateBox(400, 360, 220, 3.2D),
|
|
8.2M
|
|
},
|
|
{
|
|
new CountryDistanceInformation(2087, true, false),
|
|
CreateBox(190, 80, 100, 1.45D),
|
|
10.355M
|
|
},
|
|
{
|
|
new CountryDistanceInformation(386, true, true),
|
|
ConfigureDefaultBox(),
|
|
5.065M
|
|
},
|
|
{
|
|
new CountryDistanceInformation(7356, false, false),
|
|
CreateBox(811, 490, 550, 176.2D),
|
|
45.48M
|
|
}
|
|
};
|
|
|
|
private static IMeasuredBox ConfigureDefaultBox() => CreateBox(320, 160, 200, 0.8D);
|
|
|
|
private static ICountryDistanceProvider ConfigureDefaultCountryProvider()
|
|
{
|
|
var provider = Substitute.For<ICountryDistanceProvider>();
|
|
provider.IsPossibleCountry(Arg.Is<string>(n => new[]
|
|
{
|
|
CountryNeighborEu, CountryNeighborNotEu, CountryNotNeighborEu, CountryNotNeighborNotEu
|
|
}.Contains(n)))
|
|
.Returns(true);
|
|
provider.GetDistanceTo(Arg.Is(CountryNeighborEu))
|
|
.Returns(new CountryDistanceInformation(640, true, true));
|
|
provider.GetDistanceTo(Arg.Is(CountryNeighborNotEu))
|
|
.Returns(new CountryDistanceInformation(480, true, false));
|
|
provider.GetDistanceTo(Arg.Is(CountryNotNeighborEu))
|
|
.Returns(new CountryDistanceInformation(1311, false, true));
|
|
provider.GetDistanceTo(Arg.Is(CountryNotNeighborNotEu))
|
|
.Returns(new CountryDistanceInformation(6874, false, false));
|
|
|
|
return provider;
|
|
}
|
|
|
|
#endregion
|
|
}
|