Stazioni: sorgenti camera lette dall'acquisitore, link Acquisizione (#88)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jbf7qKuxsnAVjxthRy7dnB
This commit is contained in:
@@ -254,3 +254,74 @@ def test_create_station_proxy_forwards_the_camera_fields(logged_in_client, mock_
|
||||
resp = logged_in_client.post("/admin/api/stations", json=body)
|
||||
assert resp.status_code == 201
|
||||
mock_admin_api.post.assert_called_once_with("/api/stations", data=body)
|
||||
|
||||
|
||||
# --- Sorgenti camera lette dall'acquisitore (#88) ---
|
||||
|
||||
def _fake_sources_response(status=200, payload=None):
|
||||
resp = MagicMock()
|
||||
resp.status_code = status
|
||||
resp.json.return_value = payload
|
||||
return resp
|
||||
|
||||
|
||||
def test_camera_sources_proxy_keeps_only_the_three_fields(logged_in_client, mock_admin_api):
|
||||
payload = {"sources": [
|
||||
{"name": "camera:folder", "label": "Cartella", "kind": "folder", "extra": 1},
|
||||
{"name": "camera:123", "label": "Basler", "kind": "gige"},
|
||||
]}
|
||||
with patch("blueprints.admin.http_requests.get",
|
||||
return_value=_fake_sources_response(200, payload)) as get:
|
||||
resp = logged_in_client.get("/admin/api/camera/sources?url=http://acq:8765/")
|
||||
assert resp.status_code == 200
|
||||
assert resp.get_json()["sources"][0] == {
|
||||
"name": "camera:folder", "label": "Cartella", "kind": "folder"}
|
||||
assert len(resp.get_json()["sources"]) == 2
|
||||
assert get.call_args.args[0] == "http://acq:8765/camera/sources"
|
||||
assert get.call_args.kwargs["timeout"] == 5
|
||||
|
||||
|
||||
@pytest.mark.parametrize("url", ["ftp://x", "", "http://", "acq:8765"])
|
||||
def test_camera_sources_proxy_rejects_invalid_url(logged_in_client, mock_admin_api, url):
|
||||
with patch("blueprints.admin.http_requests.get") as get:
|
||||
resp = logged_in_client.get("/admin/api/camera/sources", query_string={"url": url})
|
||||
assert resp.status_code == 400
|
||||
assert resp.get_json()["error"] is True
|
||||
get.assert_not_called()
|
||||
|
||||
|
||||
def test_camera_sources_proxy_unreachable_is_502(logged_in_client, mock_admin_api):
|
||||
import requests
|
||||
with patch("blueprints.admin.http_requests.get",
|
||||
side_effect=requests.ConnectionError("rifiutata")):
|
||||
resp = logged_in_client.get("/admin/api/camera/sources?url=http://acq:8765")
|
||||
assert resp.status_code == 502
|
||||
assert "rifiutata" in resp.get_json()["detail"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("status,payload", [(200, {"altro": 1}), (200, {"sources": "x"}), (500, {"sources": []})])
|
||||
def test_camera_sources_proxy_invalid_response_is_502(logged_in_client, mock_admin_api, status, payload):
|
||||
with patch("blueprints.admin.http_requests.get",
|
||||
return_value=_fake_sources_response(status, payload)):
|
||||
resp = logged_in_client.get("/admin/api/camera/sources?url=http://acq:8765")
|
||||
assert resp.status_code == 502
|
||||
|
||||
|
||||
def test_camera_sources_proxy_non_admin_is_redirected(client, mock_admin_api):
|
||||
with client.session_transaction() as sess:
|
||||
sess["api_key"] = "test-key"
|
||||
sess["user"] = {"id": 2, "username": "operator", "roles": ["MeasurementTec"],
|
||||
"is_admin": False, "active": True}
|
||||
sess["user_id"] = 2
|
||||
with patch("blueprints.admin.http_requests.get") as get:
|
||||
resp = client.get("/admin/api/camera/sources?url=http://acq:8765")
|
||||
assert resp.status_code in (301, 302)
|
||||
get.assert_not_called()
|
||||
|
||||
|
||||
def test_station_form_has_the_camera_sources_picker(logged_in_client, mock_admin_api):
|
||||
mock_admin_api.get.return_value = []
|
||||
html = logged_in_client.get("/admin/stations").get_data(as_text=True)
|
||||
assert "cameraSourcesList" in html
|
||||
assert "loadCameraSources" in html
|
||||
assert "/acquisizione" in html
|
||||
|
||||
@@ -120,7 +120,7 @@ class TestStationCameraCalibration:
|
||||
assert resp.status_code == 200
|
||||
assert body["state"] == "calibrated"
|
||||
assert body["calibration"]["px_per_mm"] == 20.03
|
||||
assert body["calibration_url"] == "http://acq:8765/calibrazione"
|
||||
assert body["calibration_url"] == "http://acq:8765/acquisizione"
|
||||
args, kwargs = get.call_args
|
||||
assert args[0] == "http://acq:8765/camera/calibration"
|
||||
assert kwargs["params"] == {"source": "camera:folder"}
|
||||
@@ -130,7 +130,7 @@ class TestStationCameraCalibration:
|
||||
resp, _ = self._get(logged_in_client, _fake(404, b"{}", {"detail": "no"}))
|
||||
assert resp.status_code == 200
|
||||
assert resp.get_json()["state"] == "uncalibrated"
|
||||
assert resp.get_json()["calibration_url"] == "http://acq:8765/calibrazione"
|
||||
assert resp.get_json()["calibration_url"] == "http://acq:8765/acquisizione"
|
||||
|
||||
def test_unreachable(self, logged_in_client, mock_api_client):
|
||||
_stations(mock_api_client)
|
||||
|
||||
Reference in New Issue
Block a user