dotnet-geo-management/Svrnty.GeoManagement.Tests/GoogleProviderTests.cs
Mathias Beaulieu-Duncan c6e6b29905
All checks were successful
Publish NuGet Packages / build-and-publish (push) Successful in 29s
refactor Country to CountryCode to better reflect the value it contain
2025-10-08 11:35:23 -04:00

191 lines
5.8 KiB
C#

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Svrnty.GeoManagement.Abstractions.Models;
using Svrnty.GeoManagement.Google;
using Svrnty.GeoManagement.Google.Configuration;
using Svrnty.GeoManagement.Tests.Configuration;
namespace Svrnty.GeoManagement.Tests;
public class GoogleProviderTests : IDisposable
{
private readonly GeoManagementGoogleProvider _provider;
private readonly IConfiguration _configuration;
private readonly ILogger<GeoManagementGoogleProvider> _logger;
private readonly TestDataConfiguration _testData;
public GoogleProviderTests()
{
// Build configuration from appsettings.Development.json
_configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.Development.json", optional: false, reloadOnChange: false)
.AddEnvironmentVariables()
.Build();
// Setup logger
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Debug);
});
_logger = loggerFactory.CreateLogger<GeoManagementGoogleProvider>();
// Get options from configuration
var options = _configuration.GetSection("GoogleGeoManagement").Get<GoogleGeoManagementOptions>();
if (options == null || string.IsNullOrWhiteSpace(options.ApiKey))
{
throw new InvalidOperationException(
"Google API key not configured. Please add your API key to appsettings.Development.json");
}
// Load test data from configuration
_testData = _configuration.GetSection("TestData").Get<TestDataConfiguration>()
?? throw new InvalidOperationException(
"Test data not configured. Please add TestData section to appsettings.Development.json");
_provider = new GeoManagementGoogleProvider(
Options.Create(options),
_logger);
}
[Fact]
public async Task GetGeoPointAsync_WithValidAddress_ReturnsCoordinates()
{
// Arrange
var address = new Address
{
Line1 = _testData.ValidAddress.Line1,
Line2 = _testData.ValidAddress.Line2,
City = _testData.ValidAddress.City,
Subdivision = _testData.ValidAddress.Subdivision,
PostalCode = _testData.ValidAddress.PostalCode,
CountryCode = _testData.ValidAddress.Country,
Location = null,
Note = null
};
// Act
var result = await _provider.GetGeoPointAsync(address);
// Assert
Assert.NotNull(result);
Assert.InRange(result.Latitude, _testData.ExpectedLatRange.Min, _testData.ExpectedLatRange.Max);
Assert.InRange(result.Longitude, _testData.ExpectedLongRange.Min, _testData.ExpectedLongRange.Max);
}
[Fact]
public async Task ReverseGeocodeAsync_WithValidCoordinates_ReturnsAddress()
{
// Arrange
var geoPoint = new GeoPoint(
_testData.ValidGeoPoint.Latitude,
_testData.ValidGeoPoint.Longitude);
// Act
var result = await _provider.ReverseGeocodeAsync(geoPoint);
// Assert
Assert.NotNull(result);
Assert.NotNull(result.Line1);
Assert.NotNull(result.City);
Assert.NotNull(result.CountryCode);
Assert.True(result.IsNormalized());
Assert.NotNull(result.Location);
}
[Fact]
public async Task NormalizeAddressAsync_WithAddressObject_ReturnsNormalizedAddress()
{
// Arrange
var address = new Address
{
Line1 = _testData.NormalizeTestAddress.Line1,
Line2 = _testData.NormalizeTestAddress.Line2,
City = _testData.NormalizeTestAddress.City,
Subdivision = _testData.NormalizeTestAddress.Subdivision,
PostalCode = _testData.NormalizeTestAddress.PostalCode,
CountryCode = _testData.NormalizeTestAddress.Country,
Location = null,
Note = null
};
// Act
var result = await _provider.NormalizeAddressAsync(address);
// Assert
Assert.NotNull(result);
Assert.True(result.IsNormalized());
Assert.NotNull(result.Location);
Assert.NotNull(result.Line1);
Assert.Contains("Amphitheatre", result.Line1, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public async Task NormalizeAddressAsync_WithAddressString_ReturnsNormalizedAddress()
{
// Arrange
var addressString = _testData.AddressString;
// Act
var result = await _provider.NormalizeAddressAsync(addressString);
// Assert
Assert.NotNull(result);
Assert.True(result.IsNormalized());
Assert.NotNull(result.Location);
Assert.NotNull(result.Line1);
Assert.Contains("Mountain View", result.City, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public async Task GetGeoPointAsync_WithInvalidAddress_ReturnsNull()
{
// Arrange
var address = new Address
{
Line1 = _testData.InvalidAddress.Line1,
Line2 = _testData.InvalidAddress.Line2,
City = _testData.InvalidAddress.City,
Subdivision = _testData.InvalidAddress.Subdivision,
PostalCode = _testData.InvalidAddress.PostalCode,
CountryCode = _testData.InvalidAddress.Country,
Location = null,
Note = null
};
// Act
var result = await _provider.GetGeoPointAsync(address);
// Assert - Google might still return something, so we just verify it doesn't crash
// In real scenarios, very invalid addresses should return null
Assert.True(result == null || result.Latitude != 0 || result.Longitude != 0);
}
[Fact]
public async Task ReverseGeocodeAsync_WithOceanCoordinates_ReturnsAddress()
{
// Arrange
var geoPoint = new GeoPoint(
_testData.OceanGeoPoint.Latitude,
_testData.OceanGeoPoint.Longitude);
// Act
var result = await _provider.ReverseGeocodeAsync(geoPoint);
// Assert - May return null or a very general location
// This test just verifies it doesn't crash
if (result != null)
{
Assert.True(result.IsNormalized());
}
}
public void Dispose()
{
// Cleanup if needed
GC.SuppressFinalize(this);
}
}