"""Tests for typed command error mapping.""" import json from pathlib import Path import pytest from google.protobuf.json_format import ParseDict from zb_mom_ww_mxgateway.errors import ensure_mxaccess_success, ensure_protocol_success from zb_mom_ww_mxgateway import MxAccessError, MxGatewaySessionError from zb_mom_ww_mxgateway.generated import mxaccess_gateway_pb2 as pb FIXTURE_ROOT = Path(__file__).resolve().parents[2] / "proto" / "fixtures" / "behavior" def test_register_fixture_is_protocol_and_mxaccess_success() -> None: reply = _load_reply("command-replies/register.ok.reply.json") assert ensure_protocol_success("register", reply.protocol_status, reply) is reply assert ensure_mxaccess_success("register", reply) is reply def test_write_failure_fixture_preserves_raw_reply() -> None: reply = _load_reply("command-replies/write.mxaccess-failure.reply.json") assert ensure_protocol_success("write", reply.protocol_status, reply) is reply with pytest.raises(MxAccessError) as captured: ensure_mxaccess_success("write", reply) assert captured.value.raw_reply is reply assert captured.value.raw_reply.hresult == -2147220992 assert len(captured.value.raw_reply.statuses) == 2 @pytest.mark.parametrize( ("fixture", "expect_failure"), [ ("command-replies/register.ok.reply.json", False), ("command-replies/write.status-category-error-success-set.reply.json", True), ("command-replies/write.status-category-ok-success-zero.reply.json", False), ("command-replies/write.hresult-s-false.reply.json", False), ("command-replies/write.hresult-e-fail.reply.json", True), ], ) def test_reply_validation_fixtures_branch_on_category_and_negative_hresult( fixture: str, expect_failure: bool, ) -> None: reply = _load_reply(fixture) if expect_failure: with pytest.raises(MxAccessError): ensure_mxaccess_success("write", reply) else: assert ensure_mxaccess_success("write", reply) is reply @pytest.mark.parametrize( ("category", "success", "expect_failure"), [ (pb.MX_STATUS_CATEGORY_OK, 0, False), (pb.MX_STATUS_CATEGORY_OK, 1, False), (pb.MX_STATUS_CATEGORY_COMMUNICATION_ERROR, 1, True), (pb.MX_STATUS_CATEGORY_UNSPECIFIED, 1, True), ], ) def test_status_entry_verdict_ignores_the_raw_success_member( category: int, success: int, expect_failure: bool, ) -> None: reply = pb.MxCommandReply( protocol_status=pb.ProtocolStatus(code=pb.PROTOCOL_STATUS_CODE_OK), statuses=[pb.MxStatusProxy(success=success, category=category)], ) if expect_failure: with pytest.raises(MxAccessError): ensure_mxaccess_success("write", reply) else: assert ensure_mxaccess_success("write", reply) is reply def test_session_status_maps_to_session_error() -> None: status = pb.ProtocolStatus( code=pb.PROTOCOL_STATUS_CODE_SESSION_NOT_FOUND, message="session missing", ) with pytest.raises(MxGatewaySessionError) as captured: ensure_protocol_success("invoke", status) assert captured.value.protocol_status is status def _load_reply(name: str) -> pb.MxCommandReply: payload = json.loads((FIXTURE_ROOT / name).read_text(encoding="utf-8")) return ParseDict(payload, pb.MxCommandReply())