All checks were successful
Build and Deploy / deploy (push) Successful in 1m0s
分区明细独立版本化并缓存加载,计费包缺失严格失败;同步态接口不再拉全文。 Co-authored-by: Cursor <cursoragent@cursor.com>
107 lines
4.3 KiB
C#
107 lines
4.3 KiB
C#
using System.Linq.Expressions;
|
|
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_ShouldPinBlacklistRemotePacksAndEmbedWeight()
|
|
{
|
|
var product = new SalesProduct
|
|
{
|
|
Id = 1,
|
|
ProductCode = "test01",
|
|
BlacklistAreaId = 10,
|
|
RemoteAreaId = 20,
|
|
WeightRuleId = 1,
|
|
WeightRoundingId = 2
|
|
};
|
|
|
|
var areas = new Dictionary<int, KpiArea>
|
|
{
|
|
[10] = new() { Id = 10, Name = "黑名单区", AreaType = "blacklist" },
|
|
[20] = new() { Id = 20, Name = "偏远区", AreaType = "remote" }
|
|
};
|
|
|
|
var kpiMock = new Mock<IKpiAreaRepository>();
|
|
kpiMock.Setup(x => x.FirstOrDefaultAsync(It.IsAny<Expression<Func<KpiArea, bool>>>(), default))
|
|
.ReturnsAsync((Expression<Func<KpiArea, bool>> expr, CancellationToken _) =>
|
|
areas.Values.FirstOrDefault(expr.Compile()));
|
|
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" }
|
|
]);
|
|
kpiMock.Setup(x => x.FindPublishByAreaIdAndContentHashAsync(It.IsAny<int>(), It.IsAny<string>(), default))
|
|
.ReturnsAsync((KpiAreaPublishRecord?)null);
|
|
kpiMock.Setup(x => x.InsertPublishRecordAsync(It.IsAny<KpiAreaPublishRecord>(), default))
|
|
.ReturnsAsync((KpiAreaPublishRecord r, CancellationToken _) =>
|
|
{
|
|
r.Id = r.AreaId * 100;
|
|
return r;
|
|
});
|
|
|
|
var weightRuleMock = new Mock<IWeightRuleRepository>();
|
|
weightRuleMock.Setup(x => x.FirstOrDefaultAsync(It.IsAny<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<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 packService = new KpiAreaPackService(kpiMock.Object);
|
|
var snapshot = new SalesProductRulesPublishSnapshotDto();
|
|
await RulesSnapshotHelper.ApplyRulesToSnapshotAsync(
|
|
snapshot,
|
|
product,
|
|
kpiMock.Object,
|
|
weightRuleMock.Object,
|
|
roundingMock.Object,
|
|
packService,
|
|
"tester");
|
|
|
|
snapshot.BlacklistAreaId.Should().Be(10);
|
|
snapshot.BlacklistAreaRef.Should().NotBeNull();
|
|
snapshot.BlacklistAreaRef!.PackVersion.Should().NotBeNullOrWhiteSpace();
|
|
snapshot.BlacklistAreaInfos.Should().BeEmpty();
|
|
snapshot.RemoteAreaRef.Should().NotBeNull();
|
|
snapshot.RemoteAreaRef!.AreaId.Should().Be(20);
|
|
snapshot.WeightRuleInfos.Should().HaveCount(1);
|
|
snapshot.WeightRoundingInfos.Should().HaveCount(1);
|
|
|
|
var json = OmsDocHelper.SerializeSnapshotJson(snapshot)!;
|
|
json.Should().Contain("blacklistAreaRef");
|
|
json.Should().Contain("remoteAreaRef");
|
|
json.Should().NotContain("blacklistAreaInfos");
|
|
json.Should().NotContain("remoteAreaInfos");
|
|
}
|
|
}
|