fix: clean up pre-existing lint in test_api.py and document per-request key read

This commit is contained in:
Brian Krabach
2026-04-01 11:17:42 -07:00
parent e1b0b55bc8
commit b4f29dacd0
2 changed files with 52 additions and 16 deletions
+22 -3
View File
@@ -558,6 +558,7 @@ async def instance_info() -> dict:
discover peer names and verify reachability. discover peer names and verify reachability.
""" """
settings = load_settings() settings = load_settings()
# Read fresh so the UI reflects key-file changes without requiring a restart.
fed_key = load_federation_key() fed_key = load_federation_key()
return { return {
"name": settings["device_name"], "name": settings["device_name"],
@@ -819,7 +820,13 @@ async def federation_sessions(request: Request) -> list[dict]:
headers={"Authorization": f"Bearer {key}"}, headers={"Authorization": f"Bearer {key}"},
) )
if resp.status_code in (401, 403): if resp.status_code in (401, 403):
return [{"status": "auth_failed", "remoteId": remote_id, "deviceName": remote_name}] return [
{
"status": "auth_failed",
"remoteId": remote_id,
"deviceName": remote_name,
}
]
resp.raise_for_status() resp.raise_for_status()
sessions = resp.json() sessions = resp.json()
# Tag each session with deviceName and remoteId # Tag each session with deviceName and remoteId
@@ -828,9 +835,21 @@ async def federation_sessions(request: Request) -> list[dict]:
for s in sessions for s in sessions
] ]
except httpx.HTTPStatusError: except httpx.HTTPStatusError:
return [{"status": "auth_failed", "remoteId": remote_id, "deviceName": remote_name}] return [
{
"status": "auth_failed",
"remoteId": remote_id,
"deviceName": remote_name,
}
]
except Exception: except Exception:
return [{"status": "unreachable", "remoteId": remote_id, "deviceName": remote_name}] return [
{
"status": "unreachable",
"remoteId": remote_id,
"deviceName": remote_name,
}
]
remote_results: list[list[dict]] = await asyncio.gather( remote_results: list[list[dict]] = await asyncio.gather(
*(fetch_remote(remote) for remote in remote_instances) *(fetch_remote(remote) for remote in remote_instances)
+30 -13
View File
@@ -1427,7 +1427,6 @@ def test_federation_bearer_auth_accepted(monkeypatch):
After implementation: _federation_key exists, middleware is found and patched, After implementation: _federation_key exists, middleware is found and patched,
Bearer request is accepted. Bearer request is accepted.
""" """
from muxplex.main import _federation_key # ImportError before implementation
from muxplex.auth import AuthMiddleware from muxplex.auth import AuthMiddleware
import muxplex.main as main_module import muxplex.main as main_module
@@ -1474,7 +1473,7 @@ def test_federation_client_exists_on_app_state(monkeypatch):
monkeypatch.setenv("MUXPLEX_PASSWORD", "test-password") monkeypatch.setenv("MUXPLEX_PASSWORD", "test-password")
with TestClient(app) as c: with TestClient(app):
# Inside the context manager the lifespan has completed startup, # Inside the context manager the lifespan has completed startup,
# so app.state.federation_client must be set. # so app.state.federation_client must be set.
assert hasattr(app.state, "federation_client"), ( assert hasattr(app.state, "federation_client"), (
@@ -1515,11 +1514,16 @@ def test_federation_sessions_returns_local_sessions(client, monkeypatch, tmp_pat
# Write settings with a known device_name and no remote instances # Write settings with a known device_name and no remote instances
import json import json
settings_path.write_text(json.dumps({"device_name": "my-workstation", "remote_instances": []}))
settings_path.write_text(
json.dumps({"device_name": "my-workstation", "remote_instances": []})
)
# Mock local session data # Mock local session data
monkeypatch.setattr("muxplex.main.get_session_list", lambda: ["session-one"]) monkeypatch.setattr("muxplex.main.get_session_list", lambda: ["session-one"])
monkeypatch.setattr("muxplex.main.get_snapshots", lambda: {"session-one": "pane text"}) monkeypatch.setattr(
"muxplex.main.get_snapshots", lambda: {"session-one": "pane text"}
)
response = client.get("/api/federation/sessions") response = client.get("/api/federation/sessions")
assert response.status_code == 200 assert response.status_code == 200
@@ -1538,7 +1542,9 @@ def test_federation_sessions_returns_local_sessions(client, monkeypatch, tmp_pat
assert local["remoteId"] is None assert local["remoteId"] is None
def test_federation_sessions_includes_remote_failure_status(client, monkeypatch, tmp_path): def test_federation_sessions_includes_remote_failure_status(
client, monkeypatch, tmp_path
):
"""GET /api/federation/sessions includes a status entry for unreachable remotes. """GET /api/federation/sessions includes a status entry for unreachable remotes.
When a remote instance cannot be reached (connection error), the result must When a remote instance cannot be reached (connection error), the result must
@@ -1554,19 +1560,28 @@ def test_federation_sessions_includes_remote_failure_status(client, monkeypatch,
monkeypatch.setattr(settings_mod, "SETTINGS_PATH", settings_path) monkeypatch.setattr(settings_mod, "SETTINGS_PATH", settings_path)
# Configure one remote instance that will fail # Configure one remote instance that will fail
settings_path.write_text(json.dumps({ settings_path.write_text(
"device_name": "local-host", json.dumps(
"remote_instances": [ {
{"url": "http://remote-host:8088", "key": "abc123", "name": "remote-host", "id": "remote-1"} "device_name": "local-host",
], "remote_instances": [
})) {
"url": "http://remote-host:8088",
"key": "abc123",
"name": "remote-host",
"id": "remote-1",
}
],
}
)
)
# Mock local sessions (empty for simplicity) # Mock local sessions (empty for simplicity)
monkeypatch.setattr("muxplex.main.get_session_list", lambda: []) monkeypatch.setattr("muxplex.main.get_session_list", lambda: [])
monkeypatch.setattr("muxplex.main.get_snapshots", lambda: {}) monkeypatch.setattr("muxplex.main.get_snapshots", lambda: {})
# Patch the federation_client to raise a ConnectError (unreachable) # Patch the federation_client to raise a ConnectError (unreachable)
from unittest.mock import AsyncMock, MagicMock from unittest.mock import MagicMock
async def mock_get(url, **kwargs): async def mock_get(url, **kwargs):
raise httpx.ConnectError("Connection refused") raise httpx.ConnectError("Connection refused")
@@ -1583,7 +1598,9 @@ def test_federation_sessions_includes_remote_failure_status(client, monkeypatch,
assert isinstance(data, list) assert isinstance(data, list)
# Find the failure status entry for the remote # Find the failure status entry for the remote
failure_entries = [s for s in data if s.get("status") in ("unreachable", "auth_failed")] failure_entries = [
s for s in data if s.get("status") in ("unreachable", "auth_failed")
]
assert len(failure_entries) == 1, ( assert len(failure_entries) == 1, (
f"Expected 1 failure status entry, got: {failure_entries}. Full data: {data}" f"Expected 1 failure status entry, got: {failure_entries}. Full data: {data}"
) )