1
0
Эх сурвалжийг харах

Add test cases for curtain direction.

Dominick Meglio 1 жил өмнө
parent
commit
6e74622f91

+ 1 - 0
requirements_dev.txt

@@ -1,5 +1,6 @@
 pytest-asyncio
 pytest-cov
+pytest-mock
 bleak>=0.17.0
 bleak-retry-connector>=3.4.0
 cryptography>=38.0.3

+ 195 - 0
tests/test_curtain.py

@@ -0,0 +1,195 @@
+import pytest
+
+from typing import Any
+
+from bleak.backends.device import BLEDevice
+
+from switchbot import SwitchBotAdvertisement, SwitchbotModel
+from switchbot.devices import curtain
+
+from test_adv_parser import generate_ble_device
+
+
+def set_advertisement_data(ble_device: BLEDevice, in_motion: bool, position: int):
+    """Set advertisement data with defaults."""
+    
+    return SwitchBotAdvertisement(
+        address="aa:bb:cc:dd:ee:ff",
+        data={
+            "rawAdvData": b"c\xc0X\x00\x11\x04",
+            "data": {
+                "calibration": True,
+                "battery": 88,
+                "inMotion": in_motion,
+                "position": position,
+                "lightLevel": 1,
+                "deviceChain": 1,
+            },
+            "isEncrypted": False,
+            "model": "c",
+            "modelFriendlyName": "Curtain",
+            "modelName": SwitchbotModel.CURTAIN,
+        },
+        device=ble_device,
+        rssi=-80,
+        active=True,
+    )
+
+@pytest.mark.parametrize("reverse_mode", [(True),(False)])
+def test_device_passive_not_in_motion(reverse_mode):
+    """Test passive not in motion advertisement."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    curtain_device = curtain.SwitchbotCurtain(ble_device, reverse_mode=reverse_mode)
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, False, 0))
+
+    assert curtain_device.is_opening() == False
+    assert curtain_device.is_closing() == False
+
+@pytest.mark.parametrize("reverse_mode", [(True),(False)])
+def test_device_passive_opening(reverse_mode):
+    """Test passive opening advertisement."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    curtain_device = curtain.SwitchbotCurtain(ble_device, reverse_mode=reverse_mode)
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 0))
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 10))
+
+    assert curtain_device.is_opening() == True
+    assert curtain_device.is_closing() == False
+
+@pytest.mark.parametrize("reverse_mode", [(True),(False)])
+def test_device_passive_closing(reverse_mode):
+    """Test passive closing advertisement."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    curtain_device = curtain.SwitchbotCurtain(ble_device, reverse_mode=reverse_mode)
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 100))
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 90))
+
+    assert curtain_device.is_opening() == False
+    assert curtain_device.is_closing() == True
+
+@pytest.mark.parametrize("reverse_mode", [(True),(False)])
+def test_device_passive_opening_then_stop(reverse_mode):
+    """Test passive stopped after opening advertisement."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    curtain_device = curtain.SwitchbotCurtain(ble_device, reverse_mode=reverse_mode)
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 0))
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 10))
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, False, 10))
+
+    assert curtain_device.is_opening() == False
+    assert curtain_device.is_closing() == False
+
+@pytest.mark.parametrize("reverse_mode", [(True),(False)])
+def test_device_passive_closing_then_stop(reverse_mode):
+    """Test passive stopped after closing advertisement."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    curtain_device = curtain.SwitchbotCurtain(ble_device, reverse_mode=reverse_mode)
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 100))
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 90))
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, False, 90))
+
+    assert curtain_device.is_opening() == False
+    assert curtain_device.is_closing() == False
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("reverse_mode", [(True),(False)])
+async def test_device_active_not_in_motion(mocker, reverse_mode):
+    """Test active not in motion."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    curtain_device = curtain.SwitchbotCurtain(ble_device, reverse_mode=reverse_mode)
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, False, 0))
+
+    basic_info = bytes([0,0,0,0,0,0,100,0])
+    async def custom_implementation():
+        return basic_info
+
+    mocker.patch.object(curtain_device, '_get_basic_info', side_effect=custom_implementation)
+
+    await curtain_device.get_basic_info()
+
+    assert curtain_device.is_opening() == False
+    assert curtain_device.is_closing() == False
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("reverse_mode", [(True),(False)])
+async def test_device_active_opening(mocker, reverse_mode):
+    """Test active opening."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    curtain_device = curtain.SwitchbotCurtain(ble_device, reverse_mode=reverse_mode)
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 0))
+
+    basic_info = bytes([0,0,0,0,0,67,10,0])
+    async def custom_implementation():
+        return basic_info
+
+    mocker.patch.object(curtain_device, '_get_basic_info', side_effect=custom_implementation)
+
+    await curtain_device.get_basic_info()
+
+    assert curtain_device.is_opening() == True
+    assert curtain_device.is_closing() == False
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("reverse_mode", [(True),(False)])
+async def test_device_active_closing(mocker, reverse_mode):
+    """Test active closing."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    curtain_device = curtain.SwitchbotCurtain(ble_device, reverse_mode=reverse_mode)
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 100))
+
+    basic_info = bytes([0,0,0,0,0,67,90,0])
+    async def custom_implementation():
+        return basic_info
+
+    mocker.patch.object(curtain_device, '_get_basic_info', side_effect=custom_implementation)
+
+    await curtain_device.get_basic_info()
+
+    assert curtain_device.is_opening() == False
+    assert curtain_device.is_closing() == True
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("reverse_mode", [(True),(False)])
+async def test_device_active_opening_then_stop(mocker, reverse_mode):
+    """Test active stopped after opening."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    curtain_device = curtain.SwitchbotCurtain(ble_device, reverse_mode=reverse_mode)
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 0))
+
+    basic_info = bytes([0,0,0,0,0,67,10,0])
+    async def custom_implementation():
+        return basic_info
+
+    mocker.patch.object(curtain_device, '_get_basic_info', side_effect=custom_implementation)
+
+    await curtain_device.get_basic_info()
+
+    basic_info = bytes([0,0,0,0,0,0,10,0])
+
+    await curtain_device.get_basic_info()
+
+    assert curtain_device.is_opening() == False
+    assert curtain_device.is_closing() == False
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("reverse_mode", [(True),(False)])
+async def test_device_active_closing_then_stop(mocker, reverse_mode):
+    """Test active stopped after closing."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    curtain_device = curtain.SwitchbotCurtain(ble_device, reverse_mode=reverse_mode)
+    curtain_device.update_from_advertisement(set_advertisement_data(ble_device, True, 100))
+
+    basic_info = bytes([0,0,0,0,0,67,90,0])
+    async def custom_implementation():
+        return basic_info
+
+    mocker.patch.object(curtain_device, '_get_basic_info', side_effect=custom_implementation)
+
+    await curtain_device.get_basic_info()
+
+    basic_info = bytes([0,0,0,0,0,0,90,0])
+
+    await curtain_device.get_basic_info()
+
+    assert curtain_device.is_opening() == False
+    assert curtain_device.is_closing() == False