chore: fixed sending stuff to ui
This commit is contained in:
@@ -78,7 +78,8 @@ async def get_available_gesture_tags(request: Request, count=0):
|
||||
amount = count or None
|
||||
timeout = 5 # seconds
|
||||
|
||||
await req_socket.send(f"{amount}".encode() if amount else b"None")
|
||||
await req_socket.send_json({"type": "tags", "count": amount})
|
||||
|
||||
try:
|
||||
body = await asyncio.wait_for(req_socket.recv(), timeout=timeout)
|
||||
except TimeoutError:
|
||||
@@ -94,7 +95,7 @@ async def get_available_gesture_tags(request: Request, count=0):
|
||||
logger.error(f"Failed to parse gesture tags JSON: {e}, body: {body}")
|
||||
# Return empty list on JSON error
|
||||
available_tags = []
|
||||
return {"available_gesture_tags": available_tags}
|
||||
return {"available_gestures": available_tags}
|
||||
|
||||
|
||||
@router.get("/commands/gesture/single")
|
||||
|
||||
@@ -229,120 +229,60 @@ async def test_ping_stream_yields_json_values(monkeypatch):
|
||||
mock_sub_socket.recv_multipart.assert_awaited()
|
||||
|
||||
|
||||
# ----------------------------
|
||||
# Updated get_available_gesture_tags tests (REQ socket on tcp://localhost:7788)
|
||||
# ----------------------------
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_available_gesture_tags_success(client, monkeypatch):
|
||||
async def test_get_available_single_gestures_success(client, monkeypatch):
|
||||
"""
|
||||
Test successful retrieval of available gesture tags using a REQ socket.
|
||||
Test successful retrieval of single gestures.
|
||||
"""
|
||||
# Arrange
|
||||
mock_req_socket = AsyncMock(spec=zmq.asyncio.Socket)
|
||||
mock_req_socket.connect = MagicMock()
|
||||
mock_req_socket.send = AsyncMock()
|
||||
response_data = {"tags": ["wave", "nod", "point", "dance"]}
|
||||
mock_req_socket.send_json = AsyncMock()
|
||||
response_data = {"single_gestures": ["wave", "point"]}
|
||||
mock_req_socket.recv = AsyncMock(return_value=json.dumps(response_data).encode())
|
||||
|
||||
mock_context = MagicMock()
|
||||
mock_context.socket.return_value = mock_req_socket
|
||||
monkeypatch.setattr(robot.Context, "instance", lambda: mock_context)
|
||||
|
||||
# Replace logger methods to avoid noisy logs in tests
|
||||
monkeypatch.setattr(robot.logger, "debug", MagicMock())
|
||||
monkeypatch.setattr(robot.logger, "error", MagicMock())
|
||||
|
||||
# Act
|
||||
response = client.get("/commands/gesture/tags")
|
||||
response = client.get("/commands/gesture/single")
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"available_gesture_tags": ["wave", "nod", "point", "dance"]}
|
||||
assert response.json() == {"available_gestures": ["wave", "point"]}
|
||||
|
||||
# Verify ZeroMQ REQ interactions
|
||||
mock_req_socket.connect.assert_called_once_with("tcp://localhost:7788")
|
||||
mock_req_socket.send.assert_awaited_once_with(b"None")
|
||||
mock_req_socket.send_json.assert_awaited_once_with({"type": "single", "count": None})
|
||||
mock_req_socket.recv.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_available_gesture_tags_with_amount(client, monkeypatch):
|
||||
"""
|
||||
The endpoint currently ignores the 'amount' TODO, so behavior is the same as 'success'.
|
||||
This test asserts that the endpoint still sends b"None" and returns the tags.
|
||||
"""
|
||||
# Arrange
|
||||
async def test_get_available_single_gestures_timeout(client, monkeypatch):
|
||||
mock_req_socket = AsyncMock(spec=zmq.asyncio.Socket)
|
||||
mock_req_socket.connect = MagicMock()
|
||||
mock_req_socket.send = AsyncMock()
|
||||
response_data = {"tags": ["wave", "nod"]}
|
||||
mock_req_socket.recv = AsyncMock(return_value=json.dumps(response_data).encode())
|
||||
|
||||
mock_context = MagicMock()
|
||||
mock_context.socket.return_value = mock_req_socket
|
||||
monkeypatch.setattr(robot.Context, "instance", lambda: mock_context)
|
||||
|
||||
monkeypatch.setattr(robot.logger, "debug", MagicMock())
|
||||
monkeypatch.setattr(robot.logger, "error", MagicMock())
|
||||
|
||||
# Act
|
||||
response = client.get("/commands/gesture/tags")
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"available_gesture_tags": ["wave", "nod"]}
|
||||
|
||||
mock_req_socket.connect.assert_called_once_with("tcp://localhost:7788")
|
||||
mock_req_socket.send.assert_awaited_once_with(b"None")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_available_gesture_tags_timeout(client, monkeypatch):
|
||||
"""
|
||||
Test timeout scenario when fetching gesture tags. Endpoint should handle TimeoutError
|
||||
and return an empty list while logging the timeout.
|
||||
"""
|
||||
# Arrange
|
||||
mock_req_socket = AsyncMock(spec=zmq.asyncio.Socket)
|
||||
mock_req_socket.connect = MagicMock()
|
||||
mock_req_socket.send = AsyncMock()
|
||||
mock_req_socket.send_json = AsyncMock()
|
||||
mock_req_socket.recv = AsyncMock(side_effect=TimeoutError)
|
||||
|
||||
mock_context = MagicMock()
|
||||
mock_context.socket.return_value = mock_req_socket
|
||||
monkeypatch.setattr(robot.Context, "instance", lambda: mock_context)
|
||||
|
||||
# Patch logger.debug so we can assert it was called with the expected message
|
||||
mock_debug = MagicMock()
|
||||
monkeypatch.setattr(robot.logger, "debug", mock_debug)
|
||||
monkeypatch.setattr(robot.logger, "error", MagicMock())
|
||||
response = client.get("/commands/gesture/single")
|
||||
|
||||
# Act
|
||||
response = client.get("/commands/gesture/tags")
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"available_gesture_tags": []}
|
||||
|
||||
# Verify the timeout was logged using the exact string from the endpoint code
|
||||
mock_debug.assert_called_once_with("Got timeout error fetching gestures.")
|
||||
|
||||
mock_req_socket.connect.assert_called_once_with("tcp://localhost:7788")
|
||||
mock_req_socket.send.assert_awaited_once_with(b"None")
|
||||
mock_req_socket.recv.assert_awaited_once()
|
||||
assert response.json() == {"available_gestures": []}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_available_gesture_tags_empty_response(client, monkeypatch):
|
||||
async def test_get_available_single_gestures_missing_key(client, monkeypatch):
|
||||
"""
|
||||
Test scenario when response contains an empty 'tags' list.
|
||||
Test response missing 'single_gestures' key.
|
||||
"""
|
||||
# Arrange
|
||||
mock_req_socket = AsyncMock(spec=zmq.asyncio.Socket)
|
||||
mock_req_socket.connect = MagicMock()
|
||||
mock_req_socket.send = AsyncMock()
|
||||
response_data = {"tags": []}
|
||||
mock_req_socket.recv = AsyncMock(return_value=json.dumps(response_data).encode())
|
||||
mock_req_socket.send_json = AsyncMock()
|
||||
mock_req_socket.recv = AsyncMock(return_value=json.dumps({"unexpected": "value"}).encode())
|
||||
|
||||
mock_context = MagicMock()
|
||||
mock_context.socket.return_value = mock_req_socket
|
||||
@@ -351,52 +291,21 @@ async def test_get_available_gesture_tags_empty_response(client, monkeypatch):
|
||||
monkeypatch.setattr(robot.logger, "debug", MagicMock())
|
||||
monkeypatch.setattr(robot.logger, "error", MagicMock())
|
||||
|
||||
# Act
|
||||
response = client.get("/commands/gesture/tags")
|
||||
response = client.get("/commands/gesture/single")
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"available_gesture_tags": []}
|
||||
assert response.json() == {"available_gestures": []}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_available_gesture_tags_missing_tags_key(client, monkeypatch):
|
||||
async def test_get_available_single_gestures_invalid_json(client, monkeypatch):
|
||||
"""
|
||||
Test scenario when response JSON doesn't contain 'tags' key.
|
||||
Test invalid JSON response for single gestures.
|
||||
"""
|
||||
# Arrange
|
||||
mock_req_socket = AsyncMock(spec=zmq.asyncio.Socket)
|
||||
mock_req_socket.connect = MagicMock()
|
||||
mock_req_socket.send = AsyncMock()
|
||||
response_data = {"some_other_key": "value"}
|
||||
mock_req_socket.recv = AsyncMock(return_value=json.dumps(response_data).encode())
|
||||
|
||||
mock_context = MagicMock()
|
||||
mock_context.socket.return_value = mock_req_socket
|
||||
monkeypatch.setattr(robot.Context, "instance", lambda: mock_context)
|
||||
|
||||
monkeypatch.setattr(robot.logger, "debug", MagicMock())
|
||||
monkeypatch.setattr(robot.logger, "error", MagicMock())
|
||||
|
||||
# Act
|
||||
response = client.get("/commands/gesture/tags")
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"available_gesture_tags": []}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_available_gesture_tags_invalid_json(client, monkeypatch):
|
||||
"""
|
||||
Test scenario when response contains invalid JSON. Endpoint should log the error
|
||||
and return an empty list.
|
||||
"""
|
||||
# Arrange
|
||||
mock_req_socket = AsyncMock(spec=zmq.asyncio.Socket)
|
||||
mock_req_socket.connect = MagicMock()
|
||||
mock_req_socket.send = AsyncMock()
|
||||
mock_req_socket.recv = AsyncMock(return_value=b"invalid json")
|
||||
mock_req_socket.send_json = AsyncMock()
|
||||
mock_req_socket.recv = AsyncMock(return_value=b"not-json")
|
||||
|
||||
mock_context = MagicMock()
|
||||
mock_context.socket.return_value = mock_req_socket
|
||||
@@ -406,10 +315,78 @@ async def test_get_available_gesture_tags_invalid_json(client, monkeypatch):
|
||||
monkeypatch.setattr(robot.logger, "error", mock_error)
|
||||
monkeypatch.setattr(robot.logger, "debug", MagicMock())
|
||||
|
||||
# Act
|
||||
response = client.get("/commands/gesture/tags")
|
||||
response = client.get("/commands/gesture/single")
|
||||
|
||||
# Assert - invalid JSON should lead to empty list and error log invocation
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"available_gesture_tags": []}
|
||||
assert response.json() == {"available_gestures": []}
|
||||
assert mock_error.call_count == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_available_basic_gestures_success(client, monkeypatch):
|
||||
"""
|
||||
Test successful retrieval of basic gestures.
|
||||
"""
|
||||
mock_req_socket = AsyncMock(spec=zmq.asyncio.Socket)
|
||||
mock_req_socket.connect = MagicMock()
|
||||
mock_req_socket.send_json = AsyncMock()
|
||||
response_data = {"basic_gestures": ["nod", "shake"]}
|
||||
mock_req_socket.recv = AsyncMock(return_value=json.dumps(response_data).encode())
|
||||
|
||||
mock_context = MagicMock()
|
||||
mock_context.socket.return_value = mock_req_socket
|
||||
monkeypatch.setattr(robot.Context, "instance", lambda: mock_context)
|
||||
|
||||
monkeypatch.setattr(robot.logger, "debug", MagicMock())
|
||||
monkeypatch.setattr(robot.logger, "error", MagicMock())
|
||||
|
||||
response = client.get("/commands/gesture/basic")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"available_gestures": ["nod", "shake"]}
|
||||
|
||||
mock_req_socket.connect.assert_called_once_with("tcp://localhost:7788")
|
||||
mock_req_socket.send_json.assert_awaited_once_with({"type": "basic", "count": None})
|
||||
mock_req_socket.recv.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_available_basic_gestures_timeout(client, monkeypatch):
|
||||
mock_req_socket = AsyncMock(spec=zmq.asyncio.Socket)
|
||||
mock_req_socket.connect = MagicMock()
|
||||
mock_req_socket.send_json = AsyncMock()
|
||||
mock_req_socket.recv = AsyncMock(side_effect=TimeoutError)
|
||||
|
||||
mock_context = MagicMock()
|
||||
mock_context.socket.return_value = mock_req_socket
|
||||
monkeypatch.setattr(robot.Context, "instance", lambda: mock_context)
|
||||
|
||||
response = client.get("/commands/gesture/basic")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"available_gestures": []}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_available_basic_gestures_invalid_json(client, monkeypatch):
|
||||
"""
|
||||
Test invalid JSON response for basic gestures.
|
||||
"""
|
||||
mock_req_socket = AsyncMock(spec=zmq.asyncio.Socket)
|
||||
mock_req_socket.connect = MagicMock()
|
||||
mock_req_socket.send_json = AsyncMock()
|
||||
mock_req_socket.recv = AsyncMock(return_value=b"{invalid json")
|
||||
|
||||
mock_context = MagicMock()
|
||||
mock_context.socket.return_value = mock_req_socket
|
||||
monkeypatch.setattr(robot.Context, "instance", lambda: mock_context)
|
||||
|
||||
mock_error = MagicMock()
|
||||
monkeypatch.setattr(robot.logger, "error", mock_error)
|
||||
monkeypatch.setattr(robot.logger, "debug", MagicMock())
|
||||
|
||||
response = client.get("/commands/gesture/basic")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"available_gestures": []}
|
||||
assert mock_error.call_count == 1
|
||||
|
||||
Reference in New Issue
Block a user