afv-library/skills/investigating-agentforce-architecture/scripts/tests/test_resolve_creds.py
2026-06-12 10:55:46 +00:00

158 lines
6.1 KiB
Python

"""Tests for ``main._resolve_creds`` — the two-path access-token retrieval
introduced for forcedotcom/cli#3560 (sf CLI v2 redaction, effective
2026-05-27).
Path 1 (primary): ``sf org auth show-access-token --json --no-prompt``
via the ``show_access_token`` recipe.
Path 2 (fallback): ``sf org display`` payload with
``SF_TEMP_SHOW_SECRETS=true`` env var.
We mock ``run_sf`` (not subprocess) since these tests target the
orchestration logic in ``main.py``, not the recipe loader. The recipe
loader and subprocess env injection have their own coverage in
``test_sf_cli.py``.
"""
from __future__ import annotations
import unittest
from unittest import mock
from . import _bootstrap # noqa: F401 — sys.path setup
import main # type: ignore
from sf_cli import AuthRequired, SfCliError # type: ignore
REDACTED_TOKEN = "[REDACTED] Use 'sf org auth show-access-token' to view"
def _display_payload(*, instance_url="https://example.salesforce.com",
access_token="TOKEN_FROM_DISPLAY"):
return {"result": {
"instanceUrl": instance_url,
"accessToken": access_token,
}}
def _show_token_payload(*, access_token="TOKEN_FROM_SHOW"):
return {"result": {"accessToken": access_token}}
class ResolveCredsTests(unittest.TestCase):
"""Cover every branch of the two-path retrieval."""
def _route(self, *, primary_payload=None, primary_exc=None,
display_payload=None):
"""Build a ``run_sf`` side-effect that dispatches by recipe name."""
display = display_payload or _display_payload()
primary = primary_payload or _show_token_payload()
def fake_run_sf(name, **params):
if name == "org_display":
return display
if name == "show_access_token":
if primary_exc is not None:
raise primary_exc
return primary
raise AssertionError(f"unexpected recipe: {name}")
return fake_run_sf
def test_primary_path_returns_show_token(self):
"""Happy path — dedicated command returns a clean token."""
with mock.patch.object(main, "run_sf", side_effect=self._route()):
url, token = main._resolve_creds("my-org")
self.assertEqual(url, "https://example.salesforce.com")
self.assertEqual(token, "TOKEN_FROM_SHOW")
def test_primary_unknown_falls_back_to_display(self):
"""Older sf CLI without the dedicated command surfaces SfCliError;
we fall back to the display payload's accessToken."""
with mock.patch.object(
main, "run_sf",
side_effect=self._route(
primary_exc=SfCliError("sf CLI 'show_access_token' failed"),
),
):
url, token = main._resolve_creds("my-org")
self.assertEqual(url, "https://example.salesforce.com")
self.assertEqual(token, "TOKEN_FROM_DISPLAY")
def test_primary_returns_redacted_token_falls_back(self):
"""Edge case: dedicated command runs cleanly but returns the
placeholder string. Treat as failure and use the display fallback."""
with mock.patch.object(
main, "run_sf",
side_effect=self._route(
primary_payload=_show_token_payload(access_token=REDACTED_TOKEN),
),
):
_, token = main._resolve_creds("my-org")
self.assertEqual(token, "TOKEN_FROM_DISPLAY")
def test_primary_returns_empty_token_falls_back(self):
"""Empty string from the dedicated command also triggers fallback."""
with mock.patch.object(
main, "run_sf",
side_effect=self._route(
primary_payload=_show_token_payload(access_token=""),
),
):
_, token = main._resolve_creds("my-org")
self.assertEqual(token, "TOKEN_FROM_DISPLAY")
def test_both_paths_redacted_raises_authrequired(self):
"""If both paths come back redacted/empty, surface AuthRequired
rather than handing the placeholder to downstream Tooling/REST
callers (which would 401 with INVALID_AUTH_HEADER)."""
with mock.patch.object(
main, "run_sf",
side_effect=self._route(
primary_payload=_show_token_payload(access_token=REDACTED_TOKEN),
display_payload=_display_payload(access_token=REDACTED_TOKEN),
),
):
with self.assertRaises(AuthRequired) as ctx:
main._resolve_creds("my-org")
self.assertIn("could not retrieve a usable access token", str(ctx.exception))
def test_missing_instance_url_raises_authrequired(self):
"""display returning empty instanceUrl is a hard failure — no
amount of token-juggling helps if we can't talk to the org."""
with mock.patch.object(
main, "run_sf",
side_effect=self._route(
display_payload=_display_payload(instance_url=""),
),
):
with self.assertRaises(AuthRequired) as ctx:
main._resolve_creds("my-org")
self.assertIn("instanceUrl", str(ctx.exception))
def test_primary_path_recipe_name_is_show_access_token(self):
"""Tripwire — the primary call MUST go through the
``show_access_token`` recipe. Without it the patch silently
regresses to the env-var-only path on sf CLI versions that
already shipped the dedicated command."""
recipes_called: list[str] = []
def fake_run_sf(name, **params):
recipes_called.append(name)
if name == "org_display":
return _display_payload()
if name == "show_access_token":
return _show_token_payload()
raise AssertionError(f"unexpected recipe: {name}")
with mock.patch.object(main, "run_sf", side_effect=fake_run_sf):
main._resolve_creds("my-org")
self.assertIn("show_access_token", recipes_called)
# And the alias was passed through:
# (We don't capture params here, but the recipe loader enforces
# required_params at run_sf time — see test_sf_cli.py.)
if __name__ == "__main__":
unittest.main()