Skip to content

Commit 537eb47

Browse files
sammuliclaude
andcommitted
refactor(cli): guard device resolution, fix test catalog isolation
Wrap _resolve_device_handle() in do_login and do_logout with a (ValueError, KeyError) guard so unknown or missing devices produce a clean error message + sys.exit(1) instead of an uncaught traceback. Refactor all four TestCliLoginLogout tests to use the existing _patch_catalog(stack) helper, which patches entry_points AND registers a teardown callback that clears _cat._cache, eliminating the catalog state leak that the previous inline pattern left behind. Also strengthen test_login_dispatches_to_auth_login to assert that the real device handle (schema.name == "d3d") is passed to auth.login. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 44f1d4c commit 537eb47

2 files changed

Lines changed: 15 additions & 22 deletions

File tree

fdp/cli.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,12 @@ def do_env(args) -> None:
5252

5353

5454
def do_login(args) -> None:
55-
handle = _resolve_device_handle(args.default_device)
5655
try:
56+
handle = _resolve_device_handle(args.default_device)
5757
result = auth.login(handle, write=args.write)
58+
except (ValueError, KeyError) as exc:
59+
print(f"Error: {exc}", file=sys.stderr)
60+
sys.exit(1)
5861
except auth.AuthError as exc:
5962
print(f"Login failed: {exc}", file=sys.stderr)
6063
sys.exit(1)
@@ -71,7 +74,11 @@ def do_login(args) -> None:
7174

7275

7376
def do_logout(args) -> None:
74-
handle = _resolve_device_handle(args.default_device)
77+
try:
78+
handle = _resolve_device_handle(args.default_device)
79+
except (ValueError, KeyError) as exc:
80+
print(f"Error: {exc}", file=sys.stderr)
81+
sys.exit(1)
7582
removed = auth.logout(handle)
7683
print("Removed cached token."
7784
if removed else "No cached token to remove.")

tests/test_cli.py

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -333,34 +333,28 @@ def test_default_device_passed_to_setup_environment(self):
333333
class TestCliLoginLogout(unittest.TestCase):
334334
def test_login_dispatches_to_auth_login(self):
335335
from fdp import cli, auth
336-
ep = _make_catalog_ep("d3d", _D3D_TEST_YAML)
337336
ct = auth.CachedToken(device="d3d", scope="read", exp=None)
338337
with ExitStack() as stack:
338+
_patch_catalog(stack)
339339
stack.enter_context(mock.patch.object(
340340
sys, "argv", ["fdp", "login"]))
341-
stack.enter_context(mock.patch(
342-
"fdp.catalog.entry_points", return_value=[ep]))
343-
from fdp.catalog import catalog as _cat
344-
_cat._cache = None
345341
login_mock = stack.enter_context(
346342
mock.patch.object(cli.auth, "login", return_value=ct))
347343
buf = io.StringIO()
348344
with redirect_stdout(buf):
349345
cli.main()
350346
login_mock.assert_called_once()
347+
self.assertEqual(
348+
login_mock.call_args.args[0].schema.name, "d3d")
351349
self.assertEqual(login_mock.call_args.kwargs.get("write"), False)
352350

353351
def test_login_write_flag(self):
354352
from fdp import cli, auth
355-
ep = _make_catalog_ep("d3d", _D3D_TEST_YAML)
356353
ct = auth.CachedToken(device="d3d", scope="write", exp=None)
357354
with ExitStack() as stack:
355+
_patch_catalog(stack)
358356
stack.enter_context(mock.patch.object(
359357
sys, "argv", ["fdp", "login", "--write"]))
360-
stack.enter_context(mock.patch(
361-
"fdp.catalog.entry_points", return_value=[ep]))
362-
from fdp.catalog import catalog as _cat
363-
_cat._cache = None
364358
login_mock = stack.enter_context(
365359
mock.patch.object(cli.auth, "login", return_value=ct))
366360
with redirect_stdout(io.StringIO()):
@@ -369,14 +363,10 @@ def test_login_write_flag(self):
369363

370364
def test_logout_dispatches(self):
371365
from fdp import cli
372-
ep = _make_catalog_ep("d3d", _D3D_TEST_YAML)
373366
with ExitStack() as stack:
367+
_patch_catalog(stack)
374368
stack.enter_context(mock.patch.object(
375369
sys, "argv", ["fdp", "logout"]))
376-
stack.enter_context(mock.patch(
377-
"fdp.catalog.entry_points", return_value=[ep]))
378-
from fdp.catalog import catalog as _cat
379-
_cat._cache = None
380370
logout_mock = stack.enter_context(
381371
mock.patch.object(cli.auth, "logout", return_value=True))
382372
with redirect_stdout(io.StringIO()):
@@ -385,14 +375,10 @@ def test_logout_dispatches(self):
385375

386376
def test_run_sets_auto_login_true(self):
387377
from fdp import cli
388-
ep = _make_catalog_ep("d3d", _D3D_TEST_YAML)
389378
with ExitStack() as stack:
379+
_patch_catalog(stack)
390380
stack.enter_context(mock.patch.object(
391381
sys, "argv", ["fdp", "run", "true"]))
392-
stack.enter_context(mock.patch(
393-
"fdp.catalog.entry_points", return_value=[ep]))
394-
from fdp.catalog import catalog as _cat
395-
_cat._cache = None
396382
setup_mock = stack.enter_context(
397383
mock.patch.object(cli, "setup_environment"))
398384
stack.enter_context(mock.patch.object(

0 commit comments

Comments
 (0)