diff options
Diffstat (limited to 'packages/meshbay-hub/tests')
31 files changed, 89 insertions, 104 deletions
diff --git a/packages/meshbay-hub/tests/conftest.py b/packages/meshbay-hub/tests/conftest.py index bf94464..bb0ed28 100644 --- a/packages/meshbay-hub/tests/conftest.py +++ b/packages/meshbay-hub/tests/conftest.py @@ -1,12 +1,12 @@ """Shared pytest fixtures for hub tests.""" import os +from pathlib import Path + import pytest import pytest_asyncio -from pathlib import Path -from unittest.mock import AsyncMock -from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey # Force SQLite in-memory for all hub tests os.environ.setdefault("MESHBAY_DATABASE_URL", "sqlite+aiosqlite:///:memory:") @@ -28,7 +28,13 @@ def hub_key_path(tmp_path_factory) -> Path: @pytest.fixture def hub_config(hub_key_path, tmp_path): - from meshbay_hub.config import HubConfig, DatabaseConfig, ServerConfig, HubIdentityConfig, JWTConfig + from meshbay_hub.config import ( + DatabaseConfig, + HubConfig, + HubIdentityConfig, + JWTConfig, + ServerConfig, + ) cfg = HubConfig( db=DatabaseConfig(url="sqlite+aiosqlite:///:memory:"), server=ServerConfig(host="127.0.0.1", port=8000), diff --git a/packages/meshbay-hub/tests/harness/chat_send_probe.py b/packages/meshbay-hub/tests/harness/chat_send_probe.py index b6dd957..d343c50 100644 --- a/packages/meshbay-hub/tests/harness/chat_send_probe.py +++ b/packages/meshbay-hub/tests/harness/chat_send_probe.py @@ -96,7 +96,6 @@ def _page() -> str: the page built itself would prove only that the page agrees with the page. """ import msgpack # noqa: F401 (imported for the failure it gives if absent) - from meshbay_common.groupbox import PURPOSE_CHAT_KEYS, seal sealed = seal(GEK, PURPOSE_CHAT_KEYS, "chat_keys_resp", GROUP_ID, diff --git a/packages/meshbay-hub/tests/test_account_deletion.py b/packages/meshbay-hub/tests/test_account_deletion.py index 3d3fee4..2653f0d 100644 --- a/packages/meshbay-hub/tests/test_account_deletion.py +++ b/packages/meshbay-hub/tests/test_account_deletion.py @@ -12,9 +12,8 @@ command. import hashlib import pytest -from sqlalchemy import select - from meshbay_hub.db.models import GroupMember, Notification, RefreshToken, User +from sqlalchemy import select def _auth_key(password: str, username: str) -> str: diff --git a/packages/meshbay-hub/tests/test_account_pinning.py b/packages/meshbay-hub/tests/test_account_pinning.py index 192bd25..a1419c3 100644 --- a/packages/meshbay-hub/tests/test_account_pinning.py +++ b/packages/meshbay-hub/tests/test_account_pinning.py @@ -23,7 +23,6 @@ from pathlib import Path import pytest from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey - from meshbay_common.device import device_add_transcript STATIC = (Path(__file__).resolve().parents[1] diff --git a/packages/meshbay-hub/tests/test_admin_views.py b/packages/meshbay-hub/tests/test_admin_views.py index 5017b76..da2d3c9 100644 --- a/packages/meshbay-hub/tests/test_admin_views.py +++ b/packages/meshbay-hub/tests/test_admin_views.py @@ -11,9 +11,8 @@ import base64 import hashlib import pytest -from sqlalchemy import select - from meshbay_hub.db.models import User +from sqlalchemy import select def _auth_key(password: str, username: str) -> str: @@ -109,9 +108,8 @@ async def test_a_node_is_recorded_at_the_address_it_announced_from( import base64 import time - from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives import serialization - + from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from meshbay_hub.db.models import Node admin = await _admin(client, db_session, "root4_test") diff --git a/packages/meshbay-hub/tests/test_asset_versioning.py b/packages/meshbay-hub/tests/test_asset_versioning.py index 0c93f5a..aa2dc6d 100644 --- a/packages/meshbay-hub/tests/test_asset_versioning.py +++ b/packages/meshbay-hub/tests/test_asset_versioning.py @@ -22,7 +22,6 @@ import re import pytest from fastapi.testclient import TestClient - from meshbay_hub.api.webapp import ASSET_V, STATIC_DIR, _asset_version from meshbay_hub.app import create_app diff --git a/packages/meshbay-hub/tests/test_availability_between_members.py b/packages/meshbay-hub/tests/test_availability_between_members.py index 2be7c03..4f5cbfb 100644 --- a/packages/meshbay-hub/tests/test_availability_between_members.py +++ b/packages/meshbay-hub/tests/test_availability_between_members.py @@ -24,7 +24,6 @@ import time import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey - from meshbay_common.crypto import pk_to_b64 @@ -158,8 +157,7 @@ async def test_one_node_cannot_spend_the_hubs_database_on_notifications(): without backpressure. The budget is what stops one group's node from costing every other group on the instance. """ - from meshbay_hub.api.revocation import ( - NOTIFY_BURST, _notify_budget, _notify_window) + from meshbay_hub.api.revocation import NOTIFY_BURST, _notify_budget, _notify_window node = "budget-node" _notify_window.pop(node, None) @@ -265,8 +263,7 @@ def test_a_node_cannot_answer_an_offer_it_was_never_sent(): """ import asyncio - from meshbay_hub.api.signaling import ( - _answer_owner, _webrtc_answers, handle_webrtc_answer) + from meshbay_hub.api.signaling import _answer_owner, _webrtc_answers, handle_webrtc_answer loop = asyncio.new_event_loop() try: @@ -657,6 +654,7 @@ async def test_a_member_still_reaches_the_node_they_share_a_group_with(client): class _AnsweringWS: async def send_text(self, text): import json as _json + from meshbay_hub.api.signaling import handle_webrtc_answer msg = _json.loads(text) answered.append(msg) diff --git a/packages/meshbay-hub/tests/test_captcha_host_check.py b/packages/meshbay-hub/tests/test_captcha_host_check.py index 68cad34..778009f 100644 --- a/packages/meshbay-hub/tests/test_captcha_host_check.py +++ b/packages/meshbay-hub/tests/test_captcha_host_check.py @@ -31,12 +31,10 @@ TOML list is a typo far more often than an intention. import json import pytest - from meshbay_hub.captcha import verify_captcha from meshbay_hub.config import CaptchaConfig, load_config - class _Resp: def __init__(self, payload): self._payload = payload diff --git a/packages/meshbay-hub/tests/test_device_auth.py b/packages/meshbay-hub/tests/test_device_auth.py index e899f12..f9b172e 100644 --- a/packages/meshbay-hub/tests/test_device_auth.py +++ b/packages/meshbay-hub/tests/test_device_auth.py @@ -21,9 +21,7 @@ stopped being true. import base64 import time -import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey - from meshbay_common.crypto import pk_to_b64 diff --git a/packages/meshbay-hub/tests/test_group_hosting.py b/packages/meshbay-hub/tests/test_group_hosting.py index c571771..c6111f2 100644 --- a/packages/meshbay-hub/tests/test_group_hosting.py +++ b/packages/meshbay-hub/tests/test_group_hosting.py @@ -14,13 +14,12 @@ deleted every group during a hub restart. import base64 import hashlib -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta import pytest -from sqlalchemy import select - from meshbay_hub.db.models import Group, GroupMember from meshbay_hub.tasks.cleanup import find_unhosted_groups, prune_unhosted_groups +from sqlalchemy import select def _auth_key(password: str, username: str) -> str: @@ -49,7 +48,7 @@ async def _group(client, owner, name, visibility="private", join_policy=None): async def _mark_hosted(db_session, group_id, when=None): g = await db_session.get(Group, group_id) - g.hosted_at = when or datetime.now(timezone.utc) + g.hosted_at = when or datetime.now(UTC) await db_session.commit() @@ -134,7 +133,7 @@ async def test_an_unhosted_group_past_the_grace_period_is_collected(client, db_s gid = (await _group(client, owner, "abandoned")).json()["group_id"] g = await db_session.get(Group, gid) - g.created_at = datetime.now(timezone.utc) - timedelta(days=8) + g.created_at = datetime.now(UTC) - timedelta(days=8) await db_session.commit() gone = await prune_unhosted_groups(db_session) @@ -149,8 +148,8 @@ async def test_an_old_group_that_was_hosted_is_never_collected(client, db_sessio gid = (await _group(client, owner, "long-lived")).json()["group_id"] g = await db_session.get(Group, gid) - g.created_at = datetime.now(timezone.utc) - timedelta(days=400) - g.hosted_at = datetime.now(timezone.utc) - timedelta(days=399) + g.created_at = datetime.now(UTC) - timedelta(days=400) + g.hosted_at = datetime.now(UTC) - timedelta(days=399) await db_session.commit() assert await find_unhosted_groups(db_session) == [] @@ -161,7 +160,7 @@ async def test_dry_run_reports_without_deleting(client, db_session): owner = await _user(client, "reaper4_test") gid = (await _group(client, owner, "still-here")).json()["group_id"] g = await db_session.get(Group, gid) - g.created_at = datetime.now(timezone.utc) - timedelta(days=30) + g.created_at = datetime.now(UTC) - timedelta(days=30) await db_session.commit() gone = await prune_unhosted_groups(db_session, dry_run=True) @@ -178,7 +177,7 @@ async def test_collecting_a_group_takes_its_memberships_with_it(client, db_sessi await client.post(f"/v1/groups/{gid}/members/tagalong", json={}, headers=owner) g = await db_session.get(Group, gid) - g.created_at = datetime.now(timezone.utc) - timedelta(days=9) + g.created_at = datetime.now(UTC) - timedelta(days=9) await db_session.commit() await prune_unhosted_groups(db_session) @@ -247,7 +246,7 @@ async def test_the_stamp_is_not_moved_by_a_later_reconnection(client, db_session owner = await _user(client, "stamped2") gid = (await _group(client, owner, "steady")).json()["group_id"] - first = datetime.now(timezone.utc) - timedelta(days=30) + first = datetime.now(UTC) - timedelta(days=30) await _mark_hosted([gid]) g = await db_session.get(Group, gid) g.hosted_at = first @@ -259,7 +258,7 @@ async def test_the_stamp_is_not_moved_by_a_later_reconnection(client, db_session await db_session.refresh(g) # SQLite hands back a naive datetime where PostgreSQL keeps the offset, so # the comparison is made on common ground rather than on the driver. - stored = g.hosted_at.replace(tzinfo=timezone.utc) if g.hosted_at.tzinfo is None \ + stored = g.hosted_at.replace(tzinfo=UTC) if g.hosted_at.tzinfo is None \ else g.hosted_at assert abs((stored - first).total_seconds()) < 1, "the stamp moved" diff --git a/packages/meshbay-hub/tests/test_group_leave_and_quota.py b/packages/meshbay-hub/tests/test_group_leave_and_quota.py index 4431f53..8af830d 100644 --- a/packages/meshbay-hub/tests/test_group_leave_and_quota.py +++ b/packages/meshbay-hub/tests/test_group_leave_and_quota.py @@ -14,13 +14,12 @@ removes them, and whoever left still holds the group key they were served. import base64 import hashlib -from datetime import datetime, timezone +from datetime import UTC, datetime import pytest -from sqlalchemy import select - from meshbay_hub.api.groups import MAX_PUBLIC_GROUPS from meshbay_hub.db.models import Group, GroupMember, User +from sqlalchemy import select def _auth_key(password: str, username: str) -> str: @@ -61,7 +60,7 @@ async def test_a_member_can_leave(client, db_session): # Marked hosted, or the member would not see the group in the first place # and the assertion below would hold whether or not leaving worked. g = await db_session.get(Group, gid) - g.hosted_at = datetime.now(timezone.utc) + g.hosted_at = datetime.now(UTC) await db_session.commit() before = await client.get("/v1/groups/mine", headers=member) diff --git a/packages/meshbay-hub/tests/test_group_membership.py b/packages/meshbay-hub/tests/test_group_membership.py index 2761595..ad1b3ab 100644 --- a/packages/meshbay-hub/tests/test_group_membership.py +++ b/packages/meshbay-hub/tests/test_group_membership.py @@ -11,10 +11,9 @@ import base64 import hashlib import pytest +from meshbay_hub.db.models import GroupMember, User from sqlalchemy import select -from meshbay_hub.db.models import Group, GroupMember, User - def _auth_key(password: str, username: str) -> str: salt = hashlib.sha256(f"meshbay:auth:v1:{username}".encode()).digest() diff --git a/packages/meshbay-hub/tests/test_group_purge.py b/packages/meshbay-hub/tests/test_group_purge.py index 0611dba..e729297 100644 --- a/packages/meshbay-hub/tests/test_group_purge.py +++ b/packages/meshbay-hub/tests/test_group_purge.py @@ -21,13 +21,18 @@ from datetime import UTC, datetime, timedelta import jwt import pytest -from sqlalchemy import delete, func, select, text -from sqlalchemy.exc import IntegrityError - from meshbay_hub.db.models import ( - ContentReport, EmailVerification, Group, GroupMember, IPLog, Notification, User, + ContentReport, + EmailVerification, + Group, + GroupMember, + IPLog, + Notification, + User, ) from meshbay_hub.db.purge import _referencing +from sqlalchemy import delete, func, select, text +from sqlalchemy.exc import IntegrityError SEEDED = {"group_members", "notifications", "email_verifications", "content_reports"} diff --git a/packages/meshbay-hub/tests/test_groups_self_service.py b/packages/meshbay-hub/tests/test_groups_self_service.py index f9346c1..a3a8f2d 100644 --- a/packages/meshbay-hub/tests/test_groups_self_service.py +++ b/packages/meshbay-hub/tests/test_groups_self_service.py @@ -1,9 +1,10 @@ """Integration tests for group self-service: create, join, members.""" +from datetime import UTC + import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey - from meshbay_common.crypto import pk_to_b64 @@ -43,10 +44,11 @@ async def _create_group(client, token, name="test-group", visibility="public", async def _mark_hosted(db_session, *group_ids): """Pretend a node announced these groups, as /v1/nodes/ws would.""" - from datetime import datetime, timezone + from datetime import datetime + from meshbay_hub.db.models import Group for gid in group_ids: - (await db_session.get(Group, gid)).hosted_at = datetime.now(timezone.utc) + (await db_session.get(Group, gid)).hosted_at = datetime.now(UTC) await db_session.commit() diff --git a/packages/meshbay-hub/tests/test_hub_api.py b/packages/meshbay-hub/tests/test_hub_api.py index 37e8e4f..9b73701 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}"}) @@ -399,9 +398,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 +434,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 +540,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 +588,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 +760,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 +775,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() diff --git a/packages/meshbay-hub/tests/test_login_lockout.py b/packages/meshbay-hub/tests/test_login_lockout.py index 6f17d98..601edbd 100644 --- a/packages/meshbay-hub/tests/test_login_lockout.py +++ b/packages/meshbay-hub/tests/test_login_lockout.py @@ -18,14 +18,13 @@ is `test_availability_between_members.py`, because it takes two accounts. """ import asyncio -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta import pytest -from sqlalchemy import select, update - from meshbay_hub.api.deps import set_admin_usernames from meshbay_hub.db.models import LoginThrottle from meshbay_hub.login_throttle import _key +from sqlalchemy import select, update RIGHT = "r" * 44 WRONG = "w" * 44 @@ -94,7 +93,7 @@ async def test_a_lockout_ends_when_its_window_does(client, db_session): await db_session.execute( update(LoginThrottle).where(LoginThrottle.key == _key("dave_test")) - .values(last_failure_at=datetime.now(timezone.utc) - timedelta(minutes=61))) + .values(last_failure_at=datetime.now(UTC) - timedelta(minutes=61))) await db_session.commit() assert (await _login(client, "dave_test", RIGHT)).status_code == 200 @@ -106,7 +105,7 @@ async def test_old_failures_do_not_carry_into_a_new_window(client, db_session): await _fail(client, "erin_test", 3) await db_session.execute( update(LoginThrottle).where(LoginThrottle.key == _key("erin_test")) - .values(last_failure_at=datetime.now(timezone.utc) - timedelta(minutes=61))) + .values(last_failure_at=datetime.now(UTC) - timedelta(minutes=61))) await db_session.commit() # One stale window of three, then one fresh failure: a count of one, not four. diff --git a/packages/meshbay-hub/tests/test_mail_is_not_a_relay.py b/packages/meshbay-hub/tests/test_mail_is_not_a_relay.py index fe6a5ee..a3f9a21 100644 --- a/packages/meshbay-hub/tests/test_mail_is_not_a_relay.py +++ b/packages/meshbay-hub/tests/test_mail_is_not_a_relay.py @@ -28,7 +28,6 @@ import base64 import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey - from meshbay_common.crypto import pk_to_b64 from meshbay_hub import mail as mail_mod from meshbay_hub.api import users as users_mod @@ -316,9 +315,8 @@ async def _signed_in(client, db_session, username: str, email: str) -> dict: genuinely `pending` here, exactly as it would be in production, and a pending account cannot log in. """ - from sqlalchemy import select, update - from meshbay_hub.db.models import User + from sqlalchemy import select, update r = await _register(client, username, email) assert r.status_code == 201, r.text @@ -406,9 +404,8 @@ async def test_the_delay_survives_the_verification_row_being_deleted( json={"email": "c-first@example.test"}) assert r.status_code == 200, r.text - from sqlalchemy import delete - from meshbay_hub.db.models import EmailVerification + from sqlalchemy import delete await db_session.execute(delete(EmailVerification)) await db_session.commit() @@ -421,9 +418,8 @@ async def test_the_delay_survives_the_verification_row_being_deleted( # ── The operator's controls ────────────────────────────────────────────────── async def _admin(client, db_session, username: str) -> dict: - from sqlalchemy import update - from meshbay_hub.db.models import User + from sqlalchemy import update headers = await _signed_in(client, db_session, username, f"{username}@example.test") @@ -491,9 +487,8 @@ async def test_an_unknown_mail_setting_is_refused(client, db_session): @pytest.mark.asyncio async def test_a_moderator_may_read_the_bounds_but_not_change_them( client, db_session): - from sqlalchemy import update - from meshbay_hub.db.models import User + from sqlalchemy import update headers = await _signed_in(client, db_session, "mailmod_test", "mailmod@example.test") diff --git a/packages/meshbay-hub/tests/test_migrations_reach_head.py b/packages/meshbay-hub/tests/test_migrations_reach_head.py index 13c5590..7f0d5df 100644 --- a/packages/meshbay-hub/tests/test_migrations_reach_head.py +++ b/packages/meshbay-hub/tests/test_migrations_reach_head.py @@ -30,9 +30,8 @@ from pathlib import Path import pytest from alembic import command from alembic.config import Config -from sqlalchemy import create_engine, inspect - from meshbay_hub.db.models import Base +from sqlalchemy import create_engine, inspect HUB = Path(__file__).resolve().parents[1] diff --git a/packages/meshbay-hub/tests/test_node_auth.py b/packages/meshbay-hub/tests/test_node_auth.py index 4137932..09816de 100644 --- a/packages/meshbay-hub/tests/test_node_auth.py +++ b/packages/meshbay-hub/tests/test_node_auth.py @@ -8,9 +8,9 @@ import base64 import time import pytest +from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey -from cryptography.hazmat.primitives import serialization def _gen_ed25519(): diff --git a/packages/meshbay-hub/tests/test_node_ws_auth.py b/packages/meshbay-hub/tests/test_node_ws_auth.py index f3ac3a2..7d96851 100644 --- a/packages/meshbay-hub/tests/test_node_ws_auth.py +++ b/packages/meshbay-hub/tests/test_node_ws_auth.py @@ -16,7 +16,6 @@ import base64 import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey - from meshbay_common.crypto import pk_to_b64 @@ -405,7 +404,10 @@ async def test_empty_node_cannot_shadow_another_members_group(client): source for that group, because it is the one clients would reach first. """ from meshbay_hub.api.revocation import ( - _authorize_node_ws, _node_groups, get_online_nodes_for_group) + _authorize_node_ws, + _node_groups, + get_online_nodes_for_group, + ) host = await _make_user(client, "hoster_test") guest = await _make_user(client, "guest_test") diff --git a/packages/meshbay-hub/tests/test_notification_dismissal.py b/packages/meshbay-hub/tests/test_notification_dismissal.py index 1c9c7b3..d498b4d 100644 --- a/packages/meshbay-hub/tests/test_notification_dismissal.py +++ b/packages/meshbay-hub/tests/test_notification_dismissal.py @@ -32,7 +32,6 @@ from pathlib import Path import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey - from meshbay_common.crypto import pk_to_b64 from meshbay_hub.api.deps import set_admin_usernames diff --git a/packages/meshbay-hub/tests/test_notifications.py b/packages/meshbay-hub/tests/test_notifications.py index 02aca1c..b87e1d5 100644 --- a/packages/meshbay-hub/tests/test_notifications.py +++ b/packages/meshbay-hub/tests/test_notifications.py @@ -3,7 +3,6 @@ import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey - from meshbay_common.crypto import pk_to_b64 from meshbay_hub.api.deps import set_admin_usernames diff --git a/packages/meshbay-hub/tests/test_notifications_behaviour.py b/packages/meshbay-hub/tests/test_notifications_behaviour.py index a247508..67fd99e 100644 --- a/packages/meshbay-hub/tests/test_notifications_behaviour.py +++ b/packages/meshbay-hub/tests/test_notifications_behaviour.py @@ -7,13 +7,12 @@ browser's localStorage and nothing read it), and there was no way to clear the list. """ -import hashlib import base64 +import hashlib import pytest -from sqlalchemy import select - from meshbay_hub.db.models import GroupMember, Notification, User +from sqlalchemy import select def _auth_key(password: str, username: str) -> str: diff --git a/packages/meshbay-hub/tests/test_packaging_hub_unit.py b/packages/meshbay-hub/tests/test_packaging_hub_unit.py index 7d8f5d2..e29164e 100644 --- a/packages/meshbay-hub/tests/test_packaging_hub_unit.py +++ b/packages/meshbay-hub/tests/test_packaging_hub_unit.py @@ -85,7 +85,6 @@ def test_the_command_resolves_from_the_installed_package_not_the_checkout(): """Derived from `meshbay_hub.__file__`, so it is correct in a venv, an RPM and a checkout alike — which is the whole point of not writing it down.""" import meshbay_hub - from meshbay_hub.daemon import migrations_dir assert migrations_dir() == ( diff --git a/packages/meshbay-hub/tests/test_password_change.py b/packages/meshbay-hub/tests/test_password_change.py index b2fe586..bfe0c97 100644 --- a/packages/meshbay-hub/tests/test_password_change.py +++ b/packages/meshbay-hub/tests/test_password_change.py @@ -11,9 +11,8 @@ import base64 import hashlib import pytest -from sqlalchemy import select - from meshbay_hub.db.models import IPLog, RefreshToken, User +from sqlalchemy import select def _auth_key(password: str, username: str) -> str: diff --git a/packages/meshbay-hub/tests/test_password_reset.py b/packages/meshbay-hub/tests/test_password_reset.py index 823807c..b07f77c 100644 --- a/packages/meshbay-hub/tests/test_password_reset.py +++ b/packages/meshbay-hub/tests/test_password_reset.py @@ -9,7 +9,7 @@ the recovery key and is not exercised here. import base64 import time -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey @@ -126,7 +126,7 @@ async def test_an_expired_code_is_refused(client, db_session): select(User.id).where(User.username == "carol_test"))).scalar_one() row = (await db_session.execute(select(EmailVerification).where( EmailVerification.user_id == uid))).scalars().one() - row.expires_at = datetime.now(timezone.utc) - timedelta(minutes=1) + row.expires_at = datetime.now(UTC) - timedelta(minutes=1) await db_session.commit() r = await client.post("/v1/users/password/reset", json={ diff --git a/packages/meshbay-hub/tests/test_public_groups_toggle.py b/packages/meshbay-hub/tests/test_public_groups_toggle.py index 96e3383..dbc6a38 100644 --- a/packages/meshbay-hub/tests/test_public_groups_toggle.py +++ b/packages/meshbay-hub/tests/test_public_groups_toggle.py @@ -17,7 +17,7 @@ and their access — plan A, not a purge. import base64 import hashlib -from datetime import datetime, timezone +from datetime import UTC, datetime import pytest from meshbay_hub.api.deps import set_admin_usernames @@ -61,7 +61,7 @@ async def _create_public(client, owner, name): async def _mark_hosted(db_session, *group_ids): """Pretend a node announced these groups, as /v1/nodes/ws would.""" for gid in group_ids: - (await db_session.get(Group, gid)).hosted_at = datetime.now(timezone.utc) + (await db_session.get(Group, gid)).hosted_at = datetime.now(UTC) await db_session.commit() diff --git a/packages/meshbay-hub/tests/test_revocation.py b/packages/meshbay-hub/tests/test_revocation.py index ad9caf4..e2ca5e7 100644 --- a/packages/meshbay-hub/tests/test_revocation.py +++ b/packages/meshbay-hub/tests/test_revocation.py @@ -1,11 +1,9 @@ """Tests for revocation — admin endpoint + token signing.""" -import time -import pytest import jwt +import pytest from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey - from meshbay_common.crypto import pk_to_b64 from meshbay_hub.api.deps import set_admin_usernames diff --git a/packages/meshbay-hub/tests/test_session_lifetime.py b/packages/meshbay-hub/tests/test_session_lifetime.py index af73767..3a1f47a 100644 --- a/packages/meshbay-hub/tests/test_session_lifetime.py +++ b/packages/meshbay-hub/tests/test_session_lifetime.py @@ -6,13 +6,12 @@ maximum — plus a sign-out the hub honours and "sign out everywhere". The browser half is `test_browser_idle_signout.py`; this is the hub's. """ -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta import pytest -from sqlalchemy import select, update - from meshbay_hub.api.deps import set_admin_usernames from meshbay_hub.db.models import RefreshToken, User +from sqlalchemy import select, update AUTH_KEY = "s" * 44 @@ -40,7 +39,7 @@ async def _refresh(client, token): def _aware(dt): - return dt if dt.tzinfo else dt.replace(tzinfo=timezone.utc) + return dt if dt.tzinfo else dt.replace(tzinfo=UTC) async def _expiry(db_session, username): @@ -66,7 +65,7 @@ async def test_the_defaults_are_in_the_panel_and_the_browser_delay_is_public(cli async def test_a_refresh_token_lasts_the_idle_window(client, db_session): await _register(client, "idle_window") await _login(client, "idle_window") - left = await _expiry(db_session, "idle_window") - datetime.now(timezone.utc) + left = await _expiry(db_session, "idle_window") - datetime.now(UTC) assert timedelta(hours=23, minutes=58) < left <= timedelta(hours=24) @@ -78,7 +77,7 @@ async def test_the_idle_window_never_undercuts_the_access_token(client, db_sessi json={"session": {"refresh_idle_hours": 1}}) await _register(client, "short_idle") await _login(client, "short_idle") - left = await _expiry(db_session, "short_idle") - datetime.now(timezone.utc) + left = await _expiry(db_session, "short_idle") - datetime.now(UTC) # The test hub's access token lives 3600 s; the floor is that plus an hour. assert left > timedelta(hours=1, minutes=58) @@ -98,7 +97,7 @@ async def test_no_session_renews_past_its_maximum(client, db_session): select(User.id).where(User.username == "long_session"))).scalar_one() await db_session.execute( update(RefreshToken).where(RefreshToken.user_id == uid) - .values(created_at=datetime.now(timezone.utc) - timedelta(hours=721))) + .values(created_at=datetime.now(UTC) - timedelta(hours=721))) await db_session.commit() r = await _refresh(client, current) diff --git a/packages/meshbay-hub/tests/test_session_renewal.py b/packages/meshbay-hub/tests/test_session_renewal.py index 5d4bcfd..7b8c108 100644 --- a/packages/meshbay-hub/tests/test_session_renewal.py +++ b/packages/meshbay-hub/tests/test_session_renewal.py @@ -26,9 +26,9 @@ broken client. """ import json +import re import shutil import subprocess -import re from pathlib import Path import pytest diff --git a/packages/meshbay-hub/tests/test_table_rows_measured.py b/packages/meshbay-hub/tests/test_table_rows_measured.py index 60ec878..f203624 100644 --- a/packages/meshbay-hub/tests/test_table_rows_measured.py +++ b/packages/meshbay-hub/tests/test_table_rows_measured.py @@ -16,11 +16,10 @@ rectangles show it does not — which is what this file is for. """ import json +import shutil import subprocess from pathlib import Path -import shutil - import pytest HARNESS = Path(__file__).parent / "harness" / "layout_probe.py" |