🚧 Add topic explorer

This commit is contained in:
Jonas Bengtsson
2026-09-20 09:23:04 +02:00
parent 1e491642f1
commit 6385a27411
11 changed files with 1184 additions and 6 deletions
+65
View File
@@ -245,6 +245,71 @@ def client(db_session, monkeypatch):
monkeypatch.setattr(broker_router, "_call_control", _fake_call_control)
monkeypatch.setattr(system_router, "_call_control", _fake_call_control)
# The topic explorer talks to the broker via MQTT. Fake the session
# registry + publish/retained so the endpoints can be exercised
# without a live broker.
from app.routers import topics as topics_router
from app import explorer as explorer_module
class FakeSession:
def __init__(self, id, username, topic_filter):
self.id = id
self.username = username
self.topic_filter = topic_filter
class FakeSessions:
def __init__(self):
self._sessions = {}
self._counter = 0
def sweep(self):
pass
def start(self, username, topic_filter):
self._counter += 1
sid = f"fake-{self._counter}"
self._sessions[sid] = FakeSession(sid, username, topic_filter)
return self._sessions[sid]
def get(self, session_id):
if session_id not in self._sessions:
raise KeyError(session_id)
return self._sessions[session_id]
def stop(self, session_id):
self._sessions.pop(session_id, None)
def stop_all(self):
self._sessions.clear()
fake_sessions = FakeSessions()
monkeypatch.setattr(explorer_module, "sessions", fake_sessions)
def fake_messages_since(session_id, index):
return []
def fake_list_retained(max_results=200, timeout=3.0):
return [
{
"index": 0,
"topic": "site/config/level",
"qos": 1,
"retain": True,
"received_at": 12345.0,
"payload_b64": "MTIz",
"payload_text": "123",
"properties": None,
}
]
def fake_publish(topic, payload, qos, retain, timeout=10.0):
fake_publish.calls.append((topic, payload, qos, retain))
fake_publish.calls = []
monkeypatch.setattr(explorer_module, "messages_since", fake_messages_since)
monkeypatch.setattr(explorer_module, "list_retained", fake_list_retained)
monkeypatch.setattr(explorer_module, "publish_message", fake_publish)
# The router imports names from the module: patch there too.
monkeypatch.setattr(topics_router.explorer, "sessions", fake_sessions)
monkeypatch.setattr(topics_router.explorer, "messages_since", fake_messages_since)
monkeypatch.setattr(topics_router.explorer, "list_retained", fake_list_retained)
monkeypatch.setattr(topics_router.explorer, "publish_message", fake_publish)
with TestClient(main_module.app) as test_client:
yield test_client