|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
5 | 5 | import asyncio |
| 6 | +import json |
6 | 7 | from typing import Any |
7 | 8 | from unittest.mock import AsyncMock, MagicMock, Mock, patch |
8 | 9 |
|
@@ -323,6 +324,38 @@ async def test_blerpc_call_incomplete_data( |
323 | 324 | await ble_rpc.call("Shelly.GetDeviceInfo") |
324 | 325 |
|
325 | 326 |
|
| 327 | +@pytest.mark.asyncio |
| 328 | +@pytest.mark.usefixtures("mock_establish_connection") |
| 329 | +async def test_blerpc_call_corrupted_frame_length_valid_json( |
| 330 | + ble_device: BLEDevice, mock_ble_client: MagicMock |
| 331 | +) -> None: |
| 332 | + """Test BLE RPC call with corrupted frame length but valid complete JSON. |
| 333 | +
|
| 334 | + Workaround for firmware bug where RX control returns wrong frame length |
| 335 | + but the actual data is complete valid JSON. |
| 336 | + """ |
| 337 | + ble_rpc = BleRPC(ble_device) |
| 338 | + |
| 339 | + mock_ble_client.write_gatt_char = AsyncMock() |
| 340 | + mock_ble_client.read_gatt_char = AsyncMock() |
| 341 | + |
| 342 | + response = {"id": 1, "src": "test", "result": {"name": "Test Device"}} |
| 343 | + response_bytes = json.dumps(response).encode() |
| 344 | + |
| 345 | + # Mock RX control says 840106079 bytes (corrupted), but we get complete JSON |
| 346 | + mock_ble_client.read_gatt_char.side_effect = [ |
| 347 | + (840106079).to_bytes(4, "big"), # Corrupted frame length |
| 348 | + response_bytes, # Complete valid JSON response |
| 349 | + b"", # Empty chunk (no more data) |
| 350 | + ] |
| 351 | + |
| 352 | + await ble_rpc.connect() |
| 353 | + |
| 354 | + # Should succeed despite corrupted frame length because JSON is valid |
| 355 | + result = await ble_rpc.call("Shelly.GetDeviceInfo") |
| 356 | + assert result == {"name": "Test Device"} |
| 357 | + |
| 358 | + |
326 | 359 | @pytest.mark.asyncio |
327 | 360 | @pytest.mark.usefixtures("mock_establish_connection") |
328 | 361 | async def test_blerpc_call_invalid_json( |
|
0 commit comments