"""drone — SCM-configured functional test (phase drone). Proves that drone is wired to the per-run gitea dep, not just healthy. The negative control: a drone deployed WITHOUT DRONE_GITEA_CLIENT_ID + DRONE_GITEA_SERVER (i.e., without compose.gitea.yml) would NOT redirect /login to the gitea dep's OAuth authorize endpoint — it would error or redirect elsewhere. This test is therefore falsified by a misconfigured drone. Test: GET https:///login (following redirects) must land at the per-run gitea dep's /login/oauth/authorize URL, and the client_id query param must match the OAuth2 app the harness created in the gitea dep (recorded in deps["gitea"]["client_id"]). Per the Adversary's pre-probe (REVIEW-drone.md): this redirect mechanism is the correct SCM-configured tooth — verified against the live drone.ci.commoninternet.net instance. """ from __future__ import annotations import ssl import urllib.parse import urllib.request import pytest @pytest.mark.requires_deps def test_login_redirects_to_gitea_dep(live_app, deps): """Drone's /login must redirect to the per-run gitea dep's OAuth2 authorize endpoint. Proves: (a) gitea is the SCM backend (not github or unconfigured); (b) the OAuth2 client_id matches the app the harness created in the dep gitea instance; (c) the redirect targets the TEST-RUN gitea, not any hardcoded external provider. """ assert "gitea" in deps, ( f"gitea dep not in deps — dep provisioning should have populated this. " f"Got keys: {list(deps.keys())}" ) gitea = deps["gitea"] gitea_domain: str = gitea["domain"] expected_client_id: str = gitea["client_id"] ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE # Follow all redirects from /login — the final URL must be gitea's OAuth2 authorize page. req = urllib.request.Request(f"https://{live_app}/login", method="GET") with urllib.request.urlopen(req, timeout=30, context=ctx) as resp: final_url = resp.geturl() parsed = urllib.parse.urlparse(final_url) assert parsed.scheme == "https", f"Unexpected scheme in final URL: {final_url!r}" assert parsed.netloc == gitea_domain, ( f"Drone /login did not redirect to the gitea dep ({gitea_domain!r}); " f"final URL: {final_url!r} — check GITEA_DOMAIN + COMPOSE_FILE in drone's .env" ) assert parsed.path == "/login/oauth/authorize", ( f"Final URL path is {parsed.path!r}, expected /login/oauth/authorize — " f"drone may not have gitea SCM configured" ) params = urllib.parse.parse_qs(parsed.query) actual_client_id = params.get("client_id", [None])[0] assert actual_client_id == expected_client_id, ( f"OAuth2 client_id mismatch: drone is using {actual_client_id!r} but the harness " f"created app {expected_client_id!r} in the dep gitea — check install_steps.sh" )