Move require connected down into the manager

This commit is contained in:
Jack Kingsman
2026-04-03 17:37:30 -07:00
parent 4a93641f04
commit e2ddf5f79f
14 changed files with 162 additions and 180 deletions

View File

@@ -1,8 +0,0 @@
"""Shared dependencies for FastAPI routers."""
from app.services.radio_runtime import radio_runtime as radio_manager
def require_connected():
"""Dependency that ensures radio is connected and returns meshcore instance."""
return radio_manager.require_connected()

View File

@@ -8,7 +8,6 @@ from fastapi import APIRouter, BackgroundTasks, HTTPException, Query
from meshcore import EventType
from pydantic import BaseModel, Field
from app.dependencies import require_connected
from app.models import (
Contact,
ContactActiveRoom,
@@ -428,7 +427,7 @@ async def request_trace(public_key: str) -> TraceResponse:
(no intermediate repeaters). This uses TRACE's dedicated width flags rather
than the radio's normal path_hash_mode setting.
"""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
@@ -487,7 +486,7 @@ async def request_trace(public_key: str) -> TraceResponse:
@router.post("/{public_key}/path-discovery", response_model=PathDiscoveryResponse)
async def request_path_discovery(public_key: str) -> PathDiscoveryResponse:
"""Discover the current forward and return paths to a known contact."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
pubkey_prefix = contact.public_key[:12]

View File

@@ -3,7 +3,6 @@ import time
from fastapi import APIRouter, HTTPException, Query
from app.dependencies import require_connected
from app.event_handlers import track_pending_ack
from app.models import (
Message,
@@ -89,7 +88,7 @@ async def list_messages(
@router.post("/direct", response_model=Message)
async def send_direct_message(request: SendDirectMessageRequest) -> Message:
"""Send a direct message to a contact."""
require_connected()
radio_manager.require_connected()
# First check our database for the contact
from app.repository import ContactRepository
@@ -136,7 +135,7 @@ TEMP_RADIO_SLOT = 0
@router.post("/channel", response_model=Message)
async def send_channel_message(request: SendChannelMessageRequest) -> Message:
"""Send a message to a channel."""
require_connected()
radio_manager.require_connected()
# Get channel info from our database
from app.repository import ChannelRepository
@@ -189,7 +188,7 @@ async def resend_channel_message(
When new_timestamp=True: resend with a fresh timestamp so repeaters treat it as a
new packet. Creates a new message row in the database. No time window restriction.
"""
require_connected()
radio_manager.require_connected()
from app.repository import ChannelRepository

View File

@@ -9,7 +9,6 @@ from fastapi import APIRouter, HTTPException
from meshcore import EventType
from pydantic import BaseModel, Field
from app.dependencies import require_connected
from app.models import (
CONTACT_TYPE_REPEATER,
ContactUpsert,
@@ -338,7 +337,7 @@ async def _resolve_trace_hops(
@router.get("/config", response_model=RadioConfigResponse)
async def get_radio_config() -> RadioConfigResponse:
"""Get the current radio configuration."""
mc = require_connected()
mc = radio_manager.require_connected()
info = mc.self_info
if not info:
@@ -370,7 +369,7 @@ async def get_radio_config() -> RadioConfigResponse:
@router.patch("/config", response_model=RadioConfigResponse)
async def update_radio_config(update: RadioConfigUpdate) -> RadioConfigResponse:
"""Update radio configuration. Only provided fields will be updated."""
require_connected()
radio_manager.require_connected()
async with radio_manager.radio_operation("update_radio_config") as mc:
try:
@@ -392,7 +391,7 @@ async def update_radio_config(update: RadioConfigUpdate) -> RadioConfigResponse:
@router.put("/private-key")
async def set_private_key(update: PrivateKeyUpdate) -> dict:
"""Set the radio's private key. This is write-only."""
require_connected()
radio_manager.require_connected()
try:
key_bytes = bytes.fromhex(update.private_key)
@@ -426,7 +425,7 @@ async def send_advertisement(request: RadioAdvertiseRequest | None = None) -> di
Returns:
status: "ok" if sent successfully
"""
require_connected()
radio_manager.require_connected()
mode: RadioAdvertMode = request.mode if request is not None else "flood"
logger.info("Sending %s advertisement", mode.replace("_", "-"))
@@ -442,7 +441,7 @@ async def send_advertisement(request: RadioAdvertiseRequest | None = None) -> di
@router.post("/discover", response_model=RadioDiscoveryResponse)
async def discover_mesh(request: RadioDiscoveryRequest) -> RadioDiscoveryResponse:
"""Run a short node-discovery sweep from the local radio."""
require_connected()
radio_manager.require_connected()
target_bits = _DISCOVERY_TARGET_BITS[request.target]
tag = random.randint(1, 0xFFFFFFFF)
@@ -509,7 +508,7 @@ async def discover_mesh(request: RadioDiscoveryRequest) -> RadioDiscoveryRespons
@router.post("/trace", response_model=RadioTraceResponse)
async def trace_path(request: RadioTraceRequest) -> RadioTraceResponse:
"""Send a multi-hop trace loop through known repeaters and back to the local radio."""
require_connected()
radio_manager.require_connected()
trace_nodes, requested_hashes = await _resolve_trace_hops(request.hops, request.hop_hash_bytes)
tag = random.randint(1, 0xFFFFFFFF)

View File

@@ -3,7 +3,6 @@ import time
from fastapi import APIRouter, HTTPException
from app.dependencies import require_connected
from app.models import (
CONTACT_TYPE_REPEATER,
AclEntry,
@@ -75,7 +74,7 @@ def _require_repeater(contact: Contact) -> None:
@router.post("/{public_key}/repeater/login", response_model=RepeaterLoginResponse)
async def repeater_login(public_key: str, request: RepeaterLoginRequest) -> RepeaterLoginResponse:
"""Attempt repeater login and report whether auth was confirmed."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_repeater(contact)
@@ -90,7 +89,7 @@ async def repeater_login(public_key: str, request: RepeaterLoginRequest) -> Repe
@router.post("/{public_key}/repeater/status", response_model=RepeaterStatusResponse)
async def repeater_status(public_key: str) -> RepeaterStatusResponse:
"""Fetch status telemetry from a repeater (single attempt, 10s timeout)."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_repeater(contact)
@@ -165,7 +164,7 @@ async def repeater_telemetry_history(public_key: str) -> list[TelemetryHistoryEn
@router.post("/{public_key}/repeater/lpp-telemetry", response_model=RepeaterLppTelemetryResponse)
async def repeater_lpp_telemetry(public_key: str) -> RepeaterLppTelemetryResponse:
"""Fetch CayenneLPP sensor telemetry from a repeater (single attempt, 10s timeout)."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_repeater(contact)
@@ -194,7 +193,7 @@ async def repeater_lpp_telemetry(public_key: str) -> RepeaterLppTelemetryRespons
@router.post("/{public_key}/repeater/neighbors", response_model=RepeaterNeighborsResponse)
async def repeater_neighbors(public_key: str) -> RepeaterNeighborsResponse:
"""Fetch neighbors from a repeater (single attempt, 10s timeout)."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_repeater(contact)
@@ -228,7 +227,7 @@ async def repeater_neighbors(public_key: str) -> RepeaterNeighborsResponse:
@router.post("/{public_key}/repeater/acl", response_model=RepeaterAclResponse)
async def repeater_acl(public_key: str) -> RepeaterAclResponse:
"""Fetch ACL from a repeater (single attempt, 10s timeout)."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_repeater(contact)
@@ -269,7 +268,7 @@ async def _batch_cli_fetch(
@router.post("/{public_key}/repeater/node-info", response_model=RepeaterNodeInfoResponse)
async def repeater_node_info(public_key: str) -> RepeaterNodeInfoResponse:
"""Fetch repeater identity/location info via a small CLI batch."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_repeater(contact)
@@ -289,7 +288,7 @@ async def repeater_node_info(public_key: str) -> RepeaterNodeInfoResponse:
@router.post("/{public_key}/repeater/radio-settings", response_model=RepeaterRadioSettingsResponse)
async def repeater_radio_settings(public_key: str) -> RepeaterRadioSettingsResponse:
"""Fetch radio settings from a repeater via radio/config CLI commands."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_repeater(contact)
@@ -313,7 +312,7 @@ async def repeater_radio_settings(public_key: str) -> RepeaterRadioSettingsRespo
)
async def repeater_advert_intervals(public_key: str) -> RepeaterAdvertIntervalsResponse:
"""Fetch advertisement intervals from a repeater via CLI commands."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_repeater(contact)
@@ -331,7 +330,7 @@ async def repeater_advert_intervals(public_key: str) -> RepeaterAdvertIntervalsR
@router.post("/{public_key}/repeater/owner-info", response_model=RepeaterOwnerInfoResponse)
async def repeater_owner_info(public_key: str) -> RepeaterOwnerInfoResponse:
"""Fetch owner info and guest password from a repeater via CLI commands."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_repeater(contact)
@@ -349,7 +348,7 @@ async def repeater_owner_info(public_key: str) -> RepeaterOwnerInfoResponse:
@router.post("/{public_key}/command", response_model=CommandResponse)
async def send_repeater_command(public_key: str, request: CommandRequest) -> CommandResponse:
"""Send a CLI command to a repeater or room server."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
require_server_capable_contact(contact)

View File

@@ -1,6 +1,5 @@
from fastapi import APIRouter, HTTPException
from app.dependencies import require_connected
from app.models import (
CONTACT_TYPE_ROOM,
AclEntry,
@@ -28,7 +27,7 @@ def _require_room(contact) -> None:
@router.post("/{public_key}/room/login", response_model=RepeaterLoginResponse)
async def room_login(public_key: str, request: RepeaterLoginRequest) -> RepeaterLoginResponse:
"""Attempt room-server login and report whether auth was confirmed."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_room(contact)
@@ -48,7 +47,7 @@ async def room_login(public_key: str, request: RepeaterLoginRequest) -> Repeater
@router.post("/{public_key}/room/status", response_model=RepeaterStatusResponse)
async def room_status(public_key: str) -> RepeaterStatusResponse:
"""Fetch status telemetry from a room server."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_room(contact)
@@ -85,7 +84,7 @@ async def room_status(public_key: str) -> RepeaterStatusResponse:
@router.post("/{public_key}/room/lpp-telemetry", response_model=RepeaterLppTelemetryResponse)
async def room_lpp_telemetry(public_key: str) -> RepeaterLppTelemetryResponse:
"""Fetch CayenneLPP telemetry from a room server."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_room(contact)
@@ -114,7 +113,7 @@ async def room_lpp_telemetry(public_key: str) -> RepeaterLppTelemetryResponse:
@router.post("/{public_key}/room/acl", response_model=RepeaterAclResponse)
async def room_acl(public_key: str) -> RepeaterAclResponse:
"""Fetch ACL entries from a room server."""
require_connected()
radio_manager.require_connected()
contact = await _resolve_contact_or_404(public_key)
_require_room(contact)

View File

@@ -83,7 +83,7 @@ class TestDMAckTrackingWiring:
await _insert_contact(pub_key)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.track_pending_ack") as mock_track,
patch("app.routers.messages.broadcast_event"),
@@ -115,7 +115,7 @@ class TestDMAckTrackingWiring:
await _insert_contact(pub_key)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.track_pending_ack") as mock_track,
patch("app.routers.messages.broadcast_event"),
@@ -144,7 +144,7 @@ class TestDMAckTrackingWiring:
await _insert_contact(pub_key)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.track_pending_ack") as mock_track,
patch("app.routers.messages.broadcast_event"),
@@ -172,7 +172,7 @@ class TestDMAckTrackingWiring:
await _insert_contact(pub_key)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.track_pending_ack") as mock_track,
patch("app.routers.messages.broadcast_event"),

View File

@@ -49,10 +49,10 @@ def _disable_background_dm_retries(monkeypatch):
def _patch_require_connected(mc=None, *, detail="Radio not connected"):
if mc is None:
return patch(
"app.dependencies.radio_manager.require_connected",
"app.services.radio_runtime.radio_runtime.require_connected",
side_effect=HTTPException(status_code=503, detail=detail),
)
return patch("app.dependencies.radio_manager.require_connected", return_value=mc)
return patch("app.services.radio_runtime.radio_runtime.require_connected", return_value=mc)
async def _insert_contact(public_key, name="Alice", **overrides):

View File

@@ -286,7 +286,7 @@ class TestPathDiscovery:
)
with (
patch("app.routers.contacts.require_connected", return_value=mc),
patch("app.routers.contacts.radio_manager.require_connected", return_value=mc),
patch("app.routers.contacts.radio_manager") as mock_rm,
patch("app.websocket.broadcast_event") as mock_broadcast,
):
@@ -324,7 +324,7 @@ class TestPathDiscovery:
mc.wait_for_event = AsyncMock(return_value=None)
with (
patch("app.routers.contacts.require_connected", return_value=mc),
patch("app.routers.contacts.radio_manager.require_connected", return_value=mc),
patch("app.routers.contacts.radio_manager") as mock_rm,
):
mock_rm.radio_operation = _noop_radio_operation(mc)

View File

@@ -7,11 +7,6 @@ import pytest
from app.radio import RadioDisconnectedError, RadioOperationBusyError, radio_manager
from app.radio_sync import is_polling_paused
from app.services.radio_runtime import RadioRuntime
def _runtime(manager):
return RadioRuntime(lambda: manager)
@pytest.fixture(autouse=True)
@@ -183,15 +178,15 @@ class TestRequireConnected:
"""HTTPException 503 is raised when radio is connected but setup is still in progress."""
from fastapi import HTTPException
from app.dependencies import require_connected
from app.services.radio_runtime import radio_runtime
manager = MagicMock()
manager.is_connected = True
manager.meshcore = MagicMock()
manager.is_setup_in_progress = True
with patch("app.dependencies.radio_manager", _runtime(manager)):
with patch.object(radio_runtime, "_manager_getter", return_value=manager):
with pytest.raises(HTTPException) as exc_info:
require_connected()
radio_runtime.require_connected()
assert exc_info.value.status_code == 503
assert "initializing" in exc_info.value.detail.lower()
@@ -200,28 +195,28 @@ class TestRequireConnected:
"""HTTPException 503 is raised when radio is not connected."""
from fastapi import HTTPException
from app.dependencies import require_connected
from app.services.radio_runtime import radio_runtime
manager = MagicMock()
manager.is_setup_in_progress = False
manager.is_connected = False
manager.meshcore = None
with patch("app.dependencies.radio_manager", _runtime(manager)):
with patch.object(radio_runtime, "_manager_getter", return_value=manager):
with pytest.raises(HTTPException) as exc_info:
require_connected()
radio_runtime.require_connected()
assert exc_info.value.status_code == 503
def test_returns_meshcore_when_connected_and_setup_complete(self):
"""Returns meshcore instance when radio is connected and setup is complete."""
from app.dependencies import require_connected
from app.services.radio_runtime import radio_runtime
mock_mc = MagicMock()
manager = MagicMock()
manager.is_setup_in_progress = False
manager.is_connected = True
manager.meshcore = mock_mc
with patch("app.dependencies.radio_manager", _runtime(manager)):
result = require_connected()
with patch.object(radio_runtime, "_manager_getter", return_value=manager):
result = radio_runtime.require_connected()
assert result is mock_mc

View File

@@ -97,7 +97,7 @@ class TestGetRadioConfig:
@pytest.mark.asyncio
async def test_maps_self_info_to_response(self):
mc = _mock_meshcore_with_info()
with patch("app.routers.radio.require_connected", return_value=mc):
with patch("app.routers.radio.radio_manager.require_connected", return_value=mc):
response = await get_radio_config()
assert response.public_key == "aa" * 32
@@ -114,7 +114,7 @@ class TestGetRadioConfig:
mc = _mock_meshcore_with_info()
mc.self_info["multi_acks"] = 1
with patch("app.routers.radio.require_connected", return_value=mc):
with patch("app.routers.radio.radio_manager.require_connected", return_value=mc):
response = await get_radio_config()
assert response.multi_acks_enabled is True
@@ -124,7 +124,7 @@ class TestGetRadioConfig:
mc = _mock_meshcore_with_info()
mc.self_info["adv_loc_policy"] = 1
with patch("app.routers.radio.require_connected", return_value=mc):
with patch("app.routers.radio.radio_manager.require_connected", return_value=mc):
response = await get_radio_config()
assert response.advert_location_source == "current"
@@ -133,7 +133,7 @@ class TestGetRadioConfig:
async def test_returns_503_when_self_info_missing(self):
mc = MagicMock()
mc.self_info = None
with patch("app.routers.radio.require_connected", return_value=mc):
with patch("app.routers.radio.radio_manager.require_connected", return_value=mc):
with pytest.raises(HTTPException) as exc:
await get_radio_config()
@@ -155,7 +155,7 @@ class TestUpdateRadioConfig:
)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.radio.sync_radio_time", new_callable=AsyncMock) as mock_sync_time,
patch(
@@ -190,7 +190,7 @@ class TestUpdateRadioConfig:
)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.radio.sync_radio_time", new_callable=AsyncMock),
patch(
@@ -220,7 +220,7 @@ class TestUpdateRadioConfig:
)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.radio.sync_radio_time", new_callable=AsyncMock),
patch(
@@ -252,7 +252,7 @@ class TestUpdateRadioConfig:
mc = _mock_meshcore_with_info()
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch.object(radio_manager, "path_hash_mode_supported", False),
):
@@ -269,7 +269,7 @@ class TestUpdateRadioConfig:
)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch.object(radio_manager, "path_hash_mode_supported", True),
patch.object(radio_manager, "path_hash_mode", 0),
@@ -287,7 +287,7 @@ class TestPrivateKeyImport:
@pytest.mark.asyncio
async def test_rejects_invalid_hex(self):
mc = _mock_meshcore_with_info()
with patch("app.routers.radio.require_connected", return_value=mc):
with patch("app.routers.radio.radio_manager.require_connected", return_value=mc):
with pytest.raises(HTTPException) as exc:
await set_private_key(PrivateKeyUpdate(private_key="not-hex"))
@@ -300,7 +300,7 @@ class TestPrivateKeyImport:
return_value=_radio_result(EventType.ERROR, {"error": "failed"})
)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -367,7 +367,7 @@ class TestDiscoverMesh:
mc.commands.send_node_discover_req = AsyncMock(side_effect=_send_node_discover_req)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.radio.DISCOVERY_WINDOW_SECONDS", 0.01),
patch(
@@ -441,7 +441,7 @@ class TestDiscoverMesh:
mc.subscribe = MagicMock(side_effect=_subscribe)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.radio.DISCOVERY_WINDOW_SECONDS", 0.01),
patch(
@@ -517,7 +517,7 @@ class TestDiscoverMesh:
mc.subscribe = MagicMock(side_effect=_subscribe)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.radio.DISCOVERY_WINDOW_SECONDS", 0.01),
patch(
@@ -591,7 +591,7 @@ class TestTracePath:
)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(
"app.routers.radio.ContactRepository.get_by_key", new_callable=AsyncMock
@@ -648,7 +648,7 @@ class TestTracePath:
)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch(
"app.routers.radio.ContactRepository.get_by_key", new_callable=AsyncMock
) as mock_get,
@@ -691,7 +691,7 @@ class TestTracePath:
mc.wait_for_event = AsyncMock(return_value=None)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(
"app.routers.radio.ContactRepository.get_by_key", new_callable=AsyncMock
@@ -731,7 +731,7 @@ class TestTracePath:
)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.radio.radio_manager") as mock_rm,
):
@@ -775,7 +775,7 @@ class TestTracePath:
mc.subscribe = MagicMock(side_effect=_subscribe)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.radio.DISCOVERY_WINDOW_SECONDS", 0.01),
patch(
@@ -811,7 +811,7 @@ class TestTracePath:
)
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -825,7 +825,7 @@ class TestTracePath:
mc = _mock_meshcore_with_info()
mc.commands.import_private_key = AsyncMock(return_value=_radio_result())
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(
"app.keystore.export_and_store_private_key",
@@ -843,7 +843,7 @@ class TestTracePath:
mc = _mock_meshcore_with_info()
mc.commands.import_private_key = AsyncMock(return_value=_radio_result())
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(
"app.keystore.export_and_store_private_key",
@@ -864,7 +864,7 @@ class TestTracePath:
mc = _mock_meshcore_with_info()
mc.commands.import_private_key = AsyncMock(return_value=_radio_result())
with (
patch("app.routers.radio.require_connected", return_value=mc),
patch("app.routers.radio.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(
"app.keystore.export_and_store_private_key",
@@ -883,7 +883,7 @@ class TestAdvertise:
async def test_raises_when_send_fails(self):
radio_manager._meshcore = MagicMock()
with (
patch("app.routers.radio.require_connected"),
patch("app.routers.radio.radio_manager.require_connected"),
patch(
"app.routers.radio.do_send_advertisement",
new_callable=AsyncMock,
@@ -899,7 +899,7 @@ class TestAdvertise:
async def test_defaults_to_flood_mode(self):
radio_manager._meshcore = MagicMock()
with (
patch("app.routers.radio.require_connected"),
patch("app.routers.radio.radio_manager.require_connected"),
patch(
"app.routers.radio.do_send_advertisement",
new_callable=AsyncMock,
@@ -917,7 +917,7 @@ class TestAdvertise:
async def test_accepts_zero_hop_mode(self):
radio_manager._meshcore = MagicMock()
with (
patch("app.routers.radio.require_connected"),
patch("app.routers.radio.radio_manager.require_connected"),
patch(
"app.routers.radio.do_send_advertisement",
new_callable=AsyncMock,
@@ -949,7 +949,7 @@ class TestAdvertise:
isolated_manager = RadioManager()
isolated_manager._meshcore = MagicMock()
with (
patch("app.routers.radio.require_connected"),
patch("app.routers.radio.radio_manager.require_connected"),
patch("app.routers.radio.radio_manager", _runtime(isolated_manager)),
patch(
"app.routers.radio.do_send_advertisement",

View File

@@ -296,7 +296,7 @@ class TestRepeaterCommandRoute:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -314,7 +314,7 @@ class TestRepeaterCommandRoute:
# Expire the deadline after a couple of ticks
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=[0.0, 5.0, 25.0]),
patch("app.routers.server_control.asyncio.sleep", new_callable=AsyncMock),
@@ -343,7 +343,7 @@ class TestRepeaterCommandRoute:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=_advancing_clock()),
):
@@ -371,7 +371,7 @@ class TestRepeaterCommandRoute:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=_advancing_clock()),
):
@@ -397,7 +397,7 @@ class TestRepeaterCommandRoute:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=_advancing_clock()),
):
@@ -425,7 +425,7 @@ class TestRepeaterCommandRoute:
mc.commands.get_msg = AsyncMock(side_effect=[unrelated, expected])
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=_advancing_clock()),
):
@@ -451,7 +451,7 @@ class TestRepeaterCommandRoute:
mc.commands.get_msg = AsyncMock(side_effect=[channel_msg, expected])
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=_advancing_clock()),
):
@@ -474,7 +474,7 @@ class TestRepeaterCommandRoute:
mc.commands.get_msg = AsyncMock(side_effect=[no_msgs, expected])
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=_advancing_clock()),
patch("app.routers.server_control.asyncio.sleep", new_callable=AsyncMock),
@@ -495,7 +495,7 @@ class TestTraceRoute:
)
with (
patch("app.routers.contacts.require_connected", return_value=mc),
patch("app.routers.contacts.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.contacts.random.randint", return_value=1234),
):
@@ -517,7 +517,7 @@ class TestTraceRoute:
mc.wait_for_event = AsyncMock(return_value=None)
with (
patch("app.routers.contacts.require_connected", return_value=mc),
patch("app.routers.contacts.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.contacts.random.randint", return_value=1234),
):
@@ -541,7 +541,7 @@ class TestTraceRoute:
)
with (
patch("app.routers.contacts.require_connected", return_value=mc),
patch("app.routers.contacts.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.contacts.random.randint", return_value=1234),
):
@@ -569,7 +569,7 @@ class TestRepeaterLogin:
await _insert_contact(KEY_A, name="Repeater", contact_type=2)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(
"app.routers.repeaters.prepare_repeater_connection",
@@ -592,7 +592,7 @@ class TestRepeaterLogin:
async def test_404_missing_contact(self, test_db):
mc = _mock_mc()
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -604,7 +604,7 @@ class TestRepeaterLogin:
mc = _mock_mc()
await _insert_contact(KEY_A, name="Client", contact_type=1)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -625,7 +625,7 @@ class TestRepeaterLogin:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.repeaters.prepare_repeater_connection", side_effect=_prepare_fail),
):
@@ -726,7 +726,7 @@ class TestRepeaterStatus:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await repeater_status(KEY_A)
@@ -749,7 +749,7 @@ class TestRepeaterStatus:
mc.commands.req_status_sync = AsyncMock(return_value=None)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -761,7 +761,7 @@ class TestRepeaterStatus:
mc = _mock_mc()
await _insert_contact(KEY_A, name="Client", contact_type=1)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -787,7 +787,7 @@ class TestRepeaterLppTelemetry:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await repeater_lpp_telemetry(KEY_A)
@@ -809,7 +809,7 @@ class TestRepeaterLppTelemetry:
mc.commands.req_telemetry_sync = AsyncMock(return_value=[])
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await repeater_lpp_telemetry(KEY_A)
@@ -823,7 +823,7 @@ class TestRepeaterLppTelemetry:
mc.commands.req_telemetry_sync = AsyncMock(return_value=None)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -835,7 +835,7 @@ class TestRepeaterLppTelemetry:
mc = _mock_mc()
await _insert_contact(KEY_A, name="Client", contact_type=1)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -861,7 +861,7 @@ class TestRepeaterNeighbors:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await repeater_neighbors(KEY_A)
@@ -879,7 +879,7 @@ class TestRepeaterNeighbors:
mc.commands.fetch_all_neighbours = AsyncMock(return_value={"neighbours": []})
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await repeater_neighbors(KEY_A)
@@ -893,7 +893,7 @@ class TestRepeaterNeighbors:
mc.commands.fetch_all_neighbours = AsyncMock(return_value=None)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await repeater_neighbors(KEY_A)
@@ -917,7 +917,7 @@ class TestRepeaterAcl:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await repeater_acl(KEY_A)
@@ -935,7 +935,7 @@ class TestRepeaterAcl:
mc.commands.req_acl_sync = AsyncMock(return_value=[])
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await repeater_acl(KEY_A)
@@ -949,7 +949,7 @@ class TestRepeaterAcl:
mc.commands.req_acl_sync = AsyncMock(return_value=None)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await repeater_acl(KEY_A)
@@ -982,7 +982,7 @@ class TestRepeaterRadioSettings:
mc.commands.get_msg = AsyncMock(side_effect=get_msg_results)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=_advancing_clock()),
):
@@ -1015,7 +1015,7 @@ class TestRepeaterRadioSettings:
clock_ticks.extend([base, base + 5.0, base + 11.0])
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=clock_ticks),
patch("app.routers.server_control.asyncio.sleep", new_callable=AsyncMock),
@@ -1031,7 +1031,7 @@ class TestRepeaterRadioSettings:
mc = _mock_mc()
await _insert_contact(KEY_A, name="Client", contact_type=1)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -1061,7 +1061,7 @@ class TestRepeaterNodeInfo:
mc.commands.get_msg = AsyncMock(side_effect=get_msg_results)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=_advancing_clock()),
):
@@ -1090,7 +1090,7 @@ class TestRepeaterNodeInfo:
clock_ticks.extend([base, base + 5.0, base + 11.0])
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=clock_ticks),
patch("app.routers.server_control.asyncio.sleep", new_callable=AsyncMock),
@@ -1122,7 +1122,7 @@ class TestRepeaterAdvertIntervals:
mc.commands.get_msg = AsyncMock(side_effect=responses)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=_advancing_clock()),
):
@@ -1143,7 +1143,7 @@ class TestRepeaterAdvertIntervals:
clock_ticks.extend([base, base + 5.0, base + 11.0])
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=clock_ticks),
patch("app.routers.server_control.asyncio.sleep", new_callable=AsyncMock),
@@ -1177,7 +1177,7 @@ class TestRepeaterOwnerInfo:
mc.commands.get_msg = AsyncMock(side_effect=responses)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=_advancing_clock()),
):
@@ -1198,7 +1198,7 @@ class TestRepeaterOwnerInfo:
clock_ticks.extend([base, base + 5.0, base + 11.0])
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch(_MONOTONIC, side_effect=clock_ticks),
patch("app.routers.server_control.asyncio.sleep", new_callable=AsyncMock),
@@ -1299,7 +1299,7 @@ class TestRepeaterAddContactError:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -1317,7 +1317,7 @@ class TestRepeaterAddContactError:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -1335,7 +1335,7 @@ class TestRepeaterAddContactError:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -1353,7 +1353,7 @@ class TestRepeaterAddContactError:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:

