mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 11:21:13 +00:00
6f23120c49
Extracts RouteRegionMatcher, RouteCsvWriter, RouteSummaryWriter, RouteImageRenderer, TilesZipBuilder, RegionFileCleaner from the ~750-LOC RouteProcessingService god-class. Moves TileInfo to its own file as a sealed record. Replaces IServiceProvider scope- locator with a direct IRegionService injection (folds AZ-360 / C08). Updates DI registration and tests. Tests: 133 / 133 unit + 5 / 5 smoke green; integration suite exit 0. Pixel-equivalent stitched route image and byte-equivalent CSV / summary / ZIP outputs verified through the smoke run. Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
3.5 KiB
C#
100 lines
3.5 KiB
C#
using FluentAssertions;
|
|
using SatelliteProvider.DataAccess.Models;
|
|
using SatelliteProvider.Services.RouteManagement;
|
|
|
|
namespace SatelliteProvider.Tests;
|
|
|
|
// AZ-364 / C11: pure-helper tests for the route-point ↔ region nearest-
|
|
// neighbour matcher extracted from RouteProcessingService.
|
|
public class RouteRegionMatcherTests
|
|
{
|
|
[Fact]
|
|
public void Match_OrdersRegionsToFollowRoutePointSequence_AZ364_AC1()
|
|
{
|
|
// Arrange
|
|
var sut = new RouteRegionMatcher();
|
|
|
|
var routePoints = new List<RoutePointEntity>
|
|
{
|
|
new() { Latitude = 0.0, Longitude = 0.0, SequenceNumber = 0 },
|
|
new() { Latitude = 1.0, Longitude = 0.0, SequenceNumber = 1 },
|
|
new() { Latitude = 2.0, Longitude = 0.0, SequenceNumber = 2 },
|
|
};
|
|
|
|
var regionFar = new RegionEntity { Id = Guid.NewGuid(), Latitude = 2.0, Longitude = 0.0 };
|
|
var regionNear = new RegionEntity { Id = Guid.NewGuid(), Latitude = 0.0, Longitude = 0.0 };
|
|
var regionMid = new RegionEntity { Id = Guid.NewGuid(), Latitude = 1.0, Longitude = 0.0 };
|
|
|
|
var unorderedRegions = new List<RegionEntity> { regionFar, regionNear, regionMid };
|
|
|
|
// Act
|
|
var ordered = sut.Match(routePoints, unorderedRegions);
|
|
|
|
// Assert
|
|
ordered.Should().HaveCount(3);
|
|
ordered[0].Id.Should().Be(regionNear.Id);
|
|
ordered[1].Id.Should().Be(regionMid.Id);
|
|
ordered[2].Id.Should().Be(regionFar.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Match_ConsumesEachRegionAtMostOnce_AZ364_AC1()
|
|
{
|
|
// Arrange
|
|
var sut = new RouteRegionMatcher();
|
|
var sharedRegion = new RegionEntity { Id = Guid.NewGuid(), Latitude = 0.0, Longitude = 0.0 };
|
|
var otherRegion = new RegionEntity { Id = Guid.NewGuid(), Latitude = 10.0, Longitude = 0.0 };
|
|
|
|
var routePoints = new List<RoutePointEntity>
|
|
{
|
|
new() { Latitude = 0.0, Longitude = 0.0, SequenceNumber = 0 },
|
|
new() { Latitude = 0.001, Longitude = 0.0, SequenceNumber = 1 },
|
|
};
|
|
|
|
// Act
|
|
var ordered = sut.Match(routePoints, new List<RegionEntity> { sharedRegion, otherRegion });
|
|
|
|
// Assert
|
|
ordered.Should().HaveCount(2);
|
|
ordered.Select(r => r.Id).Should().OnlyHaveUniqueItems();
|
|
ordered[0].Id.Should().Be(sharedRegion.Id);
|
|
ordered[1].Id.Should().Be(otherRegion.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Match_FewerRegionsThanPoints_ReturnsAvailableSubset_AZ364_AC1()
|
|
{
|
|
// Arrange
|
|
var sut = new RouteRegionMatcher();
|
|
var soleRegion = new RegionEntity { Id = Guid.NewGuid(), Latitude = 0.0, Longitude = 0.0 };
|
|
|
|
var routePoints = new List<RoutePointEntity>
|
|
{
|
|
new() { Latitude = 0.0, Longitude = 0.0, SequenceNumber = 0 },
|
|
new() { Latitude = 1.0, Longitude = 0.0, SequenceNumber = 1 },
|
|
};
|
|
|
|
// Act
|
|
var ordered = sut.Match(routePoints, new List<RegionEntity> { soleRegion });
|
|
|
|
// Assert
|
|
ordered.Should().HaveCount(1);
|
|
ordered[0].Id.Should().Be(soleRegion.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Match_NullArguments_Throws_AZ364_AC1()
|
|
{
|
|
// Arrange
|
|
var sut = new RouteRegionMatcher();
|
|
|
|
// Act
|
|
Action actNullPoints = () => sut.Match(null!, new List<RegionEntity>());
|
|
Action actNullRegions = () => sut.Match(new List<RoutePointEntity>(), null!);
|
|
|
|
// Assert
|
|
actNullPoints.Should().Throw<ArgumentNullException>();
|
|
actNullRegions.Should().Throw<ArgumentNullException>();
|
|
}
|
|
}
|