fix(envs): offer the two Meta keys the setup panel tells you to set

Running the new diagnostics against the live account returned "No ad
account is configured. Set META_ADS_ACCOUNT_ID in Settings >
Environments." That instruction was wrong: the Settings page renders
_KEY_REGISTRY, and neither META_ADS_ACCOUNT_ID nor META_PAGE_ID was in it,
so there was no field to type either one into. Arbitrary keys can be
stored, but only listed ones are shown, which left the operator holding an
instruction they could not follow anywhere but a terminal — the exact
thing the panel exists to avoid.

The test reads the remedy strings out of diagnostics.py and asserts every
env var they name is in the registry, so a future check that mentions a
new key cannot ship pointing at a page that does not offer it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
AFFAANh
2026-08-07 12:54:18 +05:30
co-authored by Claude Opus 5
parent c0b458d283
commit 2479b94edf
2 changed files with 37 additions and 0 deletions
+5
View File
@@ -226,6 +226,11 @@ _KEY_REGISTRY: List[Dict[str, str]] = [
# Advertising
{"key": "GOOGLE_ADS_DEVELOPER_TOKEN", "plugin": "Google Ads", "description": "Google Ads API developer token"},
{"key": "META_ADS_ACCESS_TOKEN", "plugin": "Meta Ads", "description": "Facebook & Instagram ads access token"},
# Both of these block a campaign launch, and the Campaigns setup panel
# tells the operator to set them here — so they have to be listed here,
# or that instruction points at a page where the field is not offered.
{"key": "META_ADS_ACCOUNT_ID", "plugin": "Meta Ads", "description": "Ad account campaigns are created in, like act_1234567890"},
{"key": "META_PAGE_ID", "plugin": "Meta Ads", "description": "Facebook Page ads are published from; sync refuses without it"},
{"key": "META_APP_ID", "plugin": "Meta Ads", "description": "Meta app ID, enables automatic token refresh"},
{"key": "META_APP_SECRET", "plugin": "Meta Ads", "description": "Meta app secret, enables automatic token refresh"},
{"key": "MASKANX_OPERATOR_TOKENS", "plugin": "Campaigns", "description": "Comma-separated name:token pairs authorised to approve and launch campaigns"},
+32
View File
@@ -330,3 +330,35 @@ def test_smoke_test_refuses_when_no_ad_account_is_configured(
assert response.status_code == 422
assert "META_ADS_ACCOUNT_ID" in response.json()["detail"]
# --- the remedies have to point somewhere real ---
def test_every_env_var_a_remedy_names_is_offered_in_settings():
"""A remedy saying "set X in Settings > Environments" is a lie if X is
not in the key registry the Settings page renders.
Arbitrary keys can be stored, but only registry entries are shown, so
an unlisted key leaves the operator with an instruction and no field.
"""
import re
from adclaw.app.routers.envs import _KEY_REGISTRY
from adclaw.campaigns import diagnostics
listed = {entry["key"] for entry in _KEY_REGISTRY}
source = (diagnostics.__file__ or "")
with open(source, encoding="utf-8") as handle:
text = handle.read()
# Env var names as they appear in the remedy strings.
named = set(re.findall(r"\b(META_[A-Z_]+|MASKANX_[A-Z_]+)\b", text))
named.discard("META_ADS_ACCOUNT_ID_ENV")
missing = sorted(named - listed)
assert not missing, (
f"Diagnostics tells the operator to set {missing} in Settings > "
f"Environments, but they are not in _KEY_REGISTRY so no field is "
f"shown for them."
)