Add Telegram QR onboarding to dashboard
This commit is contained in:
@@ -968,6 +968,157 @@ class TestWebServerEndpoints:
|
||||
assert data["state"] == "not_configured"
|
||||
assert "DISCORD_BOT_TOKEN" in data["message"]
|
||||
|
||||
def test_telegram_onboarding_start_strips_poll_token(self, monkeypatch):
|
||||
import hermes_cli.web_server as ws
|
||||
|
||||
with ws._telegram_onboarding_lock:
|
||||
ws._telegram_onboarding_pairings.clear()
|
||||
|
||||
calls = []
|
||||
|
||||
def fake_request(method, path, *, body=None, bearer_token=None):
|
||||
calls.append((method, path, body, bearer_token))
|
||||
return {
|
||||
"pairing_id": "pair123",
|
||||
"poll_token": "poll-secret",
|
||||
"suggested_username": "hermes_pair123_bot",
|
||||
"deep_link": "https://t.me/newbot/HermesSetupBot/hermes_pair123_bot",
|
||||
"qr_payload": "https://t.me/newbot/HermesSetupBot/hermes_pair123_bot",
|
||||
"expires_at": "2027-05-18T00:00:00.000Z",
|
||||
}
|
||||
|
||||
monkeypatch.setattr(ws, "_telegram_onboarding_request_sync", fake_request)
|
||||
|
||||
resp = self.client.post(
|
||||
"/api/messaging/telegram/onboarding/start",
|
||||
json={"bot_name": "Hosted Hermes"},
|
||||
)
|
||||
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
assert data["pairing_id"] == "pair123"
|
||||
assert "poll_token" not in data
|
||||
assert calls == [
|
||||
(
|
||||
"POST",
|
||||
"/v1/telegram/pairings",
|
||||
{"bot_name": "Hosted Hermes"},
|
||||
None,
|
||||
)
|
||||
]
|
||||
|
||||
def test_telegram_onboarding_ready_and_apply_never_returns_bot_token(self, monkeypatch):
|
||||
import hermes_cli.web_server as ws
|
||||
from hermes_cli.config import load_config, load_env
|
||||
|
||||
with ws._telegram_onboarding_lock:
|
||||
ws._telegram_onboarding_pairings.clear()
|
||||
|
||||
def fake_request(method, path, *, body=None, bearer_token=None):
|
||||
if method == "POST":
|
||||
return {
|
||||
"pairing_id": "pair-ready",
|
||||
"poll_token": "poll-secret",
|
||||
"suggested_username": "hermes_pair_ready_bot",
|
||||
"deep_link": "https://t.me/newbot/HermesSetupBot/hermes_pair_ready_bot",
|
||||
"qr_payload": "https://t.me/newbot/HermesSetupBot/hermes_pair_ready_bot",
|
||||
"expires_at": "2027-05-18T00:00:00.000Z",
|
||||
}
|
||||
assert method == "GET"
|
||||
assert path == "/v1/telegram/pairings/pair-ready"
|
||||
assert bearer_token == "poll-secret"
|
||||
return {
|
||||
"status": "ready",
|
||||
"bot_username": "hermes_pair_ready_bot",
|
||||
"owner_user_id": 123456789,
|
||||
"token": "123456:SECRET",
|
||||
}
|
||||
|
||||
monkeypatch.setattr(ws, "_telegram_onboarding_request_sync", fake_request)
|
||||
|
||||
start = self.client.post("/api/messaging/telegram/onboarding/start", json={})
|
||||
assert start.status_code == 200
|
||||
|
||||
ready = self.client.get("/api/messaging/telegram/onboarding/pair-ready")
|
||||
assert ready.status_code == 200
|
||||
ready_data = ready.json()
|
||||
assert ready_data["status"] == "ready"
|
||||
assert ready_data["owner_user_id"] == "123456789"
|
||||
assert "token" not in ready_data
|
||||
|
||||
applied = self.client.post(
|
||||
"/api/messaging/telegram/onboarding/pair-ready/apply",
|
||||
json={"allowed_user_ids": ["123456789", "123456789"]},
|
||||
)
|
||||
assert applied.status_code == 200
|
||||
applied_data = applied.json()
|
||||
assert applied_data == {
|
||||
"ok": True,
|
||||
"platform": "telegram",
|
||||
"bot_username": "hermes_pair_ready_bot",
|
||||
"needs_restart": True,
|
||||
}
|
||||
env = load_env()
|
||||
assert env["TELEGRAM_BOT_TOKEN"] == "123456:SECRET"
|
||||
assert env["TELEGRAM_ALLOWED_USERS"] == "123456789"
|
||||
assert load_config()["platforms"]["telegram"]["enabled"] is True
|
||||
|
||||
def test_telegram_onboarding_apply_requires_ready_pairing(self, monkeypatch):
|
||||
import hermes_cli.web_server as ws
|
||||
|
||||
with ws._telegram_onboarding_lock:
|
||||
ws._telegram_onboarding_pairings.clear()
|
||||
|
||||
def fake_request(method, path, *, body=None, bearer_token=None):
|
||||
return {
|
||||
"pairing_id": "pair-waiting",
|
||||
"poll_token": "poll-secret",
|
||||
"suggested_username": "hermes_pair_waiting_bot",
|
||||
"deep_link": "https://t.me/newbot/HermesSetupBot/hermes_pair_waiting_bot",
|
||||
"qr_payload": "https://t.me/newbot/HermesSetupBot/hermes_pair_waiting_bot",
|
||||
"expires_at": "2027-05-18T00:00:00.000Z",
|
||||
}
|
||||
|
||||
monkeypatch.setattr(ws, "_telegram_onboarding_request_sync", fake_request)
|
||||
|
||||
start = self.client.post("/api/messaging/telegram/onboarding/start", json={})
|
||||
assert start.status_code == 200
|
||||
|
||||
resp = self.client.post(
|
||||
"/api/messaging/telegram/onboarding/pair-waiting/apply",
|
||||
json={"allowed_user_ids": ["123456789"]},
|
||||
)
|
||||
|
||||
assert resp.status_code == 409
|
||||
assert "not ready" in resp.json()["detail"]
|
||||
|
||||
def test_telegram_onboarding_cancel_clears_local_session(self, monkeypatch):
|
||||
import hermes_cli.web_server as ws
|
||||
|
||||
with ws._telegram_onboarding_lock:
|
||||
ws._telegram_onboarding_pairings.clear()
|
||||
|
||||
def fake_request(method, path, *, body=None, bearer_token=None):
|
||||
return {
|
||||
"pairing_id": "pair-cancel",
|
||||
"poll_token": "poll-secret",
|
||||
"suggested_username": "hermes_pair_cancel_bot",
|
||||
"deep_link": "https://t.me/newbot/HermesSetupBot/hermes_pair_cancel_bot",
|
||||
"qr_payload": "https://t.me/newbot/HermesSetupBot/hermes_pair_cancel_bot",
|
||||
"expires_at": "2027-05-18T00:00:00.000Z",
|
||||
}
|
||||
|
||||
monkeypatch.setattr(ws, "_telegram_onboarding_request_sync", fake_request)
|
||||
|
||||
start = self.client.post("/api/messaging/telegram/onboarding/start", json={})
|
||||
assert start.status_code == 200
|
||||
|
||||
cancel = self.client.delete("/api/messaging/telegram/onboarding/pair-cancel")
|
||||
assert cancel.status_code == 200
|
||||
|
||||
status = self.client.get("/api/messaging/telegram/onboarding/pair-cancel")
|
||||
assert status.status_code == 404
|
||||
|
||||
def test_session_token_endpoint_removed(self):
|
||||
"""GET /api/auth/session-token should no longer exist (token injected via HTML)."""
|
||||
resp = self.client.get("/api/auth/session-token")
|
||||
@@ -3985,4 +4136,3 @@ class TestValidateProviderCredential:
|
||||
def test_empty_value_rejected(self):
|
||||
data = self._post("OPENAI_API_KEY", " ").json()
|
||||
assert data["ok"] is False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user