#!/usr/bin/env python3 """Fix test route param names to match handler parseUintParam expectations.""" import os, re, glob HANDLER_DIR = "internal/handler/api/v1" TEST_DIR = "internal/handler/api/v1" def extract_handler_params(handler_file): """Extract all parseUintParam(c, "xxx") param names from a handler.""" params = set() with open(handler_file) as f: for line in f: m = re.findall(r'parseUintParam\(c,\s*"([^"]+)"', line) params.update(m) return params def find_handler_for_test(test_file): """Map test file to its handler file.""" # e.g. agent_bot_handler_test.go -> agent_bot_handler.go base = test_file.replace("_test.go", ".go") base = base.replace("_crud_test.go", "_crud_handler.go") base = base.replace("_suite_test.go", "_suite_handler.go") handler_path = os.path.join(HANDLER_DIR, base) if os.path.exists(handler_path): return handler_path # Try removing suffixes for suffix in ["_handler_crud", "_handler_suite", "_handler_test"]: candidate = base.replace(suffix + ".go", "_handler.go") candidate = os.path.join(HANDLER_DIR, candidate) if os.path.exists(candidate): return candidate return None # Build handler param map handler_params = {} for f in sorted(glob.glob(os.path.join(HANDLER_DIR, "*_handler.go"))): params = extract_handler_params(f) if params: handler_params[os.path.basename(f)] = params # Special known mappings for non-_handler.go test files SPECIAL_MAPS = { "csat_survey_handler_test.go": {"id": "csat_survey_id"}, "csat_survey_update_test.go": {"id": "csat_survey_id"}, "draft_message_handler_test.go": {"id": "draft_id"}, "notification_handler_test.go": {"id": "notification_id"}, "message_handler_test.go": {"id": "message_id"}, "conversation_handler_crud_test.go": {"id": "conversation_id"}, "conversation_handler_test.go": {"id": "conversation_id"}, "conversation_participant_handler_test.go": {"id": "user_id"}, "automation_rule_handler_test.go": {"id": "automation_id"}, "agent_bot_handler_test.go": {"id": "agent_bot_id"}, "contact_handler_crud_test.go": {"id": "contact_id"}, "account_handler_test.go": {"id": "account_id"}, "account_saml_settings_handler_test.go": {"id": "saml_setting_id"}, "inbox_handler_test.go": {"id": "inbox_id"}, "integration_hook_handler_test.go": {"id": "hook_id"}, "integration_hook_handler_suite_test.go": {"id": "hook_id"}, "label_handler_test.go": {"id": "label_id"}, "team_handler_test.go": {"id": "team_id"}, "sla_policy_handler_test.go": {"id": "sla_policy_id"}, "custom_filter_handler_test.go": {"id": "custom_filter_id"}, "canned_response_handler_test.go": {"id": "canned_response_id"}, "banner_handler_test.go": {"id": "banner_id"}, "audit_handler_test.go": {"id": "audit_id"}, "captain_custom_tool_crud_handler_test.go": {"id": "custom_tool_id"}, "captain_custom_tool_test_handler_test.go": {"id": "custom_tool_id"}, "category_handler_test.go": {"id": "category_id"}, "company_handler_test.go": {"id": "company_id"}, "mfa_handler_test.go": {"id": "mfa_id"}, "search_handler_test.go": {"id": "search_id"}, "auto_reply_rule_handler_test.go": {"id": "auto_reply_rule_id"}, "bot_rule_handler_test.go": {"id": "bot_rule_id"}, "copilot_suggestion_handler_test.go": {"id": "copilot_suggestion_id"}, "rag_handler_test.go": {"id": "rag_source_id"}, "platform_e2e_test.go": {"id": "agent_bot_id"}, "platform_agent_bot_handler_test.go": {"id": "agent_bot_id"}, "push_subscription_handler_test.go": {"id": "push_subscription_id"}, "webhook_subscription_handler_test.go": {"id": "webhook_subscription_id"}, "installation_config_handler_test.go": {"id": "installation_config_id"}, "custom_attribute_definition_handler_test.go": {"id": "custom_attribute_definition_id"}, "agent_bot_inbox_handler_test.go": {"id": "agent_bot_inbox_id"}, "assignment_policy_v2_handler_test.go": {"id": "assignment_policy_id"}, "conversation_insight_handler_test.go": {"id": "conversation_id"}, "webwidget_offline_handler_test.go": {"id": "inbox_id"}, "tiktok_channel_handler_test.go": {"id": "inbox_id"}, "assignable_agent_handler_test.go": {"id": "inbox_id"}, } # Also extract from handler files to verify/expand the map for hf, params in handler_params.items(): test_name = hf.replace("_handler.go", "_handler_test.go") non_id_params = [p for p in params if p != "id" and p != "account_id" and p != "conversation_id"] # Find the resource-specific param (e.g. "agent_bot_id", "automation_id") resource_params = [p for p in params if p.endswith("_id") and p not in ("account_id", "conversation_id", "user_id", "contact_id")] if resource_params and test_name not in SPECIAL_MAPS: for rp in resource_params: if "id" in SPECIAL_MAPS.get(test_name, {}): continue SPECIAL_MAPS[test_name] = {"id": rp} changes = 0 for test_file in sorted(glob.glob(os.path.join(TEST_DIR, "*_test.go"))): basename = os.path.basename(test_file) if basename not in SPECIAL_MAPS: continue id_map = SPECIAL_MAPS[basename] with open(test_file) as f: content = f.read() new_content = content # Replace :id" route params with correct names for old, new in id_map.items(): # Pattern: "/:id" -> "/:new_name" new_content = new_content.replace(f'"/:{old}"', f'"/:{new}"') # Also handle patterns like "/:id/clone" etc new_content = re.sub(rf'"/:{old}/', f'"/:{new}/', new_content) if new_content != content: with open(test_file, 'w') as f: f.write(new_content) changes += 1 print(f" Fixed: {basename} ({id_map})") print(f"\nTotal files fixed: {changes}")