| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- import sys
- import unittest
- from pathlib import Path
- from unittest.mock import patch
- ROOT = Path(__file__).resolve().parent
- if str(ROOT) not in sys.path:
- sys.path.insert(0, str(ROOT))
- PROJECT_ROOT = ROOT.parents[1]
- if str(PROJECT_ROOT) not in sys.path:
- sys.path.insert(0, str(PROJECT_ROOT))
- from tools.ad_creation import AdCandidate, build_ad_request_body
- from tools.delivery_config import (
- BID_MODE_AVERAGE_COST,
- BID_MODE_MAX_CONVERSION,
- parse_bid_scene,
- parse_placement_config,
- )
- def _candidate() -> AdCandidate:
- return AdCandidate(
- account_id=123,
- adgroup_name="test-ad",
- site_set=["SITE_SET_WECHAT"],
- custom_audience=None,
- bid_amount_fen=35,
- audience_tier_label="泛人群",
- age=[{"min": 45, "max": 66}],
- location_types=["LIVE_IN"],
- region_ids=[1],
- daily_budget_fen=10000,
- time_series="1" * 48,
- delivery_version="miniapp_user_growth_v1",
- fingerprint="fp",
- wechat_position=None,
- )
- class AdCreationStatusTest(unittest.TestCase):
- def test_ad_request_defaults_to_normal_status(self):
- with patch("tools.ad_creation.get_account_feedback_id", return_value=6700001):
- body = build_ad_request_body(_candidate(), begin_date="2026-07-01")
- self.assertEqual(body["configured_status"], "AD_STATUS_NORMAL")
- def test_max_conversion_uses_systematic_bid_with_custom_cost_cap(self):
- candidate = _candidate()
- candidate.bid_scene = BID_MODE_MAX_CONVERSION
- candidate.custom_cost_cap_fen = 48
- with patch("tools.ad_creation.get_account_feedback_id", return_value=6700001):
- body = build_ad_request_body(candidate, begin_date="2026-07-01")
- self.assertEqual("SMART_BID_TYPE_SYSTEMATIC", body["smart_bid_type"])
- self.assertEqual(0, body["bid_amount"])
- self.assertEqual("COST_CONSTRAINT_SCENE_OPEN", body["cost_constraint_scene"])
- self.assertEqual(48, body["custom_cost_cap"])
- self.assertNotIn("bid_scene", body)
- def test_aim_placement_uses_automatic_site_without_site_set(self):
- candidate = _candidate()
- candidate.automatic_site_enabled = True
- candidate.site_set = []
- with patch("tools.ad_creation.get_account_feedback_id", return_value=6700001):
- body = build_ad_request_body(candidate, begin_date="2026-07-01")
- self.assertTrue(body["automatic_site_enabled"])
- self.assertNotIn("site_set", body)
- def test_parse_feishu_bid_scene_and_placement(self):
- self.assertEqual(BID_MODE_AVERAGE_COST, parse_bid_scene(""))
- self.assertEqual(BID_MODE_MAX_CONVERSION, parse_bid_scene("最大转化量"))
- placement = parse_placement_config(
- "微信朋友圈,微信公众号与小程序,腾讯平台与内容媒体,腾讯营销联盟"
- )
- self.assertFalse(placement.automatic_site_enabled)
- self.assertEqual(
- [
- "SITE_SET_MOMENTS",
- "SITE_SET_WECHAT",
- "SITE_SET_WECHAT_PLUGIN",
- "SITE_SET_TENCENT_NEWS",
- "SITE_SET_TENCENT_VIDEO",
- "SITE_SET_KANDIAN",
- "SITE_SET_QQ_MUSIC_GAME",
- "SITE_SET_MOBILE_UNION",
- ],
- placement.site_set,
- )
- aim = parse_placement_config("AIM+")
- self.assertTrue(aim.automatic_site_enabled)
- self.assertEqual([], aim.site_set)
- if __name__ == "__main__":
- unittest.main()
|