123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- from unittest.mock import AsyncMock
- import pytest
- from bleak.backends.device import BLEDevice
- from switchbot import SwitchBotAdvertisement, SwitchbotModel
- from switchbot.const.fan import FanMode
- from switchbot.devices import fan
- from .test_adv_parser import generate_ble_device
- def create_device_for_command_testing(init_data: dict | None = None):
- ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
- fan_device = fan.SwitchbotFan(ble_device)
- fan_device.update_from_advertisement(make_advertisement_data(ble_device, init_data))
- fan_device._send_command = AsyncMock()
- fan_device.update = AsyncMock()
- return fan_device
- def make_advertisement_data(ble_device: BLEDevice, init_data: dict | None = None):
- """Set advertisement data with defaults."""
- if init_data is None:
- init_data = {}
- return SwitchBotAdvertisement(
- address="aa:bb:cc:dd:ee:ff",
- data={
- "rawAdvData": b"~\x00R",
- "data": {
- "isOn": True,
- "mode": "NORMAL",
- "nightLight": 3,
- "oscillating": False,
- "battery": 60,
- "speed": 50,
- }
- | init_data,
- "isEncrypted": False,
- "model": ",",
- "modelFriendlyName": "Circulator Fan",
- "modelName": SwitchbotModel.CIRCULATOR_FAN,
- },
- device=ble_device,
- rssi=-80,
- active=True,
- )
- @pytest.mark.asyncio
- @pytest.mark.parametrize(
- "response, expected",
- [
- (b"\x00", None),
- (b"\x07", None),
- (b"\x01\x02\x03", b"\x01\x02\x03"),
- ],
- )
- async def test__get_basic_info(response, expected):
- fan_device = create_device_for_command_testing()
- fan_device._send_command = AsyncMock(return_value=response)
- result = await fan_device._get_basic_info(cmd="TEST_CMD")
- assert result == expected
- @pytest.mark.asyncio
- @pytest.mark.parametrize(
- "basic_info,firmware_info", [(True, False), (False, True), (False, False)]
- )
- async def test_get_basic_info_returns_none(basic_info, firmware_info):
- fan_device = create_device_for_command_testing()
- async def mock_get_basic_info(arg):
- if arg == fan.COMMAND_GET_BASIC_INFO:
- return basic_info
- elif arg == fan.DEVICE_GET_BASIC_SETTINGS_KEY:
- return firmware_info
- fan_device._get_basic_info = AsyncMock(side_effect=mock_get_basic_info)
- assert await fan_device.get_basic_info() is None
- @pytest.mark.asyncio
- @pytest.mark.parametrize(
- "basic_info,firmware_info,result",
- [
- (
- bytearray(b"\x01\x02W\x82g\xf5\xde4\x01=dPP\x03\x14P\x00\x00\x00\x00"),
- bytearray(b"\x01W\x0b\x17\x01"),
- [87, True, False, "NORMAL", 61, 1.1],
- ),
- (
- bytearray(b"\x01\x02U\xc2g\xf5\xde4\x04+dPP\x03\x14P\x00\x00\x00\x00"),
- bytearray(b"\x01U\x0b\x17\x01"),
- [85, True, True, "BABY", 43, 1.1],
- ),
- ],
- )
- async def test_get_basic_info(basic_info, firmware_info, result):
- fan_device = create_device_for_command_testing()
- async def mock_get_basic_info(arg):
- if arg == fan.COMMAND_GET_BASIC_INFO:
- return basic_info
- elif arg == fan.DEVICE_GET_BASIC_SETTINGS_KEY:
- return firmware_info
- fan_device._get_basic_info = AsyncMock(side_effect=mock_get_basic_info)
- info = await fan_device.get_basic_info()
- assert info["battery"] == result[0]
- assert info["isOn"] == result[1]
- assert info["oscillating"] == result[2]
- assert info["mode"] == result[3]
- assert info["speed"] == result[4]
- assert info["firmware"] == result[5]
- @pytest.mark.asyncio
- async def test_set_preset_mode():
- fan_device = create_device_for_command_testing({"mode": "BABY"})
- await fan_device.set_preset_mode("BABY")
- assert fan_device.get_current_mode() == "BABY"
- @pytest.mark.asyncio
- async def test_set_set_percentage_with_speed_is_0():
- fan_device = create_device_for_command_testing({"speed": 0, "isOn": False})
- await fan_device.turn_off()
- assert fan_device.get_current_percentage() == 0
- assert fan_device.is_on() is False
- @pytest.mark.asyncio
- async def test_set_set_percentage():
- fan_device = create_device_for_command_testing({"speed": 80})
- await fan_device.set_percentage(80)
- assert fan_device.get_current_percentage() == 80
- @pytest.mark.asyncio
- async def test_set_not_oscillation():
- fan_device = create_device_for_command_testing({"oscillating": False})
- await fan_device.set_oscillation(False)
- assert fan_device.get_oscillating_state() is False
- @pytest.mark.asyncio
- async def test_set_oscillation():
- fan_device = create_device_for_command_testing({"oscillating": True})
- await fan_device.set_oscillation(True)
- assert fan_device.get_oscillating_state() is True
- @pytest.mark.asyncio
- async def test_turn_on():
- fan_device = create_device_for_command_testing({"isOn": True})
- await fan_device.turn_on()
- assert fan_device.is_on() is True
- @pytest.mark.asyncio
- async def test_turn_off():
- fan_device = create_device_for_command_testing({"isOn": False})
- await fan_device.turn_off()
- assert fan_device.is_on() is False
- def test_get_modes():
- assert FanMode.get_modes() == ["NORMAL", "NATURAL", "SLEEP", "BABY"]
|