mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
Fix up resend logic to be cleaner
This commit is contained in:
@@ -180,7 +180,7 @@ RESEND_WINDOW_SECONDS = 30
|
||||
async def resend_channel_message(
|
||||
message_id: int,
|
||||
new_timestamp: bool = Query(default=False),
|
||||
) -> dict[str, object]:
|
||||
) -> ResendChannelMessageResponse:
|
||||
"""Resend a channel message.
|
||||
|
||||
When new_timestamp=False (default): byte-perfect resend using the original timestamp.
|
||||
|
||||
@@ -8,6 +8,7 @@ from typing import Any
|
||||
from fastapi import HTTPException
|
||||
from meshcore import EventType
|
||||
|
||||
from app.models import ResendChannelMessageResponse
|
||||
from app.region_scope import normalize_region_scope
|
||||
from app.repository import AppSettingsRepository, ContactRepository, MessageRepository
|
||||
from app.services.messages import (
|
||||
@@ -437,7 +438,7 @@ async def resend_channel_message_record(
|
||||
now_fn: NowFn,
|
||||
temp_radio_slot: int,
|
||||
message_repository=MessageRepository,
|
||||
) -> dict[str, Any]:
|
||||
) -> ResendChannelMessageResponse:
|
||||
"""Resend a stored outgoing channel message."""
|
||||
try:
|
||||
key_bytes = bytes.fromhex(message.conversation_key)
|
||||
@@ -530,7 +531,11 @@ async def resend_channel_message_record(
|
||||
new_message.id,
|
||||
channel.name,
|
||||
)
|
||||
return {"status": "ok", "message_id": new_message.id, "message": new_message}
|
||||
return ResendChannelMessageResponse(
|
||||
status="ok",
|
||||
message_id=new_message.id,
|
||||
message=new_message,
|
||||
)
|
||||
|
||||
logger.info("Resent channel message %d to %s", message.id, channel.name)
|
||||
return {"status": "ok", "message_id": message.id}
|
||||
return ResendChannelMessageResponse(status="ok", message_id=message.id)
|
||||
|
||||
@@ -20,6 +20,7 @@ import type {
|
||||
RadioDiscoveryResponse,
|
||||
RadioDiscoveryTarget,
|
||||
PathDiscoveryResponse,
|
||||
ResendChannelMessageResponse,
|
||||
RepeaterAclResponse,
|
||||
RepeaterAdvertIntervalsResponse,
|
||||
RepeaterLoginResponse,
|
||||
@@ -34,12 +35,6 @@ import type {
|
||||
UnreadCounts,
|
||||
} from './types';
|
||||
|
||||
export interface ResendChannelMessageResponse {
|
||||
status: string;
|
||||
message_id: number;
|
||||
message?: Message;
|
||||
}
|
||||
|
||||
const API_BASE = '/api';
|
||||
|
||||
async function fetchJson<T>(url: string, options?: RequestInit): Promise<T> {
|
||||
|
||||
@@ -247,6 +247,12 @@ export interface MessagesAroundResponse {
|
||||
has_newer: boolean;
|
||||
}
|
||||
|
||||
export interface ResendChannelMessageResponse {
|
||||
status: string;
|
||||
message_id: number;
|
||||
message?: Message;
|
||||
}
|
||||
|
||||
type ConversationType = 'contact' | 'channel' | 'raw' | 'map' | 'visualizer' | 'search';
|
||||
|
||||
export interface Conversation {
|
||||
|
||||
@@ -632,8 +632,8 @@ class TestResendChannelMessage:
|
||||
):
|
||||
result = await resend_channel_message(msg_id, new_timestamp=False)
|
||||
|
||||
assert result["status"] == "ok"
|
||||
assert result["message_id"] == msg_id
|
||||
assert result.status == "ok"
|
||||
assert result.message_id == msg_id
|
||||
|
||||
# Verify radio was called with correct timestamp bytes
|
||||
mc.commands.send_chan_msg.assert_awaited_once()
|
||||
@@ -731,7 +731,7 @@ class TestResendChannelMessage:
|
||||
):
|
||||
result = await resend_channel_message(msg_id, new_timestamp=False)
|
||||
|
||||
assert result["status"] == "ok"
|
||||
assert result.status == "ok"
|
||||
mock_broadcast_error.assert_called_once()
|
||||
assert "restore failed" in mock_broadcast_error.call_args.args[0].lower()
|
||||
|
||||
@@ -762,15 +762,16 @@ class TestResendChannelMessage:
|
||||
mock_time.time.return_value = float(now)
|
||||
result = await resend_channel_message(msg_id, new_timestamp=True)
|
||||
|
||||
assert result["status"] == "ok"
|
||||
assert result["message_id"] != msg_id
|
||||
resent = await MessageRepository.get_by_id(result["message_id"])
|
||||
assert result.status == "ok"
|
||||
assert result.message_id != msg_id
|
||||
resent = await MessageRepository.get_by_id(result.message_id)
|
||||
assert resent is not None
|
||||
assert result["message"].id == resent.id
|
||||
assert result["message"].conversation_key == resent.conversation_key
|
||||
assert result["message"].text == resent.text
|
||||
assert result["message"].sender_timestamp == resent.sender_timestamp
|
||||
assert result["message"].outgoing is True
|
||||
assert result.message is not None
|
||||
assert result.message.id == resent.id
|
||||
assert result.message.conversation_key == resent.conversation_key
|
||||
assert result.message.text == resent.text
|
||||
assert result.message.sender_timestamp == resent.sender_timestamp
|
||||
assert result.message.outgoing is True
|
||||
assert resent.sender_timestamp == now + 1
|
||||
assert resent.received_at == now
|
||||
sent_timestamp = int.from_bytes(
|
||||
@@ -896,9 +897,9 @@ class TestResendChannelMessage:
|
||||
):
|
||||
result = await resend_channel_message(msg_id, new_timestamp=True)
|
||||
|
||||
assert result["status"] == "ok"
|
||||
assert result.status == "ok"
|
||||
# Should return a NEW message id, not the original
|
||||
assert result["message_id"] != msg_id
|
||||
assert result.message_id != msg_id
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resend_new_timestamp_creates_new_message(self, test_db):
|
||||
@@ -925,7 +926,7 @@ class TestResendChannelMessage:
|
||||
):
|
||||
result = await resend_channel_message(msg_id, new_timestamp=True)
|
||||
|
||||
new_msg_id = result["message_id"]
|
||||
new_msg_id = result.message_id
|
||||
new_msg = await MessageRepository.get_by_id(new_msg_id)
|
||||
original_msg = await MessageRepository.get_by_id(msg_id)
|
||||
|
||||
@@ -963,7 +964,7 @@ class TestResendChannelMessage:
|
||||
mock_broadcast.assert_called_once()
|
||||
event_type, event_data = mock_broadcast.call_args.args
|
||||
assert event_type == "message"
|
||||
assert event_data["id"] == result["message_id"]
|
||||
assert event_data["id"] == result.message_id
|
||||
assert event_data["outgoing"] is True
|
||||
assert event_data["channel_name"] == "#broadcast"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user