from unittest.mock import Mock, patch import pytest from pigway_frame_flow.drivers.kokonna.widgets import WidgetReader from pigway_frame_flow.errors import FlowError def test_snapshot_does_not_contact_official_service(): with patch("requests.post") as post: result = WidgetReader().read() assert result.source == "snapshot" assert len(result.catalog) == 75 assert not result.configured and not result.current_verified and not result.writable post.assert_not_called() def test_live_current_and_cache(): response = Mock(status_code=200) response.json.return_value = { "result": { "rows": [ {"id": 29, "name": "古诗词", "tags": [], "args": {"城市": "private"}} ], "frameCoverRobot": { "frameCover": {"id": 29}, "args": {"private": "secret"}, }, } } with patch("requests.post", return_value=response) as post: reader = WidgetReader("official-secret", 123) result = reader.read() assert reader.read() is result assert result.current_verified and result.current.id == 29 assert "private" not in result.model_dump_json() assert "official-secret" not in result.model_dump_json() assert post.call_count == 1 assert post.call_args.kwargs["json"]["method"] == "appFrame.getFrameCovers" assert post.call_args.kwargs["allow_redirects"] is False @pytest.mark.parametrize( "payload", [{"error": {"message": "official-secret"}}, {"result": {}}] ) def test_vendor_errors_are_not_exposed(payload): response = Mock(status_code=200) response.json.return_value = payload with ( patch("requests.post", return_value=response), pytest.raises(FlowError) as error, ): WidgetReader("official-secret", 123).read() assert "official-secret" not in str(error.value) def test_missing_robot_id_never_uses_session(): with patch("requests.post") as post: assert not WidgetReader("secret").read().configured post.assert_not_called() def test_widget_api_mock_and_auth(client): response = client.get("/api/v1/devices/living-room/widgets") assert response.status_code == 200 assert response.json()["source"] == "mock" assert len(response.json()["catalog"]) == 75 client.headers.clear() assert client.get("/api/v1/devices/living-room/widgets").status_code == 401