"""Shared wordpress test helper — install-wizard client + admin credentials. A fresh CI deploy of the recipe does NOT run `core_install` (no POST_DEPLOY_CMDS in the CI env), so the app serves the WP install wizard until something completes it. The custom tests complete it here (run-scoped class-B credentials; the whole app — DB volume + secrets — is destroyed at teardown) and then exercise the real APIs (wp-json + XML-RPC) as an installed site. `ensure_installed` is idempotent so any custom test can call it first regardless of alphabetical ordering. """ from __future__ import annotations import ssl import urllib.error import urllib.parse import urllib.request # Per-run *.ci.commoninternet.net domains use the operator wildcard cert via the Traefik file # provider; the real-cert chain check is done once in the generic install assertion. _CTX = ssl.create_default_context() _CTX.check_hostname = False _CTX.verify_mode = ssl.CERT_NONE ADMIN_USER = "ccci-admin" ADMIN_PW = "Ccci-Wp-Test-Pw-2026!x" # strong so the wizard needs no pw_weak confirmation ADMIN_EMAIL = "ccci-admin@ccci.example.com" BLOG_TITLE = "CCCI Test Site" def _open(url: str, data: bytes | None = None, timeout: int = 60) -> tuple[int, str]: req = urllib.request.Request(url, data=data) if data is not None: req.add_header("Content-Type", "application/x-www-form-urlencoded") try: with urllib.request.urlopen(req, timeout=timeout, context=_CTX) as resp: return resp.getcode(), resp.read().decode(errors="replace") except urllib.error.HTTPError as e: try: return e.code, e.read().decode(errors="replace") except Exception: # noqa: BLE001 return e.code, "" def fetch_text(url: str, timeout: int = 60) -> tuple[int, str]: """GET a URL and return (status, body-text) — for HTML-content assertions.""" return _open(url, timeout=timeout) def ensure_installed(domain: str) -> bool: """Complete the WP install wizard if it hasn't been completed yet. Returns True if THIS call ran the install, False if the site was already installed. Fails the calling test (assert) if the wizard is reachable but the install POST fails. """ base = f"https://{domain}" status, body = _open(f"{base}/wp-admin/install.php") assert status == 200, f"GET /wp-admin/install.php HTTP {status} (body[:200]={body[:200]!r})" if "already installed" in body.lower(): return False assert "wordpress" in body.lower(), ( f"/wp-admin/install.php does not look like the WP installer: {body[:300]!r}" ) assert "database connection" not in body.lower(), ( "WP installer reports a database connection problem — app→mariadb wiring is broken" ) form = urllib.parse.urlencode( { "weblog_title": BLOG_TITLE, "user_name": ADMIN_USER, "admin_password": ADMIN_PW, "admin_password2": ADMIN_PW, "admin_email": ADMIN_EMAIL, "blog_public": "1", "Submit": "Install WordPress", "language": "", } ).encode() status, body = _open(f"{base}/wp-admin/install.php?step=2", data=form, timeout=180) assert status == 200, f"install POST HTTP {status} (body[:300]={body[:300]!r})" lowered = body.lower() assert "success" in lowered or "wordpress has been installed" in lowered, ( f"install POST did not report success: {body[:400]!r}" ) return True