"""Tests for the Python CLI.""" import json from click.testing import CliRunner from zb_mom_ww_mxgateway import __version__ from zb_mom_ww_mxgateway_cli.commands import main _BATCH_EOR = "__MXGW_BATCH_EOR__" def test_version_json_is_deterministic() -> None: runner = CliRunner() result = runner.invoke(main, ["version", "--json"]) assert result.exit_code == 0 assert json.loads(result.output) == { "client": "mxgw-py", "package": "mxaccess-gateway-client", "version": __version__, } def test_write_parser_rejects_unknown_value_type() -> None: runner = CliRunner() result = runner.invoke( main, [ "write", "--session-id", "session-1", "--server-handle", "12", "--item-handle", "34", "--type", "unsupported", "--value", "123", "--api-key", "mxgw_test_secret", "--json", ], ) assert result.exit_code != 0 assert "unsupported value type" in result.output def test_stream_alarms_is_registered() -> None: runner = CliRunner() result = runner.invoke(main, ["stream-alarms", "--help"]) assert result.exit_code == 0 assert "--filter-prefix" in result.output assert "--max-messages" in result.output def test_acknowledge_alarm_requires_reference() -> None: runner = CliRunner() result = runner.invoke( main, ["acknowledge-alarm", "--api-key", "mxgw_test_secret", "--json"], ) assert result.exit_code != 0 assert "--reference" in result.output def test_cli_error_output_redacts_api_key() -> None: runner = CliRunner() result = runner.invoke( main, [ "open-session", "--endpoint", "127.0.0.1:1", "--api-key", "mxgw_test_secret", "--plaintext", "--json", ], ) assert result.exit_code != 0 assert "mxgw_test_secret" not in result.output def test_batch_runs_version_command_and_writes_eor() -> None: runner = CliRunner() result = runner.invoke(main, ["batch"], input="version --json\n") assert result.exit_code == 0 blocks = [block for block in result.output.split(_BATCH_EOR + "\n") if block] assert len(blocks) == 1 payload = json.loads(blocks[0].strip()) assert payload == { "client": "mxgw-py", "package": "mxaccess-gateway-client", "version": __version__, } def test_batch_terminates_on_empty_line() -> None: runner = CliRunner() result = runner.invoke( main, ["batch"], input="version --json\n\nversion --json\n", ) assert result.exit_code == 0 # Only the first command runs; the empty line breaks the loop before the second. assert result.output.count(_BATCH_EOR) == 1 def test_batch_continues_after_error_line() -> None: runner = CliRunner() # First line is invalid (unknown subcommand), second is a valid version call. result = runner.invoke( main, ["batch"], input="not-a-real-command\nversion --json\n", ) assert result.exit_code == 0 assert result.output.count(_BATCH_EOR) == 2 blocks = [block for block in result.output.split(_BATCH_EOR + "\n") if block] assert len(blocks) == 2 # First block: error JSON ({"error": "...", "type": "..."}). error_payload = json.loads(blocks[0].strip().splitlines()[-1]) assert "error" in error_payload assert "type" in error_payload # Second block: successful version JSON. version_payload = json.loads(blocks[1].strip()) assert version_payload["version"] == __version__