using FluentAssertions; using Oms.Application.Dtos.Channels; using Oms.Application.Shared; using Oms.Domain.ChannelsAggregate.Consts; using Oms.Domain.ChannelsAggregate.Entities; namespace Oms.Tests; public class AllocationResolverTests { [Fact] public void FilterProviders_ShouldRespectCustomerScope() { var providers = new List { new() { SerialNumber = 1, ServiceChannelId = 1, CustomerIds = [10] }, new() { SerialNumber = 2, ServiceChannelId = 2, CustomerIds = [] }, new() { SerialNumber = 3, ServiceChannelId = null } }; var filtered = AllocationResolver.FilterProviders(providers, 10); filtered.Should().HaveCount(2); filtered.Select(x => x.ServiceChannelId).Should().BeEquivalentTo([1, 2]); } [Fact] public void SelectChannel_CostLowest_ShouldPickCheapest() { var candidates = BuildCandidates( (1, 30m, 5, 10), (2, 20m, 8, 20)); var channel = AllocationResolver.SelectChannel(AllocationSchemeCodes.CostLowest, candidates); channel.Id.Should().Be(2); } [Fact] public void SelectChannel_TimeFastest_ShouldPickLowestMinTime() { var candidates = BuildCandidates( (1, 30m, 5, 10), (2, 20m, 3, 20)); var channel = AllocationResolver.SelectChannel(AllocationSchemeCodes.TimeFastest, candidates); channel.Id.Should().Be(2); } [Fact] public void SelectChannel_OverallBest_ShouldPickHighestWeight() { var candidates = BuildCandidates( (1, 30m, 5, 10), (2, 20m, 8, 30)); var channel = AllocationResolver.SelectChannel(AllocationSchemeCodes.OverallBest, candidates); channel.Id.Should().Be(2); } private static List BuildCandidates( params (int channelId, decimal cost, int minTime, int weight)[] rows) { return rows.Select(row => new AllocationResolver.ChannelCandidate { Provider = new SalesProductAllocationProviderSnapshotDto { SerialNumber = row.channelId, ServiceChannelId = row.channelId, Weight = row.weight }, Channel = new ServiceChannel { Id = row.channelId, ChannelCode = $"CH-{row.channelId}", MinTime = row.minTime }, TotalPayableCost = row.cost }).ToList(); } }