using FluentValidation.TestHelper; using SatelliteProvider.Api.Validators; using SatelliteProvider.Common.DTO; namespace SatelliteProvider.Tests.Validators; // AZ-809: unit tests for GeofencePolygonValidator. Covers (a) presence of // both corners, (b) range checks per corner, and (c) the cross-field // invariant `NW north-of SE` AND `NW west-of SE`. public class GeofencePolygonValidatorTests { private readonly GeofencePolygonValidator _validator; public GeofencePolygonValidatorTests() { GlobalValidatorConfig.ApplyOnce(); _validator = new GeofencePolygonValidator(); } private static GeofencePolygon ValidPolygon() => new() { NorthWest = new GeoPoint(50.15, 36.05), SouthEast = new GeoPoint(50.05, 36.15), }; [Fact] public void Validate_AllValid_Passes() { // Arrange var polygon = ValidPolygon(); // Act var result = _validator.TestValidate(polygon); // Assert result.ShouldNotHaveAnyValidationErrors(); } [Fact] public void Validate_NorthWestNull_FailsNotNullRule() { // Arrange var polygon = ValidPolygon(); polygon.NorthWest = null; // Act var result = _validator.TestValidate(polygon); // Assert result.ShouldHaveValidationErrorFor("northWest") .WithErrorMessage("`northWest` corner is required."); } [Fact] public void Validate_SouthEastNull_FailsNotNullRule() { // Arrange var polygon = ValidPolygon(); polygon.SouthEast = null; // Act var result = _validator.TestValidate(polygon); // Assert result.ShouldHaveValidationErrorFor("southEast") .WithErrorMessage("`southEast` corner is required."); } [Theory] [InlineData(-90.001)] [InlineData(90.001)] public void Validate_NorthWestLatOutOfRange_FailsRangeRule(double lat) { // Arrange var polygon = ValidPolygon(); polygon.NorthWest = new GeoPoint(lat, 36.05); // Act var result = _validator.TestValidate(polygon); // Assert result.ShouldHaveValidationErrorFor("northWest.lat"); } [Theory] [InlineData(-180.001)] [InlineData(180.001)] public void Validate_SouthEastLonOutOfRange_FailsRangeRule(double lon) { // Arrange var polygon = ValidPolygon(); polygon.SouthEast = new GeoPoint(50.05, lon); // Act var result = _validator.TestValidate(polygon); // Assert result.ShouldHaveValidationErrorFor("southEast.lon"); } [Fact] public void Validate_NorthWestLatNotGreaterThanSouthEast_FailsInvariant() { // Arrange — NW.Lat <= SE.Lat → invariant violation var polygon = ValidPolygon(); polygon.NorthWest = new GeoPoint(50.05, 36.05); polygon.SouthEast = new GeoPoint(50.05, 36.15); // Act var result = _validator.TestValidate(polygon); // Assert result.ShouldHaveValidationErrorFor("northWest") .WithErrorMessage("`northWest.lat` must be greater than `southEast.lat` (NW is north-of SE)."); } [Fact] public void Validate_NorthWestLonNotLessThanSouthEast_FailsInvariant() { // Arrange — NW.Lon >= SE.Lon → invariant violation var polygon = ValidPolygon(); polygon.NorthWest = new GeoPoint(50.15, 36.15); polygon.SouthEast = new GeoPoint(50.05, 36.15); // Act var result = _validator.TestValidate(polygon); // Assert result.ShouldHaveValidationErrorFor("northWest") .WithErrorMessage("`northWest.lon` must be less than `southEast.lon` (NW is west-of SE)."); } }