Rewrite onboarding prose to a neutral voice
This commit is contained in:
@@ -13,7 +13,7 @@ bash tests/test_doctor.sh
|
||||
|
||||
## Inventory
|
||||
|
||||
- **`test_forge_auth.py`** — `scripts/forge_auth.py` unit tests: PKCE
|
||||
- **`test_forge_auth.py`**: `scripts/forge_auth.py` unit tests: PKCE
|
||||
pair generation, HMAC state signing + CSRF rejection,
|
||||
`ForgeAuthConfig.from_env` validation (loopback-only redirect,
|
||||
missing port, missing env vars, `FORGE_GITEA_USERNAME`
|
||||
@@ -22,19 +22,19 @@ bash tests/test_doctor.sh
|
||||
read/write/merge/`has_live_gitea_token`, `auth_store_path`
|
||||
precedence, `run_logout`, `main()` dispatcher.
|
||||
|
||||
- **`test_git_credential_forge.py`** — `scripts/git-credential-forge.py`
|
||||
- **`test_git_credential_forge.py`**: `scripts/git-credential-forge.py`
|
||||
unit tests: credential protocol I/O, host/scheme/port matching,
|
||||
live-token fast-path, pass-through for missing store or non-matching
|
||||
host, expired-token refresh, refresh-failure handling, `store`/`erase`
|
||||
no-ops, `main()` dispatcher.
|
||||
|
||||
- **`test_forge_auth_integration.py`** — end-to-end Python integration
|
||||
- **`test_forge_auth_integration.py`**: end-to-end Python integration
|
||||
tests against `tests/mock_oidc_server.py`: full PKCE flow,
|
||||
gateway-required schema on disk, idempotent re-login, refresh token
|
||||
rotation with server-side revocation, logout preserving
|
||||
gateway-bearer fields.
|
||||
|
||||
- **`test_forge_auth_integration.sh`** — shell end-to-end: drives
|
||||
- **`test_forge_auth_integration.sh`**: shell end-to-end: drives
|
||||
`forge_auth.py login` against the mock server, installs the
|
||||
credential helper into a sandboxed `$HOME`, and exercises
|
||||
`git credential fill`. Covers URL matching, `github.com`
|
||||
@@ -43,17 +43,17 @@ bash tests/test_doctor.sh
|
||||
logout URL surfaced, authorise URL carries `prompt=login` +
|
||||
`login_hint`).
|
||||
|
||||
- **`test_setup_args.sh`** — `scripts/setup.sh` coverage: argument
|
||||
- **`test_setup_args.sh`**: `scripts/setup.sh` coverage: argument
|
||||
parsing, `--help`, `--headless` wiring to `forge_login.sh
|
||||
--no-browser`, the `--headless + FORGE_SETUP_YES=1` hang guard,
|
||||
live-token reuse, silent-refresh rescue, `prompt_choice` non-tty
|
||||
stdout isolation.
|
||||
|
||||
- **`test_doctor.sh`** — `scripts/doctor.sh`: miss-path under a
|
||||
- **`test_doctor.sh`**: `scripts/doctor.sh`: miss-path under a
|
||||
sandboxed PATH, asserts every `[MISS]` line is followed by a `fix:`
|
||||
line.
|
||||
|
||||
- **`mock_oidc_server.py`** — test fixture implementing
|
||||
- **`mock_oidc_server.py`**: test fixture implementing
|
||||
`/.well-known/openid-configuration`, `/login/oauth/authorize`,
|
||||
`/login/oauth/access_token`, `/login/oauth/userinfo`. PKCE
|
||||
verification on `authorization_code`; rotation + revocation on
|
||||
|
||||
@@ -15,8 +15,8 @@ out="$(mktemp)"
|
||||
trap 'rm -f "$out"' EXIT
|
||||
|
||||
# Strip everything that could satisfy the checks we want to fail.
|
||||
# /usr/bin/python3 is 3.10.x on Ubuntu 22.04; that's fine: we want to
|
||||
# prove the python>=3.11 miss branch renders its fix+alt lines.
|
||||
# /usr/bin/python3 is 3.10.x on Ubuntu 22.04; this case exercises the
|
||||
# python>=3.11 miss branch and its fix+alt lines.
|
||||
if env -i HOME="$HOME" PATH="/usr/bin:/bin" bash "$repo/scripts/doctor.sh" >"$out" 2>&1; then
|
||||
echo "FAIL: doctor.sh exited 0 despite missing prerequisites"
|
||||
cat "$out"
|
||||
|
||||
@@ -335,7 +335,7 @@ class AuthFileTests(unittest.TestCase):
|
||||
|
||||
def test_merge_login_preserves_gateway_bearer(self) -> None:
|
||||
# Simulates the case where the orchestrator already ran
|
||||
# `auth login` and populated the gateway bearer. We must not
|
||||
# `auth login` and populated the gateway bearer. The code must not
|
||||
# overwrite those fields.
|
||||
f = fa.AuthFile(raw={
|
||||
"username": "old-alice",
|
||||
@@ -396,8 +396,8 @@ class AuthFileTests(unittest.TestCase):
|
||||
self.assertEqual(roundtrip["username"], "u")
|
||||
|
||||
def test_write_preserves_unknown_keys(self) -> None:
|
||||
# Forward-compat: the gateway might add new fields we don't
|
||||
# know about. Writing must preserve them verbatim.
|
||||
# Forward-compat: the gateway might add new fields unknown to the
|
||||
# current schema. Writing must preserve them verbatim.
|
||||
raw = {"username": "u", "future_field": {"x": 1}, "access_token": "A"}
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
p = Path(d) / "a.json"
|
||||
@@ -644,7 +644,7 @@ class BuildAuthorizeErrorTests(unittest.TestCase):
|
||||
|
||||
def test_different_scope_without_base_url_uses_placeholder(self) -> None:
|
||||
self.assertIn(
|
||||
"<your-gitea-url>/user/settings/applications",
|
||||
"<gitea-base-url>/user/settings/applications",
|
||||
str(self._exc_different_scope(gitea_base_url="")),
|
||||
)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Covers the full PKCE login flow (authorize → callback → token
|
||||
exchange → userinfo → persist), transparent refresh, logout, and
|
||||
the idempotent "already authenticated" short-circuit.
|
||||
|
||||
No real network calls. No browser required: we simulate the
|
||||
No real network calls. No browser required: the test simulates the
|
||||
browser by doing an HTTP GET to the authorize endpoint; the mock
|
||||
server 302-redirects to the loopback callback, which
|
||||
`forge_auth.run_login` is already listening on.
|
||||
@@ -44,14 +44,14 @@ def _free_loopback_port() -> int:
|
||||
class _MockBrowser:
|
||||
"""Drive the authorize endpoint on a worker thread.
|
||||
|
||||
We wait a fraction of a second for `run_login` to bind its
|
||||
The worker waits a fraction of a second for `run_login` to bind its
|
||||
loopback callback server, then GET the authorize URL. The mock
|
||||
server redirects us to the callback; following the redirect
|
||||
server redirects to the callback; following the redirect
|
||||
causes `run_login`'s callback handler to fire, and the auth flow
|
||||
completes.
|
||||
|
||||
urllib's default opener follows redirects automatically, which is
|
||||
exactly what we want here: one GET, one automatic redirect, done.
|
||||
the required behavior here: one GET, one automatic redirect, done.
|
||||
"""
|
||||
|
||||
def __init__(self, authorize_url: str, delay_seconds: float = 0.2) -> None:
|
||||
@@ -111,14 +111,14 @@ class ForgeAuthIntegrationTests(unittest.TestCase):
|
||||
# Helpers
|
||||
# -----------------------------------------------------------------
|
||||
def _login(self) -> fa.AuthFile:
|
||||
"""Run run_login() with an auto-browser that does the GET for us."""
|
||||
"""Run run_login() with an auto-browser issuing the authorize GET."""
|
||||
with mock.patch.dict(os.environ, self.env, clear=True):
|
||||
config = fa.ForgeAuthConfig.from_env()
|
||||
|
||||
# We need to start the mock "browser" AFTER run_login
|
||||
# The mock browser starts AFTER run_login
|
||||
# prints the authorize URL but BEFORE it blocks on the
|
||||
# loopback server. Since run_login prints then blocks
|
||||
# synchronously, we can intercept webbrowser.open to
|
||||
# synchronously, the code intercepts webbrowser.open to
|
||||
# kick off the GET at exactly the right moment.
|
||||
browser_holder: dict[str, _MockBrowser] = {}
|
||||
|
||||
@@ -240,8 +240,8 @@ class ForgeAuthIntegrationTests(unittest.TestCase):
|
||||
def test_callback_state_csrf_mismatch_raises(self) -> None:
|
||||
"""A tampered state on the callback must raise.
|
||||
|
||||
We cannot easily tamper with the real PKCE flow end-to-end,
|
||||
so we exercise verify_state directly: the `run_login` path
|
||||
The real PKCE flow is not easily tampered end-to-end here,
|
||||
so the test exercises verify_state directly: the `run_login` path
|
||||
wires it straight through.
|
||||
"""
|
||||
key = b"\x01" * 32
|
||||
|
||||
Reference in New Issue
Block a user