mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
Do our own tracking for contact-on-radio with more correct return state
This commit is contained in:
@@ -419,6 +419,7 @@ async def add_contact_to_radio(public_key: str) -> dict:
|
||||
# Check if already on radio
|
||||
radio_contact = mc.get_contact_by_key_prefix(contact.public_key[:12])
|
||||
if radio_contact:
|
||||
await ContactRepository.set_on_radio(contact.public_key, True)
|
||||
return {"status": "ok", "message": "Contact already on radio"}
|
||||
|
||||
logger.info("Adding contact %s to radio", contact.public_key[:12])
|
||||
|
||||
@@ -206,7 +206,6 @@ async def send_channel_message_to_channel(
|
||||
message_repository=MessageRepository,
|
||||
) -> Any:
|
||||
"""Send a channel message and persist/broadcast the outgoing row."""
|
||||
message_id: int | None = None
|
||||
now: int | None = None
|
||||
radio_name = ""
|
||||
our_public_key: str | None = None
|
||||
@@ -235,27 +234,27 @@ async def send_channel_message_to_channel(
|
||||
if result.type == EventType.ERROR:
|
||||
raise HTTPException(status_code=500, detail=f"Failed to send message: {result.payload}")
|
||||
|
||||
outgoing_message = await create_outgoing_channel_message(
|
||||
conversation_key=channel_key_upper,
|
||||
text=text_with_sender,
|
||||
sender_timestamp=now,
|
||||
received_at=now,
|
||||
sender_name=radio_name or None,
|
||||
sender_key=our_public_key,
|
||||
channel_name=channel.name,
|
||||
broadcast_fn=broadcast_fn,
|
||||
message_repository=message_repository,
|
||||
)
|
||||
if outgoing_message is None:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Failed to store outgoing message - unexpected duplicate",
|
||||
)
|
||||
message_id = outgoing_message.id
|
||||
|
||||
if message_id is None or now is None:
|
||||
if now is None:
|
||||
raise HTTPException(status_code=500, detail="Failed to store outgoing message")
|
||||
|
||||
outgoing_message = await create_outgoing_channel_message(
|
||||
conversation_key=channel_key_upper,
|
||||
text=text_with_sender,
|
||||
sender_timestamp=now,
|
||||
received_at=now,
|
||||
sender_name=radio_name or None,
|
||||
sender_key=our_public_key,
|
||||
channel_name=channel.name,
|
||||
broadcast_fn=broadcast_fn,
|
||||
message_repository=message_repository,
|
||||
)
|
||||
if outgoing_message is None:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Failed to store outgoing message - unexpected duplicate",
|
||||
)
|
||||
|
||||
message_id = outgoing_message.id
|
||||
acked_count, paths = await message_repository.get_ack_and_paths(message_id)
|
||||
return build_message_model(
|
||||
message_id=message_id,
|
||||
|
||||
@@ -954,8 +954,8 @@ class TestAddRemoveRadio:
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_add_already_on_radio(self, test_db, client):
|
||||
"""Adding a contact already on radio returns ok without calling add_contact."""
|
||||
await _insert_contact(KEY_A, on_radio=True)
|
||||
"""Adding a contact already on radio repairs the DB flag and skips add_contact."""
|
||||
await _insert_contact(KEY_A, on_radio=False)
|
||||
|
||||
mock_mc = MagicMock()
|
||||
mock_mc.get_contact_by_key_prefix = MagicMock(return_value=MagicMock()) # On radio
|
||||
@@ -966,6 +966,10 @@ class TestAddRemoveRadio:
|
||||
|
||||
assert response.status_code == 200
|
||||
assert "already" in response.json()["message"].lower()
|
||||
contact = await ContactRepository.get_by_key(KEY_A)
|
||||
assert contact is not None
|
||||
assert contact.on_radio is True
|
||||
mock_mc.commands.add_contact.assert_not_called()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_remove_from_radio(self, test_db, client):
|
||||
|
||||
@@ -907,3 +907,35 @@ class TestConcurrentChannelSends:
|
||||
msg_type="CHAN", conversation_key=chan_key.upper(), limit=10
|
||||
)
|
||||
assert len(msgs) == 2
|
||||
|
||||
|
||||
class TestChannelSendLockScope:
|
||||
"""Channel send should release the radio lock before DB persistence work."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_channel_message_row_created_after_radio_lock_released(self, test_db):
|
||||
mc = _make_mc(name="TestNode")
|
||||
chan_key = "de" * 16
|
||||
await ChannelRepository.upsert(key=chan_key, name="#lockscope")
|
||||
|
||||
observed_lock_states: list[bool] = []
|
||||
original_create = MessageRepository.create
|
||||
|
||||
async def _assert_lock_then_create(*args, **kwargs):
|
||||
observed_lock_states.append(bool(radio_manager._operation_lock.locked()))
|
||||
return await original_create(*args, **kwargs)
|
||||
|
||||
with (
|
||||
patch("app.routers.messages.require_connected", return_value=mc),
|
||||
patch.object(radio_manager, "_meshcore", mc),
|
||||
patch("app.routers.messages.broadcast_event"),
|
||||
patch(
|
||||
"app.services.message_send.MessageRepository.create",
|
||||
side_effect=_assert_lock_then_create,
|
||||
),
|
||||
):
|
||||
await send_channel_message(
|
||||
SendChannelMessageRequest(channel_key=chan_key, text="Lock scope test")
|
||||
)
|
||||
|
||||
assert observed_lock_states == [False]
|
||||
|
||||
Reference in New Issue
Block a user