|
|
@@ -2,6 +2,11 @@ from unittest import IsolatedAsyncioTestCase
|
|
|
from unittest.mock import AsyncMock, patch, PropertyMock
|
|
|
from uuid import uuid4
|
|
|
|
|
|
+from homeassistant.components.light import COLOR_MODE_ONOFF
|
|
|
+from homeassistant.components.lock import STATE_LOCKED, STATE_UNLOCKED
|
|
|
+from homeassistant.components.switch import DEVICE_CLASS_SWITCH
|
|
|
+from homeassistant.const import STATE_UNAVAILABLE
|
|
|
+
|
|
|
from custom_components.tuya_local.generic.climate import TuyaLocalClimate
|
|
|
from custom_components.tuya_local.generic.fan import TuyaLocalFan
|
|
|
from custom_components.tuya_local.generic.humidifier import TuyaLocalHumidifier
|
|
|
@@ -17,6 +22,8 @@ from custom_components.tuya_local.helpers.device_config import (
|
|
|
possible_matches,
|
|
|
)
|
|
|
|
|
|
+from ..helpers import assert_device_properties_set
|
|
|
+
|
|
|
DEVICE_TYPES = {
|
|
|
"climate": TuyaLocalClimate,
|
|
|
"fan": TuyaLocalFan,
|
|
|
@@ -106,3 +113,199 @@ class TuyaDeviceTestCase(IsolatedAsyncioTestCase):
|
|
|
await e.async_update()
|
|
|
self.mock_device.async_refresh.assert_called_once()
|
|
|
result.assert_awaited()
|
|
|
+
|
|
|
+
|
|
|
+# Mixins for common test functions
|
|
|
+
|
|
|
+
|
|
|
+class SwitchableTests:
|
|
|
+ def setUpSwitchable(self, dps, subject):
|
|
|
+ self.switch_dps = dps
|
|
|
+ self.switch_subject = subject
|
|
|
+
|
|
|
+ def test_switchable_is_on(self):
|
|
|
+ self.dps[self.switch_dps] = True
|
|
|
+ self.assertTrue(self.switch_subject.is_on)
|
|
|
+
|
|
|
+ self.dps[self.switch_dps] = False
|
|
|
+ self.assertFalse(self.switch_subject.is_on)
|
|
|
+
|
|
|
+ self.dps[self.switch_dps] = None
|
|
|
+ self.assertIsNone(self.switch_subject.is_on)
|
|
|
+
|
|
|
+ async def test_switchable_turn_on(self):
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.switch_subject._device, {self.switch_dps: True}
|
|
|
+ ):
|
|
|
+ await self.switch_subject.async_turn_on()
|
|
|
+
|
|
|
+ async def test_switchable_turn_off(self):
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.switch_subject._device, {self.switch_dps: False}
|
|
|
+ ):
|
|
|
+ await self.switch_subject.async_turn_off()
|
|
|
+
|
|
|
+ async def test_switchable_toggle(self):
|
|
|
+ self.dps[self.switch_dps] = False
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.switch_subject._device, {self.switch_dps: True}
|
|
|
+ ):
|
|
|
+ await self.switch_subject.async_toggle()
|
|
|
+
|
|
|
+ self.dps[self.switch_dps] = True
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.switch_subject._device, {self.switch_dps: False}
|
|
|
+ ):
|
|
|
+ await self.switch_subject.async_toggle()
|
|
|
+
|
|
|
+
|
|
|
+class BasicLightTests:
|
|
|
+ def setUpBasicLight(self, dps, subject):
|
|
|
+ self.basicLight = subject
|
|
|
+ self.basicLightDps = dps
|
|
|
+
|
|
|
+ def test_basic_light_supported_color_modes(self):
|
|
|
+ self.assertCountEqual(
|
|
|
+ self.basicLight.supported_color_modes,
|
|
|
+ [COLOR_MODE_ONOFF],
|
|
|
+ )
|
|
|
+
|
|
|
+ def test_basic_light_color_mode(self):
|
|
|
+ self.assertEqual(self.basicLight.color_mode, COLOR_MODE_ONOFF)
|
|
|
+
|
|
|
+ def test_light_has_no_brightness(self):
|
|
|
+ self.assertIsNone(self.basicLight.brightness)
|
|
|
+
|
|
|
+ def test_light_has_no_effects(self):
|
|
|
+ self.assertIsNone(self.basicLight.effect_list)
|
|
|
+ self.assertIsNone(self.basicLight.effect)
|
|
|
+
|
|
|
+ def test_basic_light_is_on(self):
|
|
|
+ self.dps[self.basicLightDps] = True
|
|
|
+ self.assertTrue(self.basicLight.is_on)
|
|
|
+ self.dps[self.basicLightDps] = False
|
|
|
+ self.assertFalse(self.basicLight.is_on)
|
|
|
+
|
|
|
+ async def test_basic_light_turn_on(self):
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.basicLight._device, {self.basicLightDps: True}
|
|
|
+ ):
|
|
|
+ await self.basicLight.async_turn_on()
|
|
|
+
|
|
|
+ async def test_basic_light_turn_off(self):
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.basicLight._device, {self.basicLightDps: False}
|
|
|
+ ):
|
|
|
+ await self.basicLight.async_turn_off()
|
|
|
+
|
|
|
+ async def test_basic_light_toggle_turns_on_when_it_was_off(self):
|
|
|
+ self.dps[self.basicLightDps] = False
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.basicLight._device,
|
|
|
+ {self.basicLightDps: True},
|
|
|
+ ):
|
|
|
+ await self.basicLight.async_toggle()
|
|
|
+
|
|
|
+ async def test_basic_light_toggle_turns_off_when_it_was_on(self):
|
|
|
+ self.dps[self.basicLightDps] = True
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.basicLight._device,
|
|
|
+ {self.basicLightDps: False},
|
|
|
+ ):
|
|
|
+ await self.basicLight.async_toggle()
|
|
|
+
|
|
|
+ def test_basic_light_state_attributes(self):
|
|
|
+ self.assertEqual(self.basicLight.device_state_attributes, {})
|
|
|
+
|
|
|
+
|
|
|
+class BasicLockTests:
|
|
|
+ def setUpBasicLock(self, dps, subject):
|
|
|
+ self.basicLock = subject
|
|
|
+ self.basicLockDps = dps
|
|
|
+
|
|
|
+ def test_basic_lock_state(self):
|
|
|
+ self.dps[self.basicLockDps] = True
|
|
|
+ self.assertEqual(self.basicLock.state, STATE_LOCKED)
|
|
|
+
|
|
|
+ self.dps[self.basicLockDps] = False
|
|
|
+ self.assertEqual(self.basicLock.state, STATE_UNLOCKED)
|
|
|
+
|
|
|
+ self.dps[self.basicLockDps] = None
|
|
|
+ self.assertEqual(self.basicLock.state, STATE_UNAVAILABLE)
|
|
|
+
|
|
|
+ def test_basic_lock_is_locked(self):
|
|
|
+ self.dps[self.basicLockDps] = True
|
|
|
+ self.assertTrue(self.basicLock.is_locked)
|
|
|
+
|
|
|
+ self.dps[self.basicLockDps] = False
|
|
|
+ self.assertFalse(self.basicLock.is_locked)
|
|
|
+
|
|
|
+ self.dps[self.basicLockDps] = None
|
|
|
+ self.assertFalse(self.basicLock.is_locked)
|
|
|
+
|
|
|
+ async def test_basic_lock_locks(self):
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.basicLock._device,
|
|
|
+ {self.basicLockDps: True},
|
|
|
+ ):
|
|
|
+ await self.basicLock.async_lock()
|
|
|
+
|
|
|
+ async def test_basic_lock_unlocks(self):
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.basicLock._device,
|
|
|
+ {self.basicLockDps: False},
|
|
|
+ ):
|
|
|
+ await self.basicLock.async_unlock()
|
|
|
+
|
|
|
+ def test_basic_lock_state_attributes(self):
|
|
|
+ self.assertEqual(self.basicLock.device_state_attributes, {})
|
|
|
+
|
|
|
+
|
|
|
+class BasicSwitchTests:
|
|
|
+ def setUpBasicSwitch(self, dps, subject):
|
|
|
+ self.basicSwitch = subject
|
|
|
+ self.basicSwitchDps = dps
|
|
|
+
|
|
|
+ def test_basic_switch_is_on(self):
|
|
|
+ self.dps[self.basicSwitchDps] = True
|
|
|
+ self.assertEqual(self.basicSwitch.is_on, True)
|
|
|
+
|
|
|
+ self.dps[self.basicSwitchDps] = False
|
|
|
+ self.assertEqual(self.basicSwitch.is_on, False)
|
|
|
+
|
|
|
+ async def test_basic_switch_turn_on(self):
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.basicSwitch._device, {self.basicSwitchDps: True}
|
|
|
+ ):
|
|
|
+ await self.basicSwitch.async_turn_on()
|
|
|
+
|
|
|
+ async def test_basic_switch_turn_off(self):
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.basicSwitch._device, {self.basicSwitchDps: False}
|
|
|
+ ):
|
|
|
+ await self.basicSwitch.async_turn_off()
|
|
|
+
|
|
|
+ async def test_basic_switch_toggle_turns_on_when_it_was_off(self):
|
|
|
+ self.dps[self.basicSwitchDps] = False
|
|
|
+
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.basicSwitch._device, {self.basicSwitchDps: True}
|
|
|
+ ):
|
|
|
+ await self.basicSwitch.async_toggle()
|
|
|
+
|
|
|
+ async def test_basic_switch_toggle_turns_off_when_it_was_on(self):
|
|
|
+ self.dps[self.basicSwitchDps] = True
|
|
|
+
|
|
|
+ async with assert_device_properties_set(
|
|
|
+ self.basicSwitch._device, {self.basicSwitchDps: False}
|
|
|
+ ):
|
|
|
+ await self.basicSwitch.async_toggle()
|
|
|
+
|
|
|
+ def test_basic_switch_class_is_switch(self):
|
|
|
+ self.assertEqual(self.basicSwitch.device_class, DEVICE_CLASS_SWITCH)
|
|
|
+
|
|
|
+ def test_basic_switch_has_no_power_monitoring(self):
|
|
|
+ self.assertIsNone(self.basicSwitch.current_power_w)
|
|
|
+
|
|
|
+ def test_basic_switch_state_attributes(self):
|
|
|
+ self.assertEqual(self.basicSwitch.device_state_attributes, {})
|