96 lines
3.4 KiB
Python
96 lines
3.4 KiB
Python
"""Integration test del router /api/right_arm/*."""
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
from presa_mano.main import app
|
|
|
|
client = TestClient(app)
|
|
|
|
|
|
def _fake_wrist_response():
|
|
return {
|
|
"left_wrist": {"position": [0.10, 0.20, 0.30], "quaternion": [0, 0, 0, 1]},
|
|
"right_wrist": {"position": [0.30, -0.20, 0.30], "quaternion": [0, 0, 0, 1]},
|
|
}
|
|
|
|
|
|
def test_state_returns_wrist_pose_and_config():
|
|
with patch("presa_mano.api.right_arm_routes._deps.g1") as g1_factory:
|
|
g1 = MagicMock()
|
|
g1.wrist.return_value = _fake_wrist_response()
|
|
g1_factory.return_value = g1
|
|
|
|
r = client.get("/api/right_arm/state")
|
|
assert r.status_code == 200
|
|
body = r.json()
|
|
assert body["wrist"]["position"] == [0.30, -0.20, 0.30]
|
|
assert "rpy_deg" in body["wrist"]
|
|
assert body["side"] == "right" or body["side"] in ("left", "right")
|
|
assert "home_pose" in body
|
|
assert "custom_pose" in body
|
|
assert "offset_camera_mm" in body
|
|
assert "axis_signs" in body
|
|
assert "max_step_m" in body
|
|
assert "z_floor_m" in body
|
|
assert "robot_active" in body
|
|
assert "timings_ms" in body
|
|
|
|
|
|
def test_state_502_when_g1_unavailable():
|
|
from presa_mano.clients import G1Unavailable
|
|
with patch("presa_mano.api.right_arm_routes._deps.g1") as g1_factory:
|
|
g1 = MagicMock()
|
|
g1.wrist.side_effect = G1Unavailable("connection refused")
|
|
g1_factory.return_value = g1
|
|
r = client.get("/api/right_arm/state")
|
|
assert r.status_code == 502
|
|
|
|
|
|
def test_activate_sets_robot_active_g1_and_side_right():
|
|
# /activate è idempotente: chiama PUT /api/config e ritorna /state
|
|
with patch("presa_mano.api.right_arm_routes._deps.g1") as g1_factory:
|
|
g1 = MagicMock()
|
|
g1.wrist.return_value = _fake_wrist_response()
|
|
g1_factory.return_value = g1
|
|
r = client.post("/api/right_arm/activate")
|
|
assert r.status_code == 200
|
|
body = r.json()
|
|
assert body["robot_active"] == "g1"
|
|
assert body["side"] == "right"
|
|
|
|
|
|
def test_snapshot_front_returns_jpeg():
|
|
fake_jpeg = b"\xff\xd8\xff" + b"\x00" * 100 # magic JPEG bytes
|
|
with patch("presa_mano.api.right_arm_routes._deps.front_camera") as factory:
|
|
cam = MagicMock()
|
|
cam.rgb_jpeg.return_value = fake_jpeg
|
|
factory.return_value = cam
|
|
r = client.get("/api/right_arm/snapshot/front")
|
|
assert r.status_code == 200
|
|
assert r.headers["content-type"].startswith("image/jpeg")
|
|
assert r.content == fake_jpeg
|
|
|
|
|
|
def test_snapshot_wrist_returns_jpeg():
|
|
fake_jpeg = b"\xff\xd8\xff" + b"\x00" * 50
|
|
with patch("presa_mano.api.right_arm_routes._deps.nuwa") as factory:
|
|
cam = MagicMock()
|
|
cam.rgb_jpeg.return_value = fake_jpeg
|
|
factory.return_value = cam
|
|
r = client.get("/api/right_arm/snapshot/wrist")
|
|
assert r.status_code == 200
|
|
assert r.headers["content-type"].startswith("image/jpeg")
|
|
assert r.content == fake_jpeg
|
|
|
|
|
|
def test_snapshot_front_502_on_failure():
|
|
with patch("presa_mano.api.right_arm_routes._deps.front_camera") as factory:
|
|
cam = MagicMock()
|
|
cam.rgb_jpeg.side_effect = RuntimeError("connection refused")
|
|
factory.return_value = cam
|
|
r = client.get("/api/right_arm/snapshot/front")
|
|
assert r.status_code == 502
|