"""Tests for src.loader — config loading and data normalization.""" import sys from pathlib import Path from unittest.mock import patch import pandas as pd sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from src.loader import load_config, normalize_columns, _clean_numeric, get_available_weeks class TestLoadConfig: def test_loads_config(self): config_path = Path(__file__).resolve().parent.parent / "config.yaml" if config_path.exists(): config = load_config(config_path) assert "google_sheets" in config assert "metrics" in config assert isinstance(config["metrics"], list) class TestNormalizeColumns: def test_renames_by_index(self): df = pd.DataFrame({ "A": ["US"], "B": ["Google"], "C": ["Awareness"], "D": ["campaign1"], "E": ["2026-01-01"], }) config = {"columns": { "country_idx": 0, "platform_idx": 1, "campaign_type_idx": 2, "campaign_name_idx": 3, "date_idx": 4, }} result = normalize_columns(df, config) assert "country" in result.columns assert "platform" in result.columns assert "date" in result.columns assert result["country"].iloc[0] == "US" class TestCleanNumeric: def test_plain_number(self): s = pd.Series(["100", "200.5", "0"]) result = _clean_numeric(s) assert list(result) == [100.0, 200.5, 0.0] def test_dollar_sign(self): s = pd.Series(["$1,234.56", "$0.50"]) result = _clean_numeric(s) assert abs(result.iloc[0] - 1234.56) < 0.01 assert abs(result.iloc[1] - 0.50) < 0.01 def test_percentage(self): s = pd.Series(["2.50%", "10.00%"]) result = _clean_numeric(s) assert abs(result.iloc[0] - 0.025) < 0.001 assert abs(result.iloc[1] - 0.10) < 0.001 def test_nan_handling(self): s = pd.Series(["", "abc", "100"]) result = _clean_numeric(s) assert pd.isna(result.iloc[0]) assert pd.isna(result.iloc[1]) assert result.iloc[2] == 100.0 class TestGetAvailableWeeks: def test_returns_sorted_pairs(self): df = pd.DataFrame({ "year": [2026, 2026, 2025, 2026], "week": [2, 1, 52, 3], }) result = get_available_weeks(df) assert result == [(2025, 52), (2026, 1), (2026, 2), (2026, 3)]