from types import SimpleNamespace import pytest from app.core.config import settings from app.services import monitoring_server_location from app.services.ip_geolocation_fallback import ExternalIpLocation def test_public_ip_normalization_rejects_private_addresses(): assert monitoring_server_location._normalize_public_ip("8.8.8.8\n") == "8.8.8.8" assert monitoring_server_location._normalize_public_ip("10.0.0.8") is None assert monitoring_server_location._normalize_public_ip("127.0.0.1") is None assert monitoring_server_location._normalize_public_ip("not-an-ip") is None @pytest.mark.asyncio async def test_server_location_is_derived_from_configured_public_ip(monkeypatch): monkeypatch.setattr(settings, "MONITORING_SERVER_PUBLIC_IP", "8.8.8.8") monkeypatch.setattr( monitoring_server_location, "resolve_ip_location", lambda ip: SimpleNamespace( location="United States / California / San Jose", country="United States", province="California", city="San Jose", isp="Google", ), ) monitoring_server_location.reset_monitoring_server_location_cache() location = await monitoring_server_location.resolve_monitoring_server_location() assert location is not None assert location.name == "United States / California / San Jose" assert location.longitude == -121.8863 assert location.latitude == 37.3382 assert location.resolution_source == "configured_public_ip" monitoring_server_location.reset_monitoring_server_location_cache() @pytest.mark.asyncio async def test_server_location_returns_none_instead_of_a_hardcoded_fallback(monkeypatch): async def no_public_ip(): return None, "unavailable" monkeypatch.setattr(monitoring_server_location, "_discover_public_ip", no_public_ip) monitoring_server_location.reset_monitoring_server_location_cache() location = await monitoring_server_location.resolve_monitoring_server_location() assert location is None monitoring_server_location.reset_monitoring_server_location_cache() @pytest.mark.asyncio async def test_server_location_uses_external_coordinates_when_local_coordinates_are_missing(monkeypatch): monkeypatch.setattr(settings, "MONITORING_SERVER_PUBLIC_IP", "5.34.216.210") monkeypatch.setattr( monitoring_server_location, "resolve_ip_location", lambda _ip: SimpleNamespace( location="公网", country="", province="", city="", isp="", ), ) async def fake_external_lookup(ip_addresses): assert ip_addresses == ["5.34.216.210"] return { "5.34.216.210": ExternalIpLocation( ip_address="5.34.216.210", country="United States of America", country_code="US", region="California", city="Los Angeles", isp="Example ISP", longitude=-118.2439, latitude=34.05257, ) } monkeypatch.setattr(monitoring_server_location, "resolve_external_ip_locations", fake_external_lookup) monitoring_server_location.reset_monitoring_server_location_cache() location = await monitoring_server_location.resolve_monitoring_server_location() assert location is not None assert location.name == "United States of America / California / Los Angeles" assert location.longitude == -118.2439 assert location.latitude == 34.05257 monitoring_server_location.reset_monitoring_server_location_cache()