From 1ea32885a37e7380fbcbc1b05c59df90ac749681 Mon Sep 17 00:00:00 2001 From: jkingsman Date: Tue, 23 Dec 2025 17:50:28 -0800 Subject: [PATCH] Add typing to send_chan_message with test --- src/meshcore/commands/messaging.py | 20 +++++++++++++++----- tests/unit/test_commands.py | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/meshcore/commands/messaging.py b/src/meshcore/commands/messaging.py index 195e56d..c48e50c 100644 --- a/src/meshcore/commands/messaging.py +++ b/src/meshcore/commands/messaging.py @@ -141,17 +141,27 @@ class MessagingCommands(CommandHandlerBase): return None if res is None else result - async def send_chan_msg(self, chan, msg, timestamp=None) -> Event: + async def send_chan_msg(self, chan: int, msg: str, timestamp: Optional[int|bytes] = None) -> Event: logger.debug(f"Sending channel message to channel {chan}: {msg}") - # Default to current time if timestamp not provided if timestamp is None: + # Default to current time if timestamp not provided import time - - timestamp = int(time.time()).to_bytes(4, "little") + timestamp_bytes = int(time.time()).to_bytes(4, "little") + elif isinstance(timestamp, int): + timestamp_bytes = timestamp.to_bytes(4, "little") + elif isinstance(timestamp, bytes) and len(timestamp) == 4: + # expected bytes format + timestamp_bytes = timestamp + else: + if isinstance(timestamp, bytes): + logger.error(f"Invalid timestamp format: got bytes of length {len(timestamp)} but expected bytes of length 4") + else: + logger.error(f"Invalid timestamp format: got {type(timestamp)} but expected int or 4 bytes") + return Event(EventType.ERROR, {"reason": "invalid_timestamp_format"}) data = ( - b"\x03\x00" + chan.to_bytes(1, "little") + timestamp + msg.encode("utf-8") + b"\x03\x00" + chan.to_bytes(1, "little") + timestamp_bytes + msg.encode("utf-8") ) return await self.send(data, [EventType.OK, EventType.ERROR]) diff --git a/tests/unit/test_commands.py b/tests/unit/test_commands.py index 91d531b..eb3170a 100644 --- a/tests/unit/test_commands.py +++ b/tests/unit/test_commands.py @@ -318,3 +318,26 @@ async def test_set_channel(command_handler, mock_connection): async def test_set_channel_invalid_secret_length(command_handler): with pytest.raises(ValueError, match="Channel secret must be exactly 16 bytes"): await command_handler.set_channel(1, "Test", b"tooshort") + + +async def test_send_chan_msg_with_str_timestamp(command_handler, mock_connection): + ts = 1620000000 + await command_handler.send_chan_msg(3, "world", timestamp=ts) + data = mock_connection.send.call_args[0][0] + assert data.startswith(b"\x03\x00\x03") + assert b"world" in data + assert data[3:7] == ts.to_bytes(4, "little") + +async def test_send_chan_msg_with_bytes_timestamp(command_handler, mock_connection): + ts = 1620000000 + await command_handler.send_chan_msg(3, "world", timestamp=ts.to_bytes(4, "little")) + data = mock_connection.send.call_args[0][0] + assert data.startswith(b"\x03\x00\x03") + assert b"world" in data + assert data[3:7] == ts.to_bytes(4, "little") + +async def test_send_chan_msg_with_invalid_timestamp(command_handler, mock_connection): + result = await command_handler.send_chan_msg(3, "world", timestamp=b"00") + + assert result.type == EventType.ERROR + assert result.payload["reason"] == "invalid_timestamp_format"