summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/test_hub_api.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-19 17:58:05 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-19 17:58:05 +0200
commit1ec316035ce9aa656dd18a05889856bce9e3aba3 (patch)
treeb50e97f50d485ef2a88ce36fe4d7511d9fe3e288 /packages/meshbay-hub/tests/test_hub_api.py
parent171a3e175889ce30f201fcdf5c4632f480344ae6 (diff)
parent95dd3dc13aecec85c2fd72410cd4d1f4ed582dfa (diff)
downloadmeshbay-1ec316035ce9aa656dd18a05889856bce9e3aba3.tar.gz
Merge origin/main: the tree-wide ruff pass beside the Music reconnect work
Diffstat (limited to 'packages/meshbay-hub/tests/test_hub_api.py')
-rw-r--r--packages/meshbay-hub/tests/test_hub_api.py45
1 files changed, 27 insertions, 18 deletions
diff --git a/packages/meshbay-hub/tests/test_hub_api.py b/packages/meshbay-hub/tests/test_hub_api.py
index 37e8e4f..2afd27b 100644
--- a/packages/meshbay-hub/tests/test_hub_api.py
+++ b/packages/meshbay-hub/tests/test_hub_api.py
@@ -3,13 +3,11 @@ Integration tests for the Hub API.
Uses SQLite in-memory + httpx.AsyncClient — no PostgreSQL, no network.
"""
-import base64
+from datetime import UTC
+
import pytest
-import pytest_asyncio
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
-from cryptography.hazmat.primitives import serialization
-
from meshbay_common.crypto import pk_to_b64
from meshbay_hub.api.deps import set_admin_usernames
@@ -32,7 +30,8 @@ async def _announce_signed(client, token: str) -> tuple[str, str]:
The node key is independent of the user's identity key, so this mints a fresh
one and signs the domain-separated announce message with it.
"""
- import base64 as _b64, time as _t
+ import base64 as _b64
+ import time as _t
me = await client.get("/v1/users/me",
headers={"Authorization": f"Bearer {token}"})
@@ -261,7 +260,9 @@ async def test_group_member_add(client):
"pk_user_ed25519": pk_ed, "pk_user_x25519": pk_x})
alice_token = (await client.post("/v1/users/login",
- json={"username": "alice2_test", "password": "alicepass99"})).json()["access_token"]
+ json={"username": "alice2_test",
+ "password": "alicepass99"})
+ ).json()["access_token"]
a_hdrs = {"Authorization": f"Bearer {alice_token}"}
@@ -299,9 +300,13 @@ async def test_non_admin_cannot_add_member(client):
"pk_user_ed25519": pk_ed, "pk_user_x25519": pk_x})
charlie_token = (await client.post("/v1/users/login",
- json={"username": "charlie_test", "password": "charliepass"})).json()["access_token"]
+ json={"username": "charlie_test",
+ "password": "charliepass"})
+ ).json()["access_token"]
dan_token = (await client.post("/v1/users/login",
- json={"username": "dan_test", "password": "danpass1234"})).json()["access_token"]
+ json={"username": "dan_test",
+ "password": "danpass1234"})
+ ).json()["access_token"]
r = await client.post("/v1/groups", json={"name": "charlies-group"},
headers={"Authorization": f"Bearer {charlie_token}"})
@@ -339,7 +344,9 @@ async def test_jwt_contains_groups_claim(client):
# Alice creates a group and adds Bob
alice_token = (await client.post("/v1/users/login",
- json={"username": "grp_alice", "password": "alicepass99"})).json()["access_token"]
+ json={"username": "grp_alice",
+ "password": "alicepass99"})
+ ).json()["access_token"]
r = await client.post("/v1/groups", json={"name": "testgroup"},
headers={"Authorization": f"Bearer {alice_token}"})
group_id = r.json()["group_id"]
@@ -399,9 +406,10 @@ async def test_my_groups(client, db_session):
# A group no node has announced is shown to its owner only — a member would
# otherwise see a name they cannot open. Stamped here so the rest of this
# test is about membership, which is what it was written for.
- from datetime import datetime, timezone
+ from datetime import datetime
+
from meshbay_hub.db.models import Group
- (await db_session.get(Group, group_id)).hosted_at = datetime.now(timezone.utc)
+ (await db_session.get(Group, group_id)).hosted_at = datetime.now(UTC)
await db_session.commit()
# Re-login to get fresh token with group claims
@@ -434,7 +442,6 @@ async def test_my_groups(client, db_session):
@pytest.mark.asyncio
async def test_group_online_nodes(client):
"""GET /v1/groups/{id}/nodes returns online nodes serving the group."""
- import json
from meshbay_hub.api.revocation import _connected_nodes, _node_groups
pk_ed, pk_x, _ = _gen_user_keys()
@@ -541,7 +548,7 @@ async def test_admin_can_revoke(client):
@pytest.mark.asyncio
async def test_email_encrypted_at_rest(client):
"""Email stored in DB must not contain plaintext address."""
- from meshbay_hub.auth import encrypt_email, decrypt_email
+ from meshbay_hub.auth import decrypt_email, encrypt_email
encrypted = encrypt_email("test@example.com")
assert "@" not in encrypted
assert decrypt_email(encrypted) == "test@example.com"
@@ -589,9 +596,10 @@ async def test_password_rehash_on_login(client, app):
user = result.scalar_one()
user.pw_version = 1
# Re-hash with v1 params so verify_password(version=1) succeeds
- from meshbay_hub.auth import _ARGON2_VERSIONS, _ARGON2_KEY_LEN, _ARGON2_LANES
- from cryptography.hazmat.primitives.kdf.argon2 import Argon2id
import os
+
+ from cryptography.hazmat.primitives.kdf.argon2 import Argon2id
+ from meshbay_hub.auth import _ARGON2_KEY_LEN, _ARGON2_LANES, _ARGON2_VERSIONS
salt = os.urandom(16)
params = _ARGON2_VERSIONS[1]
pw_hash = Argon2id(
@@ -760,13 +768,14 @@ async def test_webrtc_signaling_roundtrip(client, app):
@pytest.mark.asyncio
async def test_ip_log_cleanup(app):
"""Old IP log entries are purged by cleanup task."""
- from datetime import datetime, timezone, timedelta
+ from datetime import datetime, timedelta
+
from meshbay_hub.db.engine import get_db
from meshbay_hub.db.models import IPLog
from meshbay_hub.tasks.cleanup import purge_old_ip_logs
async for db in get_db():
- old_ts = datetime.now(timezone.utc) - timedelta(days=400)
+ old_ts = datetime.now(UTC) - timedelta(days=400)
db.add(IPLog(event="test_old", ip_address="1.2.3.4", timestamp=old_ts))
db.add(IPLog(event="test_recent", ip_address="5.6.7.8"))
await db.commit()
@@ -774,7 +783,7 @@ async def test_ip_log_cleanup(app):
deleted = await purge_old_ip_logs(db, retention_days=365)
assert deleted == 1
- from sqlalchemy import select, func
+ from sqlalchemy import func, select
count = (await db.execute(
select(func.count()).where(IPLog.event.in_(["test_old", "test_recent"]))
)).scalar_one()