Skip to content

Commit 3cd5541

Browse files
committed
fix: extract shared auth test helpers, global config isolation, align docstring
- Move _inject_github_config / make_github_auth_entry to tests/auth_helpers.py to eliminate duplication across test_extensions, test_presets, test_upgrade - Move auth config isolation fixture to global conftest.py (autouse) so ALL tests are isolated from ~/.specify/auth.json, not just test_upgrade - Align load_auth_config docstring with actual behavior: ValueError may be caught by higher-level HTTP helpers that warn and continue unauthenticated - 1831 tests passing
1 parent 36919ec commit 3cd5541

6 files changed

Lines changed: 43 additions & 49 deletions

File tree

src/specify_cli/authentication/config.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ def load_auth_config(
5151
Returns an empty list when the file does not exist — this means
5252
all HTTP requests will be unauthenticated (opt-in model).
5353
54-
Raises ``ValueError`` on schema violations so misconfigurations
55-
surface immediately rather than silently degrading to no-auth.
54+
Raises ``ValueError`` on schema violations. Callers that want
55+
misconfigurations to fail fast can allow this exception to
56+
propagate; higher-level HTTP helpers may instead catch it,
57+
warn, and continue with unauthenticated requests.
5658
"""
5759
config_path = path or _default_config_path()
5860

tests/auth_helpers.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""Shared test helpers for authentication config injection."""
2+
3+
from __future__ import annotations
4+
5+
from specify_cli.authentication.config import AuthConfigEntry
6+
7+
8+
def make_github_auth_entry(token_env: str = "GH_TOKEN") -> AuthConfigEntry:
9+
"""Build a GitHub ``AuthConfigEntry`` for testing."""
10+
return AuthConfigEntry(
11+
hosts=("github.com", "api.github.com", "raw.githubusercontent.com", "codeload.github.com"),
12+
provider="github",
13+
auth="bearer",
14+
token_env=token_env,
15+
)
16+
17+
18+
def inject_github_config(monkeypatch, token_env: str = "GH_TOKEN") -> None:
19+
"""Inject a GitHub auth.json config entry into the auth HTTP module."""
20+
from specify_cli.authentication import http as _auth_http
21+
monkeypatch.setattr(_auth_http, "_config_override", [make_github_auth_entry(token_env)])

tests/conftest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,15 @@ def _has_working_bash() -> bool:
6666
def strip_ansi(text: str) -> str:
6767
"""Remove ANSI escape codes from Rich-formatted CLI output."""
6868
return _ANSI_ESCAPE_RE.sub("", text)
69+
70+
71+
# ---------------------------------------------------------------------------
72+
# Auth config isolation — prevents tests from reading ~/.specify/auth.json
73+
# ---------------------------------------------------------------------------
74+
75+
76+
@pytest.fixture(autouse=True)
77+
def _isolate_auth_config(monkeypatch):
78+
"""Ensure no test reads the real ~/.specify/auth.json."""
79+
from specify_cli.authentication import http as _auth_http
80+
monkeypatch.setattr(_auth_http, "_config_override", [])

tests/test_extensions.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,16 +2454,8 @@ def _make_catalog(self, temp_dir):
24542454
return ExtensionCatalog(project_dir)
24552455

24562456
def _inject_github_config(self, monkeypatch, token_env="GH_TOKEN"):
2457-
"""Inject a GitHub auth.json config entry for testing."""
2458-
from specify_cli.authentication.config import AuthConfigEntry
2459-
import specify_cli.authentication.http as _mod
2460-
entry = AuthConfigEntry(
2461-
hosts=("github.com", "api.github.com", "raw.githubusercontent.com", "codeload.github.com"),
2462-
provider="github",
2463-
auth="bearer",
2464-
token_env=token_env,
2465-
)
2466-
monkeypatch.setattr(_mod, "_config_override", [entry])
2457+
from tests.auth_helpers import inject_github_config
2458+
inject_github_config(monkeypatch, token_env)
24672459

24682460
def test_make_request_no_token_no_auth_header(self, temp_dir, monkeypatch):
24692461
"""Without a token, requests carry no Authorization header."""
@@ -2529,8 +2521,6 @@ def test_make_request_no_auth_when_no_config(self, temp_dir, monkeypatch):
25292521
"""No auth header when no auth.json config exists."""
25302522
monkeypatch.delenv("GITHUB_TOKEN", raising=False)
25312523
monkeypatch.delenv("GH_TOKEN", raising=False)
2532-
import specify_cli.authentication.http as _mod
2533-
monkeypatch.setattr(_mod, "_config_override", [])
25342524
catalog = self._make_catalog(temp_dir)
25352525
req = catalog._make_request("https://github.com/org/repo/releases/download/v1/ext.zip")
25362526
assert "Authorization" not in req.headers

tests/test_presets.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,16 +1224,8 @@ class TestPresetCatalog:
12241224
"""Test template catalog functionality."""
12251225

12261226
def _inject_github_config(self, monkeypatch, token_env="GH_TOKEN"):
1227-
"""Inject a GitHub auth.json config entry for testing."""
1228-
from specify_cli.authentication.config import AuthConfigEntry
1229-
import specify_cli.authentication.http as _mod
1230-
entry = AuthConfigEntry(
1231-
hosts=("github.com", "api.github.com", "raw.githubusercontent.com", "codeload.github.com"),
1232-
provider="github",
1233-
auth="bearer",
1234-
token_env=token_env,
1235-
)
1236-
monkeypatch.setattr(_mod, "_config_override", [entry])
1227+
from tests.auth_helpers import inject_github_config
1228+
inject_github_config(monkeypatch, token_env)
12371229

12381230
def test_default_catalog_url(self, project_dir):
12391231
"""Test default catalog URL."""
@@ -1481,8 +1473,6 @@ def test_make_request_no_auth_when_no_config(self, project_dir, monkeypatch):
14811473
"""No auth header when no auth.json config exists."""
14821474
monkeypatch.delenv("GITHUB_TOKEN", raising=False)
14831475
monkeypatch.delenv("GH_TOKEN", raising=False)
1484-
import specify_cli.authentication.http as _mod
1485-
monkeypatch.setattr(_mod, "_config_override", [])
14861476
catalog = PresetCatalog(project_dir)
14871477
req = catalog._make_request("https://github.com/org/repo/releases/download/v1/pack.zip")
14881478
assert "Authorization" not in req.headers

tests/test_upgrade.py

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,6 @@
2424
app,
2525
)
2626

27-
28-
@pytest.fixture(autouse=True)
29-
def _isolate_auth_config(monkeypatch):
30-
"""Ensure tests never read the real ~/.specify/auth.json."""
31-
from specify_cli.authentication import http as _mod
32-
monkeypatch.setattr(_mod, "_config_override", [])
33-
3427
from tests.conftest import strip_ansi
3528

3629
runner = CliRunner()
@@ -310,16 +303,8 @@ def _side_effect(req, timeout=None):
310303

311304

312305
def _inject_github_config(monkeypatch, token_env="GH_TOKEN"):
313-
"""Inject a GitHub auth.json config entry for testing."""
314-
from specify_cli.authentication.config import AuthConfigEntry
315-
import specify_cli.authentication.http as _mod
316-
entry = AuthConfigEntry(
317-
hosts=("github.com", "api.github.com", "raw.githubusercontent.com", "codeload.github.com"),
318-
provider="github",
319-
auth="bearer",
320-
token_env=token_env,
321-
)
322-
monkeypatch.setattr(_mod, "_config_override", [entry])
306+
from tests.auth_helpers import inject_github_config
307+
inject_github_config(monkeypatch, token_env)
323308

324309

325310
class TestUserStory3:
@@ -350,8 +335,6 @@ def test_github_token_used_when_gh_token_unset(self, monkeypatch):
350335
def test_no_authorization_header_when_both_unset(self, monkeypatch):
351336
monkeypatch.delenv("GH_TOKEN", raising=False)
352337
monkeypatch.delenv("GITHUB_TOKEN", raising=False)
353-
import specify_cli.authentication.http as _mod
354-
monkeypatch.setattr(_mod, "_config_override", [])
355338
captured, side_effect = _capture_request_via_urlopen()
356339
with patch("specify_cli.authentication.http.urllib.request.urlopen", side_effect=side_effect):
357340
_fetch_latest_release_tag()
@@ -396,8 +379,6 @@ def test_gh_token_never_appears_in_failure_output(
396379
):
397380
monkeypatch.setenv("GH_TOKEN", SENTINEL_GH_TOKEN)
398381
monkeypatch.delenv("GITHUB_TOKEN", raising=False)
399-
import specify_cli.authentication.http as _mod
400-
monkeypatch.setattr(_mod, "_config_override", [])
401382
with patch("specify_cli._get_installed_version", return_value="0.7.4"), patch(
402383
"specify_cli.authentication.http.urllib.request.urlopen", side_effect=side_effect
403384
):
@@ -411,8 +392,6 @@ def test_github_token_never_appears_in_failure_output(
411392
):
412393
monkeypatch.delenv("GH_TOKEN", raising=False)
413394
monkeypatch.setenv("GITHUB_TOKEN", SENTINEL_GITHUB_TOKEN)
414-
import specify_cli.authentication.http as _mod
415-
monkeypatch.setattr(_mod, "_config_override", [])
416395
with patch("specify_cli._get_installed_version", return_value="0.7.4"), patch(
417396
"specify_cli.authentication.http.urllib.request.urlopen", side_effect=side_effect
418397
):

0 commit comments

Comments
 (0)