"""Campaign Name 解析器单元测试。""" import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) import pandas as pd import pytest from src.campaign_parser import ( parse_campaign_name, enrich_dataframe, AUDIENCE_REMARKETING, AUDIENCE_ASC, AUDIENCE_COLD, ) class TestParseCampaignName: """parse_campaign_name 单函数测试。""" def test_standard_12_fields(self): name = "US_Conversion_Meta_All_Purchase_Bone-Conduction_Others_AO_ASC_Mix_20260123_coreNumber" r = parse_campaign_name(name) assert r["market"] == "US" assert r["funnel"] == "Conversion" assert r["parsed_platform"] == "Meta" assert r["channel"] == "All" assert r["ad_objective"] == "Purchase" assert r["product_line"] == "Bone-Conduction" assert r["product_model"] == "Others" assert r["project_type"] == "AO" assert r["audience_raw"] == "ASC" assert r["creative_type"] == "Mix" assert r["campaign_date"] == "20260123" assert r["note"] == "coreNumber" assert r["parse_ok"] is True def test_audience_rmkt(self): name = "US_Conversion_Meta_All_Purchase_Bone-Conduction_Others_AO_RMKT_Mix_20260123_note" r = parse_campaign_name(name) assert r["audience_type"] == AUDIENCE_REMARKETING assert r["objective_group"] == "Purchase_RMKT" def test_audience_asc(self): name = "US_Conversion_Meta_All_Purchase_Bone-Conduction_Others_AO_ASC_Mix_20260123_note" r = parse_campaign_name(name) assert r["audience_type"] == AUDIENCE_ASC assert r["objective_group"] == "Purchase_ASC" def test_audience_cold(self): name = "US_Conversion_Meta_All_Purchase_Bone-Conduction_Others_AO_INT_Mix_20260123_note" r = parse_campaign_name(name) assert r["audience_type"] == AUDIENCE_COLD assert r["objective_group"] == "Purchase_Cold" def test_broad_audience(self): name = "CA_Conversion_Google_All_Purchase_Bone-Conduction_X_AO_Broad_Video_20260101_test" r = parse_campaign_name(name) assert r["audience_type"] == AUDIENCE_COLD assert r["objective_group"] == "Purchase_Cold" def test_lal_audience(self): name = "US_Consideration_Meta_IG_Linkclick_Bone-Conduction_X_AO_LAL_Image_20260101_test" r = parse_campaign_name(name) assert r["audience_type"] == AUDIENCE_COLD assert r["objective_group"] == "Linkclick" def test_less_than_5_fields(self): name = "US_Conversion_Meta" r = parse_campaign_name(name) assert r["parse_ok"] is False assert r["market"] == "US" assert r["ad_objective"] is None def test_exactly_5_fields(self): name = "US_Conversion_Meta_All_Purchase" r = parse_campaign_name(name) assert r["parse_ok"] is True assert r["ad_objective"] == "Purchase" assert r["product_line"] is None def test_more_than_12_fields(self): name = "US_Conversion_Meta_All_Purchase_BC_O_AO_ASC_Mix_20260101_note1_extra1_extra2" r = parse_campaign_name(name) assert r["note"] == "note1_extra1_extra2" assert r["parse_ok"] is True def test_invalid_market(self): name = "UK_Conversion_Meta_All_Purchase_BC_O_AO_ASC_Mix_20260101_note" r = parse_campaign_name(name) assert r["parse_ok"] is False def test_non_purchase_objective_group(self): name = "US_Consideration_Meta_All_Linkclick_BC_O_AO_INT_Mix_20260101_note" r = parse_campaign_name(name) assert r["objective_group"] == "Linkclick" def test_unknown_objective(self): name = "US_Conversion_Meta_All_SomethingNew_BC_O_AO_INT_Mix_20260101_note" r = parse_campaign_name(name) assert r["objective_group"] == "Other" class TestEnrichDataframe: """enrich_dataframe 批量解析测试。""" def test_basic_enrichment(self): df = pd.DataFrame({ "campaign_name": [ "US_Conversion_Meta_All_Purchase_Bone-Conduction_Others_AO_ASC_Mix_20260123_core", "CA_Awareness_Google_All_Pageview_Bone-Conduction_X_AO_Broad_Video_20260101_test", ], "Cost": [100.0, 50.0], }) result = enrich_dataframe(df) assert "market" in result.columns assert "funnel" in result.columns assert "ad_objective" in result.columns assert "audience_type" in result.columns assert "objective_group" in result.columns assert result.iloc[0]["market"] == "US" assert result.iloc[1]["market"] == "CA" assert result.iloc[0]["objective_group"] == "Purchase_ASC" assert result.iloc[1]["objective_group"] == "Pageview" def test_missing_campaign_name_column(self): df = pd.DataFrame({"Cost": [100.0]}) result = enrich_dataframe(df) assert "market" not in result.columns def test_does_not_modify_original(self): df = pd.DataFrame({"campaign_name": ["US_Conversion_Meta_All_Purchase"], "Cost": [1.0]}) original_cols = list(df.columns) enrich_dataframe(df) assert list(df.columns) == original_cols def test_parse_ok_rate_logging(self, caplog): df = pd.DataFrame({ "campaign_name": [ "US_Conversion_Meta_All_Purchase", "INVALID", "US_Awareness_Meta_All_Pageview", ], "Cost": [1.0, 2.0, 3.0], }) import logging with caplog.at_level(logging.INFO, logger="ad-agent"): result = enrich_dataframe(df) assert result["parse_ok"].sum() == 2 if __name__ == "__main__": pytest.main([__file__, "-v"])