admin/src/Oms.Tests/RulesSnapshotHelperPublishTests.cs
zzh 7827b4803e feat: slim rules/price publish snapshots with PostcodeRange (left,right]
Use slim DTOs without audit timestamps; migrate legacy LeftPostcode/RightPostcode on read.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 14:10:34 +08:00

93 lines
3.8 KiB
C#

using FluentAssertions;
using Moq;
using Oms.Application.Dtos.Orders;
using Oms.Application.Shared;
using Oms.Domain.ChannelsAggregate.Entities;
using Oms.Domain.ChannelsAggregate.Repositories;
namespace Oms.Tests;
public class RulesSnapshotHelperPublishTests
{
[Fact]
public async Task ApplyRulesToSnapshotAsync_ShouldEmbedBlacklistRemoteWeightAndRounding()
{
var product = new SalesProduct
{
Id = 1,
ProductCode = "test01",
BlacklistAreaId = 10,
RemoteAreaId = 20,
WeightRuleId = 1,
WeightRoundingId = 2
};
var kpiMock = new Mock<IKpiAreaRepository>();
kpiMock.Setup(x => x.FirstOrDefaultAsync(It.IsAny<System.Linq.Expressions.Expression<Func<KpiArea, bool>>>(), default))
.ReturnsAsync((System.Linq.Expressions.Expression<Func<KpiArea, bool>> _, CancellationToken _) =>
new KpiArea { Id = 10, Name = "黑名单区" });
kpiMock.Setup(x => x.GetAllInfosByAreaIdAsync(10, default))
.ReturnsAsync(
[
new KpiAreaInfo { Id = 1, AreaId = 10, CountryCode = "US", LeftPostcode = "90000", RightPostcode = "90010" }
]);
kpiMock.Setup(x => x.GetAllInfosByAreaIdAsync(20, default))
.ReturnsAsync(
[
new KpiAreaInfo { Id = 2, AreaId = 20, CountryCode = "US", LeftPostcode = "06000", RightPostcode = "06999" }
]);
var weightRuleMock = new Mock<IWeightRuleRepository>();
weightRuleMock.Setup(x => x.FirstOrDefaultAsync(It.IsAny<System.Linq.Expressions.Expression<Func<WeightRule, bool>>>(), default))
.ReturnsAsync(new WeightRule { Id = 1, Name = "标准计重" });
weightRuleMock.Setup(x => x.GetAllInfosByRuleIdAsync(1, default))
.ReturnsAsync(
[
new WeightRuleInfo
{
Id = 1,
RuleId = 1,
Condition = "gw>vw",
BillableWeight = "gw",
VolumetricFactor = "6000"
}
]);
var roundingMock = new Mock<IWeightRoundingRepository>();
roundingMock.Setup(x => x.FirstOrDefaultAsync(It.IsAny<System.Linq.Expressions.Expression<Func<WeightRounding, bool>>>(), default))
.ReturnsAsync(new WeightRounding { Id = 2, Name = "标准进位" });
roundingMock.Setup(x => x.GetAllInfosByRoundingIdAsync(2, default))
.ReturnsAsync(
[
new WeightRoundingInfo { Id = 1, RoundingId = 2, StartValue = 0, EndValue = 20, Public = "0.5" }
]);
var snapshot = new SalesProductRulesPublishSnapshotDto();
await RulesSnapshotHelper.ApplyRulesToSnapshotAsync(
snapshot,
product,
kpiMock.Object,
weightRuleMock.Object,
roundingMock.Object);
snapshot.BlacklistAreaId.Should().Be(10);
snapshot.BlacklistAreaInfos.Should().HaveCount(1);
snapshot.RemoteAreaId.Should().Be(20);
snapshot.RemoteAreaInfos.Should().HaveCount(1);
snapshot.WeightRuleId.Should().Be(1);
snapshot.WeightRuleInfos.Should().HaveCount(1);
snapshot.WeightRoundingId.Should().Be(2);
snapshot.WeightRoundingInfos.Should().HaveCount(1);
var json = OmsDocHelper.SerializeSnapshotJson(snapshot);
json.Should().Contain("PostcodeRange");
json.Should().Contain("(90000,90010]");
json.Should().Contain("WeightRuleInfos");
json.Should().Contain("WeightRoundingInfos");
json.Should().Contain("RemoteAreaInfos");
json.Should().NotContain("CreateTime");
json.Should().NotContain("UpdateTime");
json.Should().NotContain("LeftPostcode");
}
}