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/conftest.py14
-rw-r--r--packages/meshbay-hub/tests/harness/boot_guard_probe.py3
-rw-r--r--packages/meshbay-hub/tests/harness/chat_send_probe.py1
-rwxr-xr-xpackages/meshbay-hub/tests/harness/menu_scroll_probe.py3
-rw-r--r--packages/meshbay-hub/tests/harness/music_grid_probe.py6
-rwxr-xr-xpackages/meshbay-hub/tests/harness/music_queue_probe.py3
-rwxr-xr-xpackages/meshbay-hub/tests/harness/playlist_store_probe.py6
-rw-r--r--packages/meshbay-hub/tests/harness/playlist_ui_probe.py12
-rw-r--r--packages/meshbay-hub/tests/test_account_deletion.py3
-rw-r--r--packages/meshbay-hub/tests/test_account_pinning.py1
-rw-r--r--packages/meshbay-hub/tests/test_admin_views.py6
-rw-r--r--packages/meshbay-hub/tests/test_asset_versioning.py1
-rw-r--r--packages/meshbay-hub/tests/test_availability_between_members.py8
-rw-r--r--packages/meshbay-hub/tests/test_captcha_host_check.py2
-rw-r--r--packages/meshbay-hub/tests/test_device_auth.py2
-rw-r--r--packages/meshbay-hub/tests/test_files_drop_upload.py3
-rw-r--r--packages/meshbay-hub/tests/test_group_hosting.py21
-rw-r--r--packages/meshbay-hub/tests/test_group_leave_and_quota.py7
-rw-r--r--packages/meshbay-hub/tests/test_group_membership.py3
-rw-r--r--packages/meshbay-hub/tests/test_group_purge.py13
-rw-r--r--packages/meshbay-hub/tests/test_groups_self_service.py8
-rw-r--r--packages/meshbay-hub/tests/test_hook_ordering.py3
-rw-r--r--packages/meshbay-hub/tests/test_hub_api.py45
-rw-r--r--packages/meshbay-hub/tests/test_layout_measured.py6
-rw-r--r--packages/meshbay-hub/tests/test_locales.py9
-rw-r--r--packages/meshbay-hub/tests/test_login_lockout.py9
-rw-r--r--packages/meshbay-hub/tests/test_mail_is_not_a_relay.py13
-rw-r--r--packages/meshbay-hub/tests/test_memory_ceiling.py6
-rw-r--r--packages/meshbay-hub/tests/test_migrations_reach_head.py3
-rw-r--r--packages/meshbay-hub/tests/test_node_auth.py2
-rw-r--r--packages/meshbay-hub/tests/test_node_ws_auth.py6
-rw-r--r--packages/meshbay-hub/tests/test_notification_dismissal.py1
-rw-r--r--packages/meshbay-hub/tests/test_notifications.py1
-rw-r--r--packages/meshbay-hub/tests/test_notifications_behaviour.py7
-rw-r--r--packages/meshbay-hub/tests/test_packaging_hub_unit.py1
-rw-r--r--packages/meshbay-hub/tests/test_password_change.py3
-rw-r--r--packages/meshbay-hub/tests/test_password_reset.py4
-rw-r--r--packages/meshbay-hub/tests/test_public_groups_toggle.py4
-rw-r--r--packages/meshbay-hub/tests/test_revocation.py4
-rw-r--r--packages/meshbay-hub/tests/test_session_lifetime.py13
-rw-r--r--packages/meshbay-hub/tests/test_session_renewal.py2
-rw-r--r--packages/meshbay-hub/tests/test_table_rows_measured.py3
-rw-r--r--packages/meshbay-hub/tests/test_transfers.py5
43 files changed, 145 insertions, 131 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/boot_guard_probe.py b/packages/meshbay-hub/tests/harness/boot_guard_probe.py
index 01751ba..b4a5e7c 100644
--- a/packages/meshbay-hub/tests/harness/boot_guard_probe.py
+++ b/packages/meshbay-hub/tests/harness/boot_guard_probe.py
@@ -83,7 +83,8 @@ const cases = [];
const post = (o) => fetch('/log', { method: 'POST', body: JSON.stringify(o) });
addEventListener('error', (e) => post({ error: 'page error: ' + (e.message || e) }));
addEventListener('unhandledrejection',
- (e) => post({ error: 'rejection: ' + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason) }));
+ (e) => post({ error: 'rejection: '
+ + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason) }));
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const add = (src) => {
const f = document.createElement('iframe');
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/harness/menu_scroll_probe.py b/packages/meshbay-hub/tests/harness/menu_scroll_probe.py
index 5fb9579..c4d3b87 100755
--- a/packages/meshbay-hub/tests/harness/menu_scroll_probe.py
+++ b/packages/meshbay-hub/tests/harness/menu_scroll_probe.py
@@ -48,7 +48,8 @@ import { Menu } from '/menu.js';
const LOGS = [];
addEventListener('error', (e) => LOGS.push('error: ' + (e.message || e)));
addEventListener('unhandledrejection',
- (e) => LOGS.push('rejection: ' + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason)));
+ (e) => LOGS.push('rejection: '
+ + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason)));
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const frame = () => new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(r)));
diff --git a/packages/meshbay-hub/tests/harness/music_grid_probe.py b/packages/meshbay-hub/tests/harness/music_grid_probe.py
index da73b1f..4f5b0ce 100644
--- a/packages/meshbay-hub/tests/harness/music_grid_probe.py
+++ b/packages/meshbay-hub/tests/harness/music_grid_probe.py
@@ -103,7 +103,8 @@ import { MusicPlayerBar } from '/music-player.js';
const LOGS = [];
addEventListener('error', (e) => LOGS.push('error: ' + (e.message || e)));
addEventListener('unhandledrejection',
- (e) => LOGS.push('rejection: ' + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason)));
+ (e) => LOGS.push('rejection: '
+ + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason)));
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const waitFor = async (sel, tries = 60) => {
@@ -212,7 +213,8 @@ const clickMenu = async (i) => {
const last = rows[rows.length - 1];
const entry = { artist: label, top,
heading: heading ? heading.textContent : null,
- headingH: heading ? Math.round(heading.getBoundingClientRect().height) : null };
+ headingH: heading
+ ? Math.round(heading.getBoundingClientRect().height) : null };
if (last && Math.abs(last.top - top) < 8) last.cells.push(entry);
else rows.push({ top, cells: [entry] });
}
diff --git a/packages/meshbay-hub/tests/harness/music_queue_probe.py b/packages/meshbay-hub/tests/harness/music_queue_probe.py
index 483c093..9be440b 100755
--- a/packages/meshbay-hub/tests/harness/music_queue_probe.py
+++ b/packages/meshbay-hub/tests/harness/music_queue_probe.py
@@ -102,7 +102,8 @@ import { MusicPlayerBar } from '/music-player.js';
const LOGS = [];
addEventListener('error', (e) => LOGS.push('error: ' + (e.message || e)));
addEventListener('unhandledrejection',
- (e) => LOGS.push('rejection: ' + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason)));
+ (e) => LOGS.push('rejection: '
+ + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason)));
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const waitFor = async (sel, tries = 60) => {
diff --git a/packages/meshbay-hub/tests/harness/playlist_store_probe.py b/packages/meshbay-hub/tests/harness/playlist_store_probe.py
index 6421426..9a54a0d 100755
--- a/packages/meshbay-hub/tests/harness/playlist_store_probe.py
+++ b/packages/meshbay-hub/tests/harness/playlist_store_probe.py
@@ -38,7 +38,8 @@ import { MANIFEST_KIND, bodyKind } from '/playlist-merge.js';
const LOGS = [];
addEventListener('error', (e) => LOGS.push('error: ' + (e.message || e)));
addEventListener('unhandledrejection',
- (e) => LOGS.push('rejection: ' + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason)));
+ (e) => LOGS.push('rejection: '
+ + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason)));
const USER = 'user-1';
const steps = [];
@@ -95,7 +96,8 @@ function fakeNode() {
await P.addTracks(USER, P.FAVORITES_ID, [track(9)], 'g1', 'Favoris');
steps.push({ step: 'after editing',
- list: (await P.listPlaylists(USER)).map((p) => ({ id: p.id, name: p.name, count: p.count })) });
+ list: (await P.listPlaylists(USER))
+ .map((p) => ({ id: p.id, name: p.name, count: p.count })) });
steps.push({ step: 'tracks read back',
tracks: (await P.getPlaylistTracks(USER, eveningId)).map((t) => ({
diff --git a/packages/meshbay-hub/tests/harness/playlist_ui_probe.py b/packages/meshbay-hub/tests/harness/playlist_ui_probe.py
index 2defed9..e6f99f7 100644
--- a/packages/meshbay-hub/tests/harness/playlist_ui_probe.py
+++ b/packages/meshbay-hub/tests/harness/playlist_ui_probe.py
@@ -101,7 +101,8 @@ import * as P from '/playlists.js';
const LOGS = [];
addEventListener('error', (e) => LOGS.push('error: ' + (e.message || e)));
addEventListener('unhandledrejection',
- (e) => LOGS.push('rejection: ' + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason)));
+ (e) => LOGS.push('rejection: '
+ + ((e.reason && (e.reason.stack || e.reason.message)) || e.reason)));
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const waitFor = async (sel, tries = 60) => {
@@ -256,7 +257,8 @@ const clickMenu = async (i) => {
open.click();
await waitFor('.music-detail .music-tracklist');
steps.push({ step: 'loaded into the queue',
- play: [...document.querySelectorAll('.music-detail .music-tracklist .music-track-title')]
+ play: [...document.querySelectorAll(
+ '.music-detail .music-tracklist .music-track-title')]
.map((e) => e.textContent) });
document.querySelector('.music-detail .video-close').click();
await sleep(150);
@@ -270,8 +272,10 @@ const clickMenu = async (i) => {
await clickLabel('A2-t2');
await sleep(300);
steps.push({ step: 'track removed',
- lists: (await P.listPlaylists('u1')).map((p) => ({ name: p.name, count: p.count })),
- tracks: (await P.getPlaylistTracks('u1', lists.find((p) => p.name === 'Soirée').id))
+ lists: (await P.listPlaylists('u1'))
+ .map((p) => ({ name: p.name, count: p.count })),
+ tracks: (await P.getPlaylistTracks('u1',
+ lists.find((p) => p.name === 'Soirée').id))
.map((tr) => tr.display_title) });
// 6. Delete it.
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_files_drop_upload.py b/packages/meshbay-hub/tests/test_files_drop_upload.py
index 5dfaf23..fc15c47 100644
--- a/packages/meshbay-hub/tests/test_files_drop_upload.py
+++ b/packages/meshbay-hub/tests/test_files_drop_upload.py
@@ -66,7 +66,8 @@ def test_names_in_a_folder_count_files_folders_and_empty_folders(tmp_path, sourc
{"path": "music/Album", "name": "t.flac"},
{"path": "musicals", "name": "not-here.txt"}]
got = _run(tmp_path, source,
- f"namesIn({json.dumps(entries)}, ['music/Empty', 'music/Album/cd1'], 'music').sort()")
+ f"namesIn({json.dumps(entries)}, "
+ f"['music/Empty', 'music/Album/cd1'], 'music').sort()")
assert got == ["Album", "Empty", "a.mp3"]
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_hook_ordering.py b/packages/meshbay-hub/tests/test_hook_ordering.py
index 3c82bb0..d03cdf5 100644
--- a/packages/meshbay-hub/tests/test_hook_ordering.py
+++ b/packages/meshbay-hub/tests/test_hook_ordering.py
@@ -123,7 +123,8 @@ def test_the_check_would_notice():
# Inject a dependency on `last` into the first declaration's dep array.
end = broken.index("\n }, [", decls[0].start())
close = broken.index("]", end)
- broken = broken[:close] + (", " if broken[end + 7:close].strip() else "") + last + broken[close:]
+ broken = (broken[:close] + (", " if broken[end + 7:close].strip() else "")
+ + last + broken[close:])
declared_at = {m.group(1): m.start() for m in DECL.finditer(broken)}
caught = False
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()
diff --git a/packages/meshbay-hub/tests/test_layout_measured.py b/packages/meshbay-hub/tests/test_layout_measured.py
index a71b6b9..9bf1bde 100644
--- a/packages/meshbay-hub/tests/test_layout_measured.py
+++ b/packages/meshbay-hub/tests/test_layout_measured.py
@@ -178,7 +178,8 @@ GROUPED = textwrap.dedent("""
<button class="transfer-cancel">&#10005;</button>
</div>
<div class="dl-progress"><div class="dl-fill" style="width:42%"></div></div>
- <div class="transfer-meta"><span>210 MB / 493 MB</span><span>3.1 MB/s &middot; 4 min left</span></div>
+ <div class="transfer-meta"><span>210 MB / 493 MB</span>
+ <span>3.1 MB/s &middot; 4 min left</span></div>
</div>
</div>
<div class="transfer-group">
@@ -190,7 +191,8 @@ GROUPED = textwrap.dedent("""
<button class="transfer-cancel">&#10005;</button>
</div>
<div class="dl-progress dl-waiting"></div>
- <div class="transfer-meta"><span>Waiting &mdash; your slots are busy</span><span>1.2 GB</span></div>
+ <div class="transfer-meta"><span>Waiting &mdash; your slots are busy</span>
+ <span>1.2 GB</span></div>
</div>
</div>
</div>
diff --git a/packages/meshbay-hub/tests/test_locales.py b/packages/meshbay-hub/tests/test_locales.py
index 59ea2bf..602d161 100644
--- a/packages/meshbay-hub/tests/test_locales.py
+++ b/packages/meshbay-hub/tests/test_locales.py
@@ -158,7 +158,8 @@ def test_locale_resolution_is_region_aware(tmp_path):
const out = {};
for (const tags of [['pt-BR'], ['pt'], ['zh-CN'], ['zh'], ['fr-CA'],
['de-AT'], ['ru', 'it'], ['ko']]) {
- Object.defineProperty(globalThis, 'navigator', { value: { languages: tags, language: tags[0] }, configurable: true });
+ Object.defineProperty(globalThis, 'navigator',
+ { value: { languages: tags, language: tags[0] }, configurable: true });
delete store.mb_lang;
out[tags.join(',')] = await i18n.initLocale();
}
@@ -186,7 +187,8 @@ def test_counted_string_picks_the_right_polish_form(tmp_path):
setItem: (k, v) => { store[k] = v; },
};
globalThis.document = { documentElement: {} };
- Object.defineProperty(globalThis, 'navigator', { value: { languages: ['pl'], language: 'pl' }, configurable: true });
+ Object.defineProperty(globalThis, 'navigator',
+ { value: { languages: ['pl'], language: 'pl' }, configurable: true });
const i18n = await import('./i18n.js');
await i18n.initLocale();
console.log(JSON.stringify(
@@ -205,7 +207,8 @@ def test_interpolated_value_is_not_read_as_a_replacement_pattern(tmp_path):
setItem: (k, v) => { store[k] = v; },
};
globalThis.document = { documentElement: {} };
- Object.defineProperty(globalThis, 'navigator', { value: { languages: ['en'], language: 'en' }, configurable: true });
+ Object.defineProperty(globalThis, 'navigator',
+ { value: { languages: ['en'], language: 'en' }, configurable: true });
const i18n = await import('./i18n.js');
await i18n.initLocale();
console.log(JSON.stringify(
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_memory_ceiling.py b/packages/meshbay-hub/tests/test_memory_ceiling.py
index 1654825..5984292 100644
--- a/packages/meshbay-hub/tests/test_memory_ceiling.py
+++ b/packages/meshbay-hub/tests/test_memory_ceiling.py
@@ -246,11 +246,11 @@ def test_no_unguarded_memory_floor(target_fn):
# definition out before looking. Comments go too — the branch that used to
# be the bug is now described in one, and a test that reads prose is the
# mistake already recorded in CLAUDE.md for the packaged systemd unit.
- start = next(n for n, l in enumerate(lines) if "const _memoryFloor" in l)
+ start = next(n for n, ln in enumerate(lines) if "const _memoryFloor" in ln)
end = next(n for n in range(start, len(lines)) if lines[n].strip() == "};")
rest = lines[:start] + lines[end + 1:]
- code = [re.sub(r"//.*$", "", l) for l in rest]
- bare = [l.strip() for l in code if re.search(r"\breturn null\b", l)]
+ code = [re.sub(r"//.*$", "", ln) for ln in rest]
+ bare = [ln.strip() for ln in code if re.search(r"\breturn null\b", ln)]
assert bare == [], (
"an unguarded in-memory fallback was added to _openDownloadTarget; "
"return _memoryFloor() instead: " + "; ".join(bare))
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..4684d3f 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:
@@ -36,7 +35,7 @@ async def test_chat_keeps_one_notification_per_group(client, db_session):
"""Forty messages are one line saying when the conversation last spoke."""
from meshbay_hub.api.notifications import create_notification
- token = await _user(client, "listener")
+ await _user(client, "listener")
owner = await _user(client, "talker_test")
g = await client.post("/v1/groups", json={"name": "busy"},
headers={"Authorization": f"Bearer {owner}"})
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"
diff --git a/packages/meshbay-hub/tests/test_transfers.py b/packages/meshbay-hub/tests/test_transfers.py
index a776b50..9b65ca5 100644
--- a/packages/meshbay-hub/tests/test_transfers.py
+++ b/packages/meshbay-hub/tests/test_transfers.py
@@ -243,7 +243,10 @@ class L {
acquire() { return this._wait; }
release(reason) { if (!this.closed) { this.closed = true; this.released.push(reason); } }
grant() { this.state = 'granted'; if (this._onState) this._onState(this); this._go(); }
- push(state, ahead) { this.state = state; this.ahead = ahead; if (this._onState) this._onState(this); }
+ push(state, ahead) {
+ this.state = state; this.ahead = ahead;
+ if (this._onState) this._onState(this);
+ }
}
"""