* fix: repair 57 failing CI tests across 14 files
Categories of fixes:
**Test isolation under xdist (-n auto):**
- test_hermes_logging: Strip ALL RotatingFileHandlers before each test
to prevent handlers leaked from other xdist workers from polluting counts
- test_code_execution: Force TERMINAL_ENV=local in setUp — prevents Modal
AuthError when another test leaks TERMINAL_ENV=modal
- test_timezone: Same TERMINAL_ENV fix for execute_code timezone tests
- test_codex_execution_paths: Mock _resolve_turn_agent_config to ensure
model resolution works regardless of xdist worker state
**Matrix adapter tests (nio not installed in CI):**
- Add _make_fake_nio() helper with real response classes for isinstance()
checks in production code
- Replace MagicMock(spec=nio.XxxResponse) with fake_nio instances
- Wrap production method calls with patch.dict('sys.modules', {'nio': ...})
so import nio succeeds in method bodies
- Use try/except instead of pytest.importorskip for nio.crypto imports
(importorskip can be fooled by MagicMock in sys.modules)
- test_matrix_voice: Skip entire file if nio is a mock, not just missing
**Stale test expectations:**
- test_cli_provider_resolution: _prompt_provider_choice now takes **kwargs
(default param added); mock getpass.getpass alongside input
- test_anthropic_oauth_flow: Mock getpass.getpass (code switched from input)
- test_gemini_provider: Mock models.dev + OpenRouter API lookups to test
hardcoded defaults without external API variance
- test_code_execution: Add notify_on_complete to blocked terminal params
- test_setup_openclaw_migration: Mock prompt_choice to select 'Full setup'
(new quick-setup path leads to _require_tty → sys.exit in CI)
- test_skill_manager_tool: Patch get_all_skills_dirs alongside SKILLS_DIR
so _find_skill searches tmp_path, not real ~/.hermes/skills/
**Missing attributes in object.__new__ test runners:**
- test_platform_reconnect: Add session_store to _make_runner()
- test_session_race_guard: Add hooks, _running_agents_ts, session_store,
delivery_router to _make_runner()
**Production bug fix (gateway/run.py):**
- Fix sentinel eviction race: _AGENT_PENDING_SENTINEL was immediately
evicted by the stale-detection logic because sentinels have no
get_activity_summary() method, causing _stale_idle=inf >= timeout.
Guard _should_evict with 'is not _AGENT_PENDING_SENTINEL'.
* fix: address remaining CI failures
- test_setup_openclaw_migration: Also mock _offer_launch_chat (called at
end of both quick and full setup paths)
- test_code_execution: Move TERMINAL_ENV=local to module level to protect
ALL test classes (TestEnvVarFiltering, TestExecuteCodeEdgeCases,
TestInterruptHandling, TestHeadTailTruncation) from xdist env leaks
- test_matrix: Use try/except for nio.crypto imports (importorskip can be
fooled by MagicMock in sys.modules under xdist)
53 lines
2.0 KiB
Python
53 lines
2.0 KiB
Python
"""Tests for Anthropic OAuth setup flow behavior."""
|
|
|
|
from hermes_cli.config import load_env, save_env_value
|
|
|
|
|
|
def test_run_anthropic_oauth_flow_prefers_claude_code_credentials(tmp_path, monkeypatch, capsys):
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
|
monkeypatch.setattr(
|
|
"agent.anthropic_adapter.run_oauth_setup_token",
|
|
lambda: "sk-ant-oat01-from-claude-setup",
|
|
)
|
|
monkeypatch.setattr(
|
|
"agent.anthropic_adapter.read_claude_code_credentials",
|
|
lambda: {
|
|
"accessToken": "cc-access-token",
|
|
"refreshToken": "cc-refresh-token",
|
|
"expiresAt": 9999999999999,
|
|
},
|
|
)
|
|
monkeypatch.setattr(
|
|
"agent.anthropic_adapter.is_claude_code_token_valid",
|
|
lambda creds: True,
|
|
)
|
|
|
|
from hermes_cli.main import _run_anthropic_oauth_flow
|
|
|
|
save_env_value("ANTHROPIC_TOKEN", "stale-env-token")
|
|
assert _run_anthropic_oauth_flow(save_env_value) is True
|
|
|
|
env_vars = load_env()
|
|
assert env_vars["ANTHROPIC_TOKEN"] == ""
|
|
assert env_vars["ANTHROPIC_API_KEY"] == ""
|
|
output = capsys.readouterr().out
|
|
assert "Claude Code credentials linked" in output
|
|
|
|
|
|
def test_run_anthropic_oauth_flow_manual_token_still_persists(tmp_path, monkeypatch, capsys):
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
|
monkeypatch.setattr("agent.anthropic_adapter.run_oauth_setup_token", lambda: None)
|
|
monkeypatch.setattr("agent.anthropic_adapter.read_claude_code_credentials", lambda: None)
|
|
monkeypatch.setattr("agent.anthropic_adapter.is_claude_code_token_valid", lambda creds: False)
|
|
monkeypatch.setattr("builtins.input", lambda _prompt="": "sk-ant-oat01-manual-token")
|
|
monkeypatch.setattr("getpass.getpass", lambda _prompt="": "sk-ant-oat01-manual-token")
|
|
|
|
from hermes_cli.main import _run_anthropic_oauth_flow
|
|
|
|
assert _run_anthropic_oauth_flow(save_env_value) is True
|
|
|
|
env_vars = load_env()
|
|
assert env_vars["ANTHROPIC_TOKEN"] == "sk-ant-oat01-manual-token"
|
|
output = capsys.readouterr().out
|
|
assert "Setup-token saved" in output
|