mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-22 01:21:14 +00:00
[AZ-351][AZ-352][AZ-363] Refactor 03 batch 1: critical defensive fixes
AZ-351: Resolve ILogger<DatabaseMigrator> directly from DI in Program.cs instead of casting ILogger<Program> (which always returned null). Migrator now logs through Serilog at startup. AZ-352: Drop empty catch in RouteProcessingService.ExtractTileCoordinatesFromFilename. Convert the method from private static to internal instance so it can use the existing _logger (per coderule: side-effecting code must not be static). Add typed null-guard via ArgumentNullException.ThrowIfNull so unexpected exceptions propagate. Adds InternalsVisibleTo on the RouteManagement csproj for SatelliteProvider.Tests, plus 4 unit tests in RouteProcessingServiceTests.cs covering AC-1 (valid / malformed / non-numeric) and AC-2 (null path propagation). AZ-363: Delete _totalEnqueued / _totalDequeued fields and the two non-atomic ++ writes in RegionRequestQueue. Fields were write-only dead code and a thread-safety hazard. Tests: 44/44 unit + 5/5 smoke (scripts/run-tests.sh --smoke). Code review verdict: PASS, 0 findings, 0 auto-fix attempts. Batch report: _docs/03_implementation/batch_07_report.md. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using SatelliteProvider.Common.Configs;
|
||||
using SatelliteProvider.DataAccess.Repositories;
|
||||
using SatelliteProvider.Services.RouteManagement;
|
||||
|
||||
namespace SatelliteProvider.Tests;
|
||||
|
||||
public class RouteProcessingServiceTests
|
||||
{
|
||||
private static RouteProcessingService BuildSut(out Mock<ILogger<RouteProcessingService>> loggerMock)
|
||||
{
|
||||
loggerMock = new Mock<ILogger<RouteProcessingService>>();
|
||||
var routeRepo = new Mock<IRouteRepository>();
|
||||
var regionRepo = new Mock<IRegionRepository>();
|
||||
var serviceProvider = new Mock<IServiceProvider>();
|
||||
var storageOptions = Options.Create(new StorageConfig());
|
||||
|
||||
return new RouteProcessingService(
|
||||
routeRepo.Object,
|
||||
regionRepo.Object,
|
||||
serviceProvider.Object,
|
||||
storageOptions,
|
||||
loggerMock.Object);
|
||||
}
|
||||
|
||||
private static void VerifyWarningLogged(Mock<ILogger<RouteProcessingService>> loggerMock, string substringInState)
|
||||
{
|
||||
loggerMock.Verify(
|
||||
l => l.Log(
|
||||
LogLevel.Warning,
|
||||
It.IsAny<EventId>(),
|
||||
It.Is<It.IsAnyType>((state, _) => state.ToString()!.Contains(substringInState)),
|
||||
It.IsAny<Exception?>(),
|
||||
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
|
||||
Times.AtLeastOnce);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtractTileCoordinatesFromFilename_ValidName_ReturnsParsedCoordinates_AC1()
|
||||
{
|
||||
// Arrange
|
||||
var sut = BuildSut(out _);
|
||||
|
||||
// Act
|
||||
var (x, y) = sut.ExtractTileCoordinatesFromFilename("/tiles/tile_1700000000_42_99.jpg");
|
||||
|
||||
// Assert
|
||||
x.Should().Be(42);
|
||||
y.Should().Be(99);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtractTileCoordinatesFromFilename_MalformedName_LogsWarningAndReturnsSentinel_AC1()
|
||||
{
|
||||
// Arrange
|
||||
var sut = BuildSut(out var loggerMock);
|
||||
const string malformed = "/tmp/not_a_tile_filename.jpg";
|
||||
|
||||
// Act
|
||||
var (x, y) = sut.ExtractTileCoordinatesFromFilename(malformed);
|
||||
|
||||
// Assert
|
||||
x.Should().Be(-1);
|
||||
y.Should().Be(-1);
|
||||
VerifyWarningLogged(loggerMock, "not_a_tile_filename");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtractTileCoordinatesFromFilename_TilePrefixWithNonNumericCoords_LogsWarningAndReturnsSentinel_AC1()
|
||||
{
|
||||
// Arrange
|
||||
var sut = BuildSut(out var loggerMock);
|
||||
const string nonNumeric = "/tiles/tile_1700000000_alpha_beta.jpg";
|
||||
|
||||
// Act
|
||||
var (x, y) = sut.ExtractTileCoordinatesFromFilename(nonNumeric);
|
||||
|
||||
// Assert
|
||||
x.Should().Be(-1);
|
||||
y.Should().Be(-1);
|
||||
VerifyWarningLogged(loggerMock, "tile_1700000000_alpha_beta");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtractTileCoordinatesFromFilename_NullPath_PropagatesArgumentNullException_AC2()
|
||||
{
|
||||
// Arrange
|
||||
var sut = BuildSut(out _);
|
||||
|
||||
// Act
|
||||
Action act = () => sut.ExtractTileCoordinatesFromFilename(null!);
|
||||
|
||||
// Assert
|
||||
act.Should().Throw<ArgumentNullException>();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user