test_mqtt.py 5.3 KB

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