from core.domain.normalization import generate_cdr_id, normalize_cdr, normalize_rat from core.domain.validation import parse_raw_cdr def test_normalize_valid_cdr() -> None: payload = { "raw_id": "raw-us-east-9988221", "src_ip": "10.240.12.1", "device_id": "310410998877665", "caller_num": "0019875551234", "svc": "4G_DATA", "up_bytes": 1048576, "down_bytes": 4194304, "rat": 6, "lac": "4021", "ci": "8812", "epoch_start": 1726070000, "epoch_end": 1726070300, } raw = parse_raw_cdr(payload) normalized = normalize_cdr(raw) assert normalized.raw_id == "raw-us-east-9988221" assert normalized.imsi == "310410998877665" assert normalized.msisdn == "+19875551234" assert normalized.service_type == "4G_DATA" assert normalized.radio_access_type == "LTE_4G" assert normalized.cell_id == "4021_8812" assert normalized.bytes_uploaded == 1048576 assert normalized.bytes_downloaded == 4194304 assert normalized.total_bytes == 5242880 assert normalized.duration_seconds == 300 assert str(normalized.source_ip) == "10.240.12.1" def test_cdr_id_is_deterministic() -> None: first = generate_cdr_id("raw-123") second = generate_cdr_id("raw-123") assert first == second def test_different_raw_ids_generate_different_cdr_ids() -> None: first = generate_cdr_id("raw-123") second = generate_cdr_id("raw-456") assert first != second def test_rat_mapping() -> None: assert normalize_rat(1) == "3G" assert normalize_rat(6) == "LTE_4G" assert normalize_rat(9) == "5G_NR" def test_missing_source_ip_defaults_to_zero_address() -> None: payload = { "raw_id": "raw-001", "device_id": "310410998877665", "caller_num": "0019875551234", "svc": "4G_DATA", "up_bytes": 100, "down_bytes": 200, "rat": 6, "lac": "4021", "ci": "8812", "epoch_start": 1726070000, "epoch_end": 1726070300, } raw = parse_raw_cdr(payload) normalized = normalize_cdr(raw) assert str(normalized.source_ip) == "0.0.0.0"