View File

@@ -88,7 +88,7 @@ class TestRoomLogin:
mc.commands.send_login = AsyncMock(side_effect=_send_login)
with (
patch("app.routers.rooms.require_connected", return_value=mc),
patch("app.routers.rooms.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await room_login(ROOM_KEY, RepeaterLoginRequest(password="hello"))
@@ -102,7 +102,7 @@ class TestRoomLogin:
await _insert_contact(ROOM_KEY, name="Client", contact_type=1)
with (
patch("app.routers.rooms.require_connected", return_value=mc),
patch("app.routers.rooms.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(HTTPException) as exc:
@@ -139,7 +139,7 @@ class TestRoomStatus:
)
with (
patch("app.routers.rooms.require_connected", return_value=mc),
patch("app.routers.rooms.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await room_status(ROOM_KEY)
@@ -156,7 +156,7 @@ class TestRoomStatus:
mc.commands.req_acl_sync = AsyncMock(return_value=[{"key": AUTHOR_KEY[:12], "perm": 3}])
with (
patch("app.routers.rooms.require_connected", return_value=mc),
patch("app.routers.rooms.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await room_acl(ROOM_KEY)
@@ -179,7 +179,7 @@ class TestRoomCommandReuse:
)
with (
patch("app.routers.repeaters.require_connected", return_value=mc),
patch("app.routers.repeaters.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
response = await send_repeater_command(ROOM_KEY, CommandRequest(command="ver"))

View File

@@ -119,7 +119,7 @@ class TestOutgoingDMBroadcast:
broadcasts.append({"type": event_type, "data": data})
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event", side_effect=capture_broadcast),
):
@@ -143,7 +143,7 @@ class TestOutgoingDMBroadcast:
await _insert_contact("abc123" + "00" * 29, "ContactA")
await _insert_contact("abc123" + "ff" * 29, "ContactB")
with patch("app.routers.messages.require_connected", return_value=mc):
with patch("app.routers.messages.radio_manager.require_connected", return_value=mc):
with pytest.raises(HTTPException) as exc_info:
await send_direct_message(
SendDirectMessageRequest(destination="abc123", text="Hello")
@@ -166,7 +166,7 @@ class TestOutgoingDMBroadcast:
)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -195,7 +195,7 @@ class TestOutgoingDMBroadcast:
)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -225,7 +225,7 @@ class TestOutgoingDMBroadcast:
assert original_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
patch("app.routers.messages.time") as mock_time,
@@ -267,7 +267,7 @@ class TestOutgoingDMBroadcast:
with (
patch("app.event_handlers.broadcast_event", side_effect=capture_broadcast),
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event", side_effect=capture_broadcast),
):
@@ -290,7 +290,7 @@ class TestOutgoingDMBroadcast:
mc.commands.send_msg = AsyncMock(return_value=_make_radio_result({}))
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
patch("app.services.message_send.asyncio.create_task") as mock_create_task,
@@ -338,7 +338,7 @@ class TestOutgoingDMBroadcast:
with (
patch.object(message_send_service, "DM_SEND_MAX_ATTEMPTS", 3),
patch("app.routers.messages.track_pending_ack", return_value=False),
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
patch("app.services.message_send.asyncio.create_task", side_effect=schedule_retry),
@@ -386,7 +386,7 @@ class TestOutgoingDMBroadcast:
with (
patch.object(message_send_service, "DM_SEND_MAX_ATTEMPTS", 3),
patch("app.event_handlers.broadcast_event"),
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
patch("app.services.message_send.asyncio.create_task", side_effect=schedule_retry),
@@ -443,7 +443,7 @@ class TestOutgoingDMBroadcast:
with (
patch.object(message_send_service, "DM_SEND_MAX_ATTEMPTS", 3),
patch("app.event_handlers.broadcast_event"),
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
patch("app.services.message_send.asyncio.create_task", side_effect=schedule_retry),
@@ -477,7 +477,7 @@ class TestOutgoingChannelBroadcast:
broadcasts.append({"type": event_type, "data": data})
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event", side_effect=capture_broadcast),
):
@@ -511,7 +511,7 @@ class TestOutgoingChannelBroadcast:
assert original_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
patch("app.routers.messages.time") as mock_time,
@@ -537,7 +537,7 @@ class TestOutgoingChannelBroadcast:
await ChannelRepository.upsert(key=chan_key, name="#acked")
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -564,7 +564,7 @@ class TestOutgoingChannelBroadcast:
broadcasts.append({"type": event_type, "data": data})
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event", side_effect=capture_broadcast),
):
@@ -594,7 +594,7 @@ class TestOutgoingChannelBroadcast:
await AppSettingsRepository.update(flood_scope="Baseline")
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -617,7 +617,7 @@ class TestOutgoingChannelBroadcast:
await AppSettingsRepository.update(flood_scope="Esperance")
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -638,7 +638,7 @@ class TestOutgoingChannelBroadcast:
)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
pytest.raises(HTTPException) as exc_info,
@@ -660,7 +660,7 @@ class TestOutgoingChannelBroadcast:
radio_manager._connection_info = "Serial: /dev/ttyUSB0"
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -688,7 +688,7 @@ class TestOutgoingChannelBroadcast:
radio_manager._connection_info = "Serial: /dev/ttyUSB0"
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -729,7 +729,7 @@ class TestOutgoingChannelBroadcast:
radio_manager._connection_info = "TCP: 127.0.0.1:4000"
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -753,7 +753,7 @@ class TestOutgoingChannelBroadcast:
radio_manager._connection_info = "Serial: /dev/ttyUSB0"
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
patch("app.radio.settings.force_channel_slot_reconfigure", True),
@@ -781,7 +781,7 @@ class TestOutgoingChannelBroadcast:
)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
pytest.raises(HTTPException) as exc_info,
@@ -816,7 +816,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
result = await resend_channel_message(msg_id, new_timestamp=False)
@@ -849,7 +849,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
pytest.raises(HTTPException) as exc_info,
):
await resend_channel_message(msg_id, new_timestamp=False)
@@ -877,7 +877,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
await resend_channel_message(msg_id, new_timestamp=False)
@@ -914,7 +914,7 @@ class TestResendChannelMessage:
)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_error") as mock_broadcast_error,
):
@@ -943,7 +943,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
patch("app.routers.messages.time") as mock_time,
@@ -989,7 +989,7 @@ class TestResendChannelMessage:
mc.commands.send_chan_msg = AsyncMock(return_value=None)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
pytest.raises(HTTPException) as exc_info,
):
@@ -1022,7 +1022,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
pytest.raises(HTTPException) as exc_info,
):
await resend_channel_message(msg_id, new_timestamp=False)
@@ -1048,7 +1048,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
pytest.raises(HTTPException) as exc_info,
):
await resend_channel_message(msg_id, new_timestamp=False)
@@ -1062,7 +1062,7 @@ class TestResendChannelMessage:
mc = _make_mc(name="MyNode")
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
pytest.raises(HTTPException) as exc_info,
):
await resend_channel_message(999999, new_timestamp=False)
@@ -1088,7 +1088,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
await resend_channel_message(msg_id, new_timestamp=False)
@@ -1115,7 +1115,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -1144,7 +1144,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -1179,7 +1179,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event") as mock_broadcast,
):
@@ -1211,7 +1211,7 @@ class TestResendChannelMessage:
assert msg_id is not None
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
pytest.raises(HTTPException) as exc_info,
):
await resend_channel_message(msg_id, new_timestamp=False)
@@ -1234,7 +1234,7 @@ class TestRadioExceptionMidSend:
mc.commands.send_msg = AsyncMock(side_effect=ConnectionError("Serial port disconnected"))
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(ConnectionError):
@@ -1258,7 +1258,7 @@ class TestRadioExceptionMidSend:
mc.commands.send_msg = AsyncMock(return_value=None)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
pytest.raises(HTTPException) as exc_info,
):
@@ -1286,7 +1286,7 @@ class TestRadioExceptionMidSend:
mc.commands.send_chan_msg = AsyncMock(return_value=None)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
pytest.raises(HTTPException) as exc_info,
):
@@ -1316,7 +1316,7 @@ class TestRadioExceptionMidSend:
)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(ConnectionError):
@@ -1341,7 +1341,7 @@ class TestRadioExceptionMidSend:
mc.commands.set_channel = AsyncMock(side_effect=TimeoutError("Radio not responding"))
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(TimeoutError):
@@ -1377,7 +1377,7 @@ class TestRadioExceptionMidSend:
mc.commands.set_channel = AsyncMock(side_effect=TimeoutError("Radio not responding"))
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
):
with pytest.raises(TimeoutError):
@@ -1407,7 +1407,7 @@ class TestRadioExceptionMidSend:
)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
pytest.raises(HTTPException) as exc_info,
):
@@ -1440,7 +1440,7 @@ class TestConcurrentChannelSends:
await ChannelRepository.upsert(key=chan_key_b, name="#bravo")
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
):
@@ -1494,7 +1494,7 @@ class TestConcurrentChannelSends:
return original_time() + call_count
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
patch("app.routers.messages.time") as mock_time,
@@ -1537,7 +1537,7 @@ class TestChannelSendLockScope:
return await original_create(*args, **kwargs)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event"),
patch(
@@ -1587,7 +1587,7 @@ class TestChannelSendLockScope:
mc.commands.send_chan_msg = AsyncMock(side_effect=send_with_self_observation)
with (
patch("app.routers.messages.require_connected", return_value=mc),
patch("app.routers.messages.radio_manager.require_connected", return_value=mc),
patch.object(radio_manager, "_meshcore", mc),
patch("app.routers.messages.broadcast_event", side_effect=capture_broadcast),
):