Files
ctms/backend/tests/test_source_location_aggregator.py
Cheng Zhou f11a5c84d9
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
feat(监控): 完善系统监控、登录状态与访问审计能力
2026-07-10 17:12:13 +08:00

69 lines
2.2 KiB
Python

from datetime import datetime, timedelta, timezone
import pytest
from app.models.source_location_snapshot import SourceLocationSnapshot
from app.services.source_location_aggregator import _identity_hash, get_source_location_timeline
def _snapshot(bucket_time: datetime, *, allowed: int, denied: int) -> SourceLocationSnapshot:
return SourceLocationSnapshot(
bucket_time=bucket_time,
ip_hash=_identity_hash("ip", "203.0.113.10"),
user_hash=_identity_hash("user", "user-1"),
country="United States",
country_code="US",
province="California",
region_code="",
city="San Jose",
isp="Example ISP",
location="United States / California / San Jose",
longitude=-121.8863,
latitude=37.3382,
accuracy_level="city",
allowed_count=allowed,
denied_count=denied,
security_event_count=denied,
high_risk_count=0,
auth_failure_count=denied,
first_seen_at=bucket_time,
last_seen_at=bucket_time + timedelta(minutes=30),
)
def test_source_location_identity_hash_is_stable_and_does_not_expose_ip():
first = _identity_hash("ip", "203.0.113.10")
second = _identity_hash("ip", "203.0.113.10")
assert first == second
assert len(first) == 64
assert "203.0.113.10" not in first
@pytest.mark.asyncio
async def test_source_location_timeline_supports_hour_and_day_rollups(db_session):
start = datetime(2026, 7, 10, 8, tzinfo=timezone.utc)
db_session.add(_snapshot(start, allowed=4, denied=1))
db_session.add(_snapshot(start + timedelta(hours=1), allowed=3, denied=2))
await db_session.commit()
hourly = await get_source_location_timeline(
db_session,
start_at=start,
end_at=start + timedelta(hours=2),
granularity="hour",
)
daily = await get_source_location_timeline(
db_session,
start_at=start,
end_at=start + timedelta(hours=2),
granularity="day",
)
assert [item["total_count"] for item in hourly] == [5, 5]
assert len(daily) == 1
assert daily[0]["total_count"] == 10
assert daily[0]["denied_count"] == 3
assert daily[0]["unique_ip_count"] == 1
assert daily[0]["unique_user_count"] == 1