dotnet-geo-management/Svrnty.GeoManagement.Tests/GoogleProviderTests.cs

174 lines
4.9 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;
namespace Svrnty.GeoManagement.Tests;
public class GoogleProviderTests : IDisposable
{
private readonly GeoManagementGoogleProvider _provider;
private readonly IConfiguration _configuration;
private readonly ILogger<GeoManagementGoogleProvider> _logger;
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");
}
_provider = new GeoManagementGoogleProvider(
Options.Create(options),
_logger);
}
[Fact]
public async Task GetGeoPointAsync_WithValidAddress_ReturnsCoordinates()
{
// Arrange
var address = new Address(
Line1: "1600 Amphitheatre Parkway",
Line2: null,
City: "Mountain View",
Subdivision: "CA",
PostalCode: "94043",
Country: "US",
Location: null,
Note: null);
// Act
var result = await _provider.GetGeoPointAsync(address);
// Assert
Assert.NotNull(result);
Assert.InRange(result.Latitude, 37.0, 38.0); // Approximate range for Mountain View, CA
Assert.InRange(result.Longitude, -123.0, -122.0);
}
[Fact]
public async Task ReverseGeocodeAsync_WithValidCoordinates_ReturnsAddress()
{
// Arrange - Google HQ coordinates
var geoPoint = new GeoPoint(37.4224764, -122.0842499);
// Act
var result = await _provider.ReverseGeocodeAsync(geoPoint);
// Assert
Assert.NotNull(result);
Assert.NotNull(result.Line1);
Assert.NotNull(result.City);
Assert.NotNull(result.Country);
Assert.True(result.IsNormalized);
Assert.NotNull(result.Location);
}
[Fact]
public async Task NormalizeAddressAsync_WithAddressObject_ReturnsNormalizedAddress()
{
// Arrange
var address = new Address(
Line1: "1600 Amphitheatre Pkwy", // Abbreviated
Line2: null,
City: "Mountain View",
Subdivision: "California",
PostalCode: "94043",
Country: "USA",
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 = "1600 Amphitheatre Parkway, Mountain View, CA";
// 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: "This is not a real address at all",
Line2: null,
City: "Fake City",
Subdivision: "XX",
PostalCode: "00000",
Country: "Nowhere",
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 - Coordinates in the middle of the Pacific Ocean
var geoPoint = new GeoPoint(0, -160);
// 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);
}
}