"""Unit tests for ts_shared_rev data cleaning helpers.""" import sys import os import pytest # Add parent directory to path so we can import ts_shared_rev sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) # Set required env vars before import os.environ.setdefault("TRACKSOLID_APP_KEY", "test_key") os.environ.setdefault("TRACKSOLID_APP_SECRET", "test_secret") os.environ.setdefault("TRACKSOLID_USER_ID", "test_user") os.environ.setdefault("TRACKSOLID_PWD_MD5", "test_md5") os.environ.setdefault("DATABASE_URL", "postgresql://test:test@localhost:5432/test") from ts_shared_rev import clean, clean_num, clean_int, clean_ts, is_valid_fix class TestClean: def test_none_returns_none(self): assert clean(None) is None def test_empty_string_returns_none(self): assert clean("") is None def test_whitespace_only_returns_none(self): assert clean(" ") is None def test_normal_string_preserved(self): assert clean("hello") == "hello" def test_strips_whitespace(self): assert clean(" hello ") == "hello" def test_non_string_converted(self): assert clean(123) == "123" def test_zero_preserved(self): assert clean(0) == "0" class TestCleanNum: def test_valid_float_string(self): assert clean_num("3.14") == pytest.approx(3.14) def test_valid_integer_string(self): assert clean_num("42") == pytest.approx(42.0) def test_non_numeric_returns_none(self): assert clean_num("abc") is None def test_none_returns_none(self): assert clean_num(None) is None def test_empty_string_returns_none(self): assert clean_num("") is None def test_numeric_value_passthrough(self): assert clean_num(45.5) == pytest.approx(45.5) def test_negative_value(self): assert clean_num("-1.5") == pytest.approx(-1.5) class TestCleanInt: def test_integer_string(self): assert clean_int("42") == 42 def test_float_string_truncates(self): assert clean_int("3.9") == 3 def test_non_numeric_returns_none(self): assert clean_int("abc") is None def test_none_returns_none(self): assert clean_int(None) is None class TestCleanTs: def test_valid_iso_timestamp(self): result = clean_ts("2024-04-12 08:00:00") assert result == "2024-04-12 08:00:00" def test_valid_iso_with_timezone(self): result = clean_ts("2024-04-12T08:00:00Z") assert result is not None def test_garbage_returns_none(self): assert clean_ts("not-a-date") is None def test_none_returns_none(self): assert clean_ts(None) is None def test_empty_string_returns_none(self): assert clean_ts("") is None def test_bcd_format_returns_none(self): # BCD format YYMMDDHHmmss is NOT handled by clean_ts (only by _parse_trip_ts) assert clean_ts("220415103000") is None class TestIsValidFix: def test_zero_island_filtered(self): assert is_valid_fix(0.0, 0.0) is False def test_valid_nairobi_coords(self): assert is_valid_fix(-1.2921, 36.8219) is True def test_none_lat_returns_false(self): assert is_valid_fix(None, 36.8219) is False def test_none_lng_returns_false(self): assert is_valid_fix(-1.2921, None) is False def test_out_of_range_lat(self): assert is_valid_fix(91.0, 36.8219) is False def test_out_of_range_lng(self): assert is_valid_fix(-1.2921, 181.0) is False def test_valid_extreme_coords(self): assert is_valid_fix(90.0, 180.0) is True def test_string_coords_accepted(self): assert is_valid_fix("-1.2921", "36.8219") is True