Tests did monkeypatch.setattr(<facade module>, name) where name is now defined in a sibling module and the production path reads the sibling's binding. Where production reads through BOTH bindings the setattr is duplicated onto the defining module (import added next to the existing alias import); where only the sibling reads it the target is repointed. Seams whose production readers go through the facade are left alone.
68 lines
2.4 KiB
Python
68 lines
2.4 KiB
Python
"""Unit tests for _print_loopback_ssh_hint() in hermes_cli/auth.py.
|
|
|
|
The helper warns users that loopback OAuth flows (Spotify) don't work over
|
|
SSH unless they set up an `ssh -L` port forward between their laptop's
|
|
browser and the remote host's loopback listener.
|
|
|
|
xAI Grok OAuth no longer uses this helper — its login is device-code-only —
|
|
but the Spotify integration still relies on it.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import io
|
|
import contextlib
|
|
import socket
|
|
|
|
|
|
from hermes_cli import auth as auth_mod
|
|
import hermes_cli.auth_device_flow as auth_device_flow
|
|
|
|
|
|
def _cap(fn):
|
|
buf = io.StringIO()
|
|
with contextlib.redirect_stdout(buf):
|
|
fn()
|
|
return buf.getvalue()
|
|
|
|
|
|
def test_loopback_ssh_hint_silent_when_not_remote(monkeypatch):
|
|
monkeypatch.setattr(auth_mod, "_is_remote_session", lambda: False)
|
|
monkeypatch.setattr(auth_device_flow, "_is_remote_session", lambda: False)
|
|
out = _cap(lambda: auth_mod._print_loopback_ssh_hint(
|
|
"http://127.0.0.1:43827/spotify/callback", docs_url=auth_mod.SPOTIFY_DOCS_URL
|
|
))
|
|
assert out == ""
|
|
|
|
|
|
def test_loopback_ssh_hint_has_visual_header(monkeypatch):
|
|
"""The hint should print a divider and header so it stands out in noisy output."""
|
|
monkeypatch.setattr(auth_mod, "_is_remote_session", lambda: True)
|
|
monkeypatch.setattr(auth_device_flow, "_is_remote_session", lambda: True)
|
|
out = _cap(lambda: auth_mod._print_loopback_ssh_hint(
|
|
"http://127.0.0.1:43827/callback"
|
|
))
|
|
assert "Remote session detected" in out
|
|
assert "---" in out # divider is present
|
|
|
|
|
|
class TestSshUserAtHost:
|
|
def test_resolves_user_and_hostname(self, monkeypatch):
|
|
monkeypatch.setenv("USER", "alice")
|
|
monkeypatch.delenv("LOGNAME", raising=False)
|
|
monkeypatch.setattr(socket, "gethostname", lambda: "myserver")
|
|
assert auth_mod._ssh_user_at_host() == "alice@myserver"
|
|
|
|
|
|
def test_placeholder_when_no_env_vars(self, monkeypatch):
|
|
monkeypatch.delenv("USER", raising=False)
|
|
monkeypatch.delenv("LOGNAME", raising=False)
|
|
monkeypatch.setattr(socket, "gethostname", lambda: "host1")
|
|
assert auth_mod._ssh_user_at_host() == "<user>@host1"
|
|
|
|
|
|
def test_placeholder_when_empty_hostname(self, monkeypatch):
|
|
monkeypatch.setenv("USER", "dave")
|
|
monkeypatch.setattr(socket, "gethostname", lambda: "")
|
|
assert auth_mod._ssh_user_at_host() == "dave@<this-host>"
|