test_mqtt.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import json
  2. import logging
  3. import pathlib
  4. import unittest.mock
  5. import pytest
  6. import intertechno_cc1101_mqtt
  7. # pylint: disable=protected-access
  8. @pytest.mark.parametrize("mqtt_host", ["mqtt-broker.local"])
  9. @pytest.mark.parametrize("mqtt_port", [1833])
  10. def test__run(caplog, mqtt_host, mqtt_port):
  11. with unittest.mock.patch(
  12. "paho.mqtt.client.Client"
  13. ) as mqtt_client_mock, caplog.at_level(logging.DEBUG):
  14. intertechno_cc1101_mqtt._run(
  15. mqtt_host=mqtt_host,
  16. mqtt_port=mqtt_port,
  17. mqtt_username=None,
  18. mqtt_password=None,
  19. alias_file_path=None,
  20. )
  21. assert mqtt_client_mock.call_count == 1
  22. assert not mqtt_client_mock.call_args[0]
  23. assert set(mqtt_client_mock.call_args[1]) == {"userdata"}
  24. event_userdata = mqtt_client_mock.call_args[1]["userdata"]
  25. assert event_userdata.aliases == {}
  26. assert event_userdata.power_setting == 0xC6
  27. assert not mqtt_client_mock().username_pw_set.called
  28. mqtt_client_mock().connect.assert_called_once_with(host=mqtt_host, port=mqtt_port)
  29. mqtt_client_mock().socket().getpeername.return_value = (mqtt_host, mqtt_port)
  30. with caplog.at_level(logging.DEBUG):
  31. mqtt_client_mock().on_connect(mqtt_client_mock(), event_userdata, {}, 0)
  32. # pylint: disable=comparison-with-callable
  33. assert mqtt_client_mock().on_message == intertechno_cc1101_mqtt._mqtt_on_message
  34. mqtt_client_mock().subscribe.assert_called_once_with("intertechno-cc1101/+/+/set")
  35. mqtt_client_mock().loop_forever.assert_called_once_with()
  36. assert caplog.record_tuples == [
  37. (
  38. "intertechno_cc1101_mqtt",
  39. logging.INFO,
  40. "connecting to MQTT broker {}:{}".format(mqtt_host, mqtt_port),
  41. ),
  42. (
  43. "intertechno_cc1101_mqtt",
  44. logging.DEBUG,
  45. "connected to MQTT broker {}:{}".format(mqtt_host, mqtt_port),
  46. ),
  47. (
  48. "intertechno_cc1101_mqtt",
  49. logging.INFO,
  50. "subscribing to MQTT topic 'intertechno-cc1101/+/+/set' (address & button index)",
  51. ),
  52. ]
  53. @pytest.mark.parametrize("mqtt_host", ["mqtt-broker.local"])
  54. @pytest.mark.parametrize("mqtt_port", [1833])
  55. @pytest.mark.parametrize("mqtt_username", ["me"])
  56. @pytest.mark.parametrize("mqtt_password", [None, "secret"])
  57. def test__run_authentication(mqtt_host, mqtt_port, mqtt_username, mqtt_password):
  58. with unittest.mock.patch("paho.mqtt.client.Client") as mqtt_client_mock:
  59. intertechno_cc1101_mqtt._run(
  60. mqtt_host=mqtt_host,
  61. mqtt_port=mqtt_port,
  62. mqtt_username=mqtt_username,
  63. mqtt_password=mqtt_password,
  64. alias_file_path=None,
  65. )
  66. assert mqtt_client_mock.call_count == 1
  67. mqtt_client_mock().username_pw_set.assert_called_once_with(
  68. username=mqtt_username, password=mqtt_password
  69. )
  70. @pytest.mark.parametrize("mqtt_host", ["mqtt-broker.local"])
  71. @pytest.mark.parametrize("mqtt_port", [1833])
  72. @pytest.mark.parametrize("mqtt_password", ["secret"])
  73. def test__run_authentication_missing_username(mqtt_host, mqtt_port, mqtt_password):
  74. with unittest.mock.patch("paho.mqtt.client.Client"):
  75. with pytest.raises(ValueError):
  76. intertechno_cc1101_mqtt._run(
  77. mqtt_host=mqtt_host,
  78. mqtt_port=mqtt_port,
  79. mqtt_username=None,
  80. mqtt_password=mqtt_password,
  81. alias_file_path=None,
  82. )
  83. @pytest.mark.parametrize("mqtt_host", ["mqtt-broker.local"])
  84. @pytest.mark.parametrize("mqtt_port", [1833])
  85. @pytest.mark.parametrize(
  86. "aliases", [{}, {"some-alias": {"address": 12345678, "button-index": 0}}]
  87. )
  88. def test__run_alias_file_path(caplog, tmp_path, mqtt_host, mqtt_port, aliases):
  89. alias_file_path = tmp_path.joinpath("aliases.json")
  90. alias_file_path.write_text(json.dumps(aliases))
  91. assert isinstance(alias_file_path, pathlib.Path)
  92. with unittest.mock.patch("paho.mqtt.client.Client") as mqtt_client_mock:
  93. intertechno_cc1101_mqtt._run(
  94. mqtt_host=mqtt_host,
  95. mqtt_port=mqtt_port,
  96. mqtt_username=None,
  97. mqtt_password=None,
  98. alias_file_path=alias_file_path,
  99. )
  100. assert mqtt_client_mock.call_count == 1
  101. event_userdata = mqtt_client_mock.call_args[1]["userdata"]
  102. assert event_userdata.aliases == aliases
  103. mqtt_client_mock().socket().getpeername.return_value = (mqtt_host, mqtt_port)
  104. with unittest.mock.patch(
  105. "intertechno_cc1101_mqtt._publish_homeassistant_discovery_configs"
  106. ) as publish_discovery_config_mock, caplog.at_level(logging.INFO):
  107. mqtt_client_mock().on_connect(mqtt_client_mock(), event_userdata, {}, 0)
  108. assert mqtt_client_mock().subscribe.call_args_list[0] == unittest.mock.call(
  109. "intertechno-cc1101/+/+/set"
  110. )
  111. assert caplog.record_tuples[0] == (
  112. "intertechno_cc1101_mqtt",
  113. logging.INFO,
  114. "subscribing to MQTT topic 'intertechno-cc1101/+/+/set' (address & button index)",
  115. )
  116. if len(aliases) == 0:
  117. assert mqtt_client_mock().subscribe.call_count == 1
  118. assert len(caplog.records) == 1
  119. publish_discovery_config_mock.assert_not_called()
  120. else:
  121. assert mqtt_client_mock().subscribe.call_count == 2
  122. assert len(caplog.records) == 2
  123. assert mqtt_client_mock().subscribe.call_args_list[1] == unittest.mock.call(
  124. "intertechno-cc1101/+/set"
  125. )
  126. assert caplog.record_tuples[1] == (
  127. "intertechno_cc1101_mqtt",
  128. logging.INFO,
  129. "subscribing to MQTT topic 'intertechno-cc1101/+/set' (alias)",
  130. )
  131. publish_discovery_config_mock.assert_called_once_with(
  132. mqtt_client=mqtt_client_mock(), aliases=aliases
  133. )