test_switchbot.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import logging
  2. import unittest.mock
  3. import bluepy.btle
  4. import pytest
  5. import switchbot_mqtt
  6. # pylint: disable=protected-access
  7. @pytest.mark.parametrize("mac_address", ["aa:bb:cc:dd:ee:ff"])
  8. @pytest.mark.parametrize(
  9. "action", [switchbot_mqtt._SwitchbotAction.ON, switchbot_mqtt._SwitchbotAction.OFF]
  10. )
  11. @pytest.mark.parametrize("command_successful", [True, False])
  12. def test__send_command(caplog, mac_address, action, command_successful):
  13. with unittest.mock.patch("switchbot.Switchbot") as switchbot_device_mock:
  14. switchbot_device_mock().turn_on.return_value = command_successful
  15. switchbot_device_mock().turn_off.return_value = command_successful
  16. switchbot_device_mock.reset_mock()
  17. with unittest.mock.patch("switchbot_mqtt._report_state") as report_mock:
  18. with caplog.at_level(logging.INFO):
  19. switchbot_mqtt._send_command(
  20. mqtt_client="dummy",
  21. switchbot_mac_address=mac_address,
  22. action=action,
  23. )
  24. switchbot_device_mock.assert_called_once_with(mac=mac_address)
  25. assert len(caplog.records) == 1
  26. logger, log_level, log_message = caplog.record_tuples[0]
  27. assert logger == "switchbot_mqtt"
  28. if command_successful:
  29. assert log_level == logging.INFO
  30. else:
  31. assert log_level == logging.ERROR
  32. assert "failed" in log_message
  33. assert mac_address in log_message
  34. if action == switchbot_mqtt._SwitchbotAction.ON:
  35. switchbot_device_mock().turn_on.assert_called_once_with()
  36. assert not switchbot_device_mock().turn_off.called
  37. assert "on" in log_message
  38. expected_state = switchbot_mqtt._SwitchbotState.ON
  39. else:
  40. switchbot_device_mock().turn_off.assert_called_once_with()
  41. assert not switchbot_device_mock().turn_on.called
  42. assert "off" in log_message
  43. expected_state = switchbot_mqtt._SwitchbotState.OFF
  44. assert report_mock.called == command_successful
  45. if command_successful:
  46. report_mock.assert_called_once_with(
  47. mqtt_client="dummy",
  48. switchbot_mac_address=mac_address,
  49. switchbot_state=expected_state,
  50. )
  51. @pytest.mark.parametrize("mac_address", ["aa:bb:cc:dd:ee:ff"])
  52. @pytest.mark.parametrize("action", [switchbot_mqtt._SwitchbotAction.ON])
  53. def test__send_command_bluetooth_error(caplog, mac_address, action):
  54. """
  55. paho.mqtt.python>=1.5.1 no longer implicitly suppresses exceptions in callbacks.
  56. verify pySwitchbot catches exceptions raised in bluetooth stack.
  57. https://github.com/Danielhiversen/pySwitchbot/blob/0.8.0/switchbot/__init__.py#L48
  58. https://github.com/Danielhiversen/pySwitchbot/blob/0.8.0/switchbot/__init__.py#L94
  59. """
  60. with unittest.mock.patch(
  61. "bluepy.btle.Peripheral",
  62. side_effect=bluepy.btle.BTLEDisconnectError(
  63. "Failed to connect to peripheral {}, addr type: random".format(mac_address)
  64. ),
  65. ), caplog.at_level(logging.ERROR):
  66. switchbot_mqtt._send_command(
  67. mqtt_client=None, switchbot_mac_address=mac_address, action=action
  68. )
  69. assert caplog.record_tuples == [
  70. (
  71. "switchbot",
  72. logging.ERROR,
  73. "Switchbot communication failed. Stopping trying.",
  74. ),
  75. (
  76. "switchbot_mqtt",
  77. logging.ERROR,
  78. "failed to turn on switchbot {}".format(mac_address),
  79. ),
  80. ]