aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/tests')
-rw-r--r--packages/meshbay-hub/tests/test_hub_api.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/packages/meshbay-hub/tests/test_hub_api.py b/packages/meshbay-hub/tests/test_hub_api.py
index 327158f..a9c97a3 100644
--- a/packages/meshbay-hub/tests/test_hub_api.py
+++ b/packages/meshbay-hub/tests/test_hub_api.py
@@ -483,6 +483,76 @@ async def test_password_rehash_on_login(client, app):
assert r.status_code == 200
+# ── WebRTC signaling (9.2) ──────────────────────────────────────────────────
+
+@pytest.mark.asyncio
+async def test_webrtc_offer_no_node(client):
+ """WebRTC offer to a non-connected node returns 404."""
+ pk_ed, pk_x, _ = _gen_user_keys()
+ await client.post("/v1/users/register", json={
+ "username": "sig_user", "email": "sig@x.com", "password": "sigpass99",
+ "pk_user_ed25519": pk_ed, "pk_user_x25519": pk_x})
+ r = await client.post("/v1/users/login", json={
+ "username": "sig_user", "password": "sigpass99"})
+ token = r.json()["access_token"]
+
+ r = await client.post("/v1/nodes/fake-node-id/webrtc/offer",
+ json={"sdp": "v=0\r\n...", "ice_candidates": []},
+ headers={"Authorization": f"Bearer {token}"})
+ assert r.status_code == 404
+ assert "not connected" in r.json()["detail"].lower()
+
+
+@pytest.mark.asyncio
+async def test_webrtc_signaling_roundtrip(client, app):
+ """WebRTC signaling: offer relayed to node via WS, answer returned to browser."""
+ import asyncio
+ import json
+
+ pk_ed, pk_x, _ = _gen_user_keys()
+ await client.post("/v1/users/register", json={
+ "username": "sig_user2", "email": "sig2@x.com", "password": "sigpass99",
+ "pk_user_ed25519": pk_ed, "pk_user_x25519": pk_x})
+ r = await client.post("/v1/users/login", json={
+ "username": "sig_user2", "password": "sigpass99"})
+ token = r.json()["access_token"]
+
+ from meshbay_hub.api.revocation import _connected_nodes
+ from meshbay_hub.api.signaling import handle_webrtc_answer
+
+ class FakeWS:
+ def __init__(self):
+ self.sent = []
+
+ async def send_text(self, text):
+ self.sent.append(json.loads(text))
+ msg = self.sent[-1]
+ if msg.get("type") == "webrtc_offer":
+ await asyncio.sleep(0.01)
+ handle_webrtc_answer({
+ "type": "webrtc_answer",
+ "peer_id": msg["peer_id"],
+ "sdp": "v=0\r\nanswer-sdp",
+ "ice_candidates": [{"candidate": "test"}],
+ })
+
+ fake_ws = FakeWS()
+ node_id = "test-node-sig"
+ _connected_nodes[node_id] = fake_ws
+
+ try:
+ r = await client.post(f"/v1/nodes/{node_id}/webrtc/offer",
+ json={"sdp": "v=0\r\noffer-sdp", "ice_candidates": []},
+ headers={"Authorization": f"Bearer {token}"})
+ assert r.status_code == 200
+ data = r.json()
+ assert "answer-sdp" in data["sdp"]
+ assert len(data["ice_candidates"]) == 1
+ assert "peer_id" in data
+ finally:
+ _connected_nodes.pop(node_id, None)
+
+
# ── IP log cleanup (8.9) ────────────────────────────────────────────────────
@pytest.mark.asyncio