Merge branch 'dev' of https://git.science.uu.nl/ics/sp/2025/n25b/pepperplus-cb into feat/10-basic-gestures
This commit is contained in:
@@ -11,7 +11,6 @@ from control_backend.schemas.ri_message import RIEndpoint
|
||||
|
||||
@pytest.fixture
|
||||
def zmq_context(mocker):
|
||||
"""Mock the ZMQ context."""
|
||||
mock_context = mocker.patch(
|
||||
"control_backend.agents.actuation.robot_gesture_agent.azmq.Context.instance"
|
||||
)
|
||||
@@ -59,19 +58,16 @@ async def test_setup_connect(zmq_context, mocker):
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_message_forwards_valid_command():
|
||||
async def test_handle_message_valid_gesture_tag():
|
||||
pubsocket = AsyncMock()
|
||||
|
||||
agent = RobotGestureAgent(
|
||||
"robot_gesture",
|
||||
address="",
|
||||
gesture_tags=["hello"],
|
||||
)
|
||||
agent.pubsocket = pubsocket
|
||||
|
||||
payload = {
|
||||
"endpoint": RIEndpoint.GESTURE_TAG,
|
||||
"data": "hello",
|
||||
}
|
||||
payload = {"endpoint": RIEndpoint.GESTURE_TAG, "data": "hello"}
|
||||
msg = InternalMessage(to="robot", sender="tester", body=json.dumps(payload))
|
||||
|
||||
await agent.handle_message(msg)
|
||||
@@ -80,13 +76,31 @@ async def test_handle_message_forwards_valid_command():
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_message_invalid_payload():
|
||||
async def test_handle_message_invalid_gesture_tag():
|
||||
pubsocket = AsyncMock()
|
||||
agent = RobotGestureAgent("robot_gesture")
|
||||
agent = RobotGestureAgent(
|
||||
"robot_gesture",
|
||||
address="",
|
||||
gesture_tags=["hello"],
|
||||
)
|
||||
agent.pubsocket = pubsocket
|
||||
|
||||
payload = {"endpoint": RIEndpoint.GESTURE_TAG, "data": "nope"}
|
||||
msg = InternalMessage(to="robot", sender="tester", body=json.dumps(payload))
|
||||
|
||||
await agent.handle_message(msg)
|
||||
|
||||
pubsocket.send_json.assert_not_awaited()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_message_invalid_payload_logged():
|
||||
pubsocket = AsyncMock()
|
||||
agent = RobotGestureAgent("robot_gesture", address="")
|
||||
agent.pubsocket = pubsocket
|
||||
agent.logger = MagicMock()
|
||||
|
||||
msg = InternalMessage(to="robot", sender="tester", body=json.dumps({"bad": "data"}))
|
||||
msg = InternalMessage(to="robot", sender="tester", body="not json")
|
||||
|
||||
await agent.handle_message(msg)
|
||||
|
||||
@@ -95,22 +109,25 @@ async def test_handle_message_invalid_payload():
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_zmq_command_loop_valid_payload():
|
||||
"""UI command with valid payload is published."""
|
||||
command = {"endpoint": RIEndpoint.GESTURE_TAG, "data": "hello"}
|
||||
async def test_zmq_command_loop_valid_gesture():
|
||||
fake_socket = AsyncMock()
|
||||
|
||||
async def recv_once():
|
||||
agent._running = False
|
||||
return (b"command", json.dumps(command).encode("utf-8"))
|
||||
return b"command", json.dumps(
|
||||
{"endpoint": RIEndpoint.GESTURE_TAG, "data": "hello"}
|
||||
).encode()
|
||||
|
||||
fake_socket.recv_multipart = recv_once
|
||||
fake_socket.send_json = AsyncMock()
|
||||
|
||||
agent = RobotGestureAgent("robot_gesture")
|
||||
agent = RobotGestureAgent(
|
||||
"robot_gesture",
|
||||
address="",
|
||||
gesture_tags=["hello"],
|
||||
)
|
||||
agent.subsocket = fake_socket
|
||||
agent.pubsocket = fake_socket
|
||||
agent.gesture_data = ["hello", "yes", "no"] # ← REQUIRED for legacy check
|
||||
agent._running = True
|
||||
|
||||
await agent._zmq_command_loop()
|
||||
@@ -119,17 +136,23 @@ async def test_zmq_command_loop_valid_payload():
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_zmq_command_loop_ignores_send_gestures():
|
||||
async def test_zmq_command_loop_invalid_tag():
|
||||
fake_socket = AsyncMock()
|
||||
|
||||
async def recv_once():
|
||||
agent._running = False
|
||||
return (b"send_gestures", b"{}")
|
||||
return b"command", json.dumps(
|
||||
{"endpoint": RIEndpoint.GESTURE_TAG, "data": "invalid"}
|
||||
).encode()
|
||||
|
||||
fake_socket.recv_multipart = recv_once
|
||||
fake_socket.send_json = AsyncMock()
|
||||
|
||||
agent = RobotGestureAgent("robot_gesture")
|
||||
agent = RobotGestureAgent(
|
||||
"robot_gesture",
|
||||
address="",
|
||||
gesture_tags=["hello"],
|
||||
)
|
||||
agent.subsocket = fake_socket
|
||||
agent.pubsocket = fake_socket
|
||||
agent._running = True
|
||||
@@ -140,7 +163,28 @@ async def test_zmq_command_loop_ignores_send_gestures():
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_gestures_tags_all():
|
||||
async def test_zmq_command_loop_ignores_send_gestures_topic():
|
||||
fake_socket = AsyncMock()
|
||||
|
||||
async def recv_once():
|
||||
agent._running = False
|
||||
return b"send_gestures", b"{}"
|
||||
|
||||
fake_socket.recv_multipart = recv_once
|
||||
fake_socket.send_json = AsyncMock()
|
||||
|
||||
agent = RobotGestureAgent("robot_gesture", address="")
|
||||
agent.subsocket = fake_socket
|
||||
agent.pubsocket = fake_socket
|
||||
agent._running = True
|
||||
|
||||
await agent._zmq_command_loop()
|
||||
|
||||
fake_socket.send_json.assert_not_awaited()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_gestures_tags():
|
||||
fake_repsocket = AsyncMock()
|
||||
|
||||
async def recv_once():
|
||||
@@ -152,6 +196,7 @@ async def test_fetch_gestures_tags_all():
|
||||
|
||||
agent = RobotGestureAgent(
|
||||
"robot_gesture",
|
||||
address="",
|
||||
gesture_tags=["hello", "yes", "no"],
|
||||
)
|
||||
agent.repsocket = fake_repsocket
|
||||
@@ -163,31 +208,7 @@ async def test_fetch_gestures_tags_all():
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_gestures_tags_with_count():
|
||||
fake_repsocket = AsyncMock()
|
||||
|
||||
async def recv_once():
|
||||
agent._running = False
|
||||
return {"type": "tags", "count": 2}
|
||||
|
||||
fake_repsocket.recv_json = recv_once
|
||||
fake_repsocket.send_json = AsyncMock()
|
||||
|
||||
agent = RobotGestureAgent(
|
||||
"robot_gesture",
|
||||
gesture_tags=["hello", "yes", "no"],
|
||||
)
|
||||
agent.repsocket = fake_repsocket
|
||||
agent._running = True
|
||||
|
||||
await agent._fetch_gestures_loop()
|
||||
|
||||
fake_repsocket.send_json.assert_awaited_once_with({"tags": ["hello", "yes"]})
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_gestures_basic_new():
|
||||
"""NEW: fetch basic gestures"""
|
||||
async def test_fetch_gestures_basic():
|
||||
fake_repsocket = AsyncMock()
|
||||
|
||||
async def recv_once():
|
||||
@@ -199,6 +220,7 @@ async def test_fetch_gestures_basic_new():
|
||||
|
||||
agent = RobotGestureAgent(
|
||||
"robot_gesture",
|
||||
address="",
|
||||
gesture_basic=["wave", "point"],
|
||||
)
|
||||
agent.repsocket = fake_repsocket
|
||||
@@ -220,48 +242,10 @@ async def test_fetch_gestures_unknown_type():
|
||||
fake_repsocket.recv_json = recv_once
|
||||
fake_repsocket.send_json = AsyncMock()
|
||||
|
||||
agent = RobotGestureAgent("robot_gesture")
|
||||
agent = RobotGestureAgent("robot_gesture", address="")
|
||||
agent.repsocket = fake_repsocket
|
||||
agent._running = True
|
||||
|
||||
await agent._fetch_gestures_loop()
|
||||
|
||||
fake_repsocket.send_json.assert_awaited_once_with({})
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_gestures_exception_logged():
|
||||
fake_repsocket = AsyncMock()
|
||||
|
||||
async def recv_once():
|
||||
agent._running = False
|
||||
raise Exception("boom")
|
||||
|
||||
fake_repsocket.recv_json = recv_once
|
||||
fake_repsocket.send_json = AsyncMock()
|
||||
|
||||
agent = RobotGestureAgent("robot_gesture")
|
||||
agent.repsocket = fake_repsocket
|
||||
agent.logger = MagicMock()
|
||||
agent._running = True
|
||||
|
||||
await agent._fetch_gestures_loop()
|
||||
|
||||
agent.logger.exception.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_stop_closes_sockets():
|
||||
pubsocket = MagicMock()
|
||||
subsocket = MagicMock()
|
||||
repsocket = MagicMock()
|
||||
|
||||
agent = RobotGestureAgent("robot_gesture")
|
||||
agent.pubsocket = pubsocket
|
||||
agent.subsocket = subsocket
|
||||
agent.repsocket = repsocket
|
||||
|
||||
await agent.stop()
|
||||
|
||||
pubsocket.close.assert_called_once()
|
||||
subsocket.close.assert_called_once()
|
||||
|
||||
Reference in New Issue
Block a user