|
@@ -1,7 +1,5 @@
|
|
|
"""Tests for the number entity."""
|
|
"""Tests for the number entity."""
|
|
|
|
|
|
|
|
-from unittest.mock import AsyncMock, Mock
|
|
|
|
|
-
|
|
|
|
|
import pytest
|
|
import pytest
|
|
|
from pytest_homeassistant_custom_component.common import MockConfigEntry
|
|
from pytest_homeassistant_custom_component.common import MockConfigEntry
|
|
|
|
|
|
|
@@ -11,11 +9,14 @@ from custom_components.tuya_local.const import (
|
|
|
CONF_TYPE,
|
|
CONF_TYPE,
|
|
|
DOMAIN,
|
|
DOMAIN,
|
|
|
)
|
|
)
|
|
|
|
|
+from custom_components.tuya_local.helpers.device_config import TuyaEntityConfig
|
|
|
from custom_components.tuya_local.number import TuyaLocalNumber, async_setup_entry
|
|
from custom_components.tuya_local.number import TuyaLocalNumber, async_setup_entry
|
|
|
|
|
|
|
|
|
|
+from .helpers import assert_device_properties_set, mock_device
|
|
|
|
|
+
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.asyncio
|
|
|
-async def test_init_entry(hass):
|
|
|
|
|
|
|
+async def test_init_entry(hass, mocker):
|
|
|
"""Test the initialisation."""
|
|
"""Test the initialisation."""
|
|
|
entry = MockConfigEntry(
|
|
entry = MockConfigEntry(
|
|
|
domain=DOMAIN,
|
|
domain=DOMAIN,
|
|
@@ -25,8 +26,8 @@ async def test_init_entry(hass):
|
|
|
CONF_PROTOCOL_VERSION: "auto",
|
|
CONF_PROTOCOL_VERSION: "auto",
|
|
|
},
|
|
},
|
|
|
)
|
|
)
|
|
|
- m_add_entities = Mock()
|
|
|
|
|
- m_device = AsyncMock()
|
|
|
|
|
|
|
+ m_add_entities = mocker.Mock()
|
|
|
|
|
+ m_device = mocker.AsyncMock()
|
|
|
|
|
|
|
|
hass.data[DOMAIN] = {
|
|
hass.data[DOMAIN] = {
|
|
|
"dummy": {"device": m_device},
|
|
"dummy": {"device": m_device},
|
|
@@ -38,7 +39,7 @@ async def test_init_entry(hass):
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.asyncio
|
|
|
-async def test_init_entry_fails_if_device_has_no_number(hass):
|
|
|
|
|
|
|
+async def test_init_entry_fails_if_device_has_no_number(hass, mocker):
|
|
|
"""Test initialisation when device has no matching entity"""
|
|
"""Test initialisation when device has no matching entity"""
|
|
|
entry = MockConfigEntry(
|
|
entry = MockConfigEntry(
|
|
|
domain=DOMAIN,
|
|
domain=DOMAIN,
|
|
@@ -48,8 +49,8 @@ async def test_init_entry_fails_if_device_has_no_number(hass):
|
|
|
CONF_PROTOCOL_VERSION: "auto",
|
|
CONF_PROTOCOL_VERSION: "auto",
|
|
|
},
|
|
},
|
|
|
)
|
|
)
|
|
|
- m_add_entities = Mock()
|
|
|
|
|
- m_device = AsyncMock()
|
|
|
|
|
|
|
+ m_add_entities = mocker.Mock()
|
|
|
|
|
+ m_device = mocker.AsyncMock()
|
|
|
|
|
|
|
|
hass.data[DOMAIN] = {
|
|
hass.data[DOMAIN] = {
|
|
|
"dummy": {"device": m_device},
|
|
"dummy": {"device": m_device},
|
|
@@ -63,7 +64,7 @@ async def test_init_entry_fails_if_device_has_no_number(hass):
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.asyncio
|
|
|
-async def test_init_entry_fails_if_config_is_missing(hass):
|
|
|
|
|
|
|
+async def test_init_entry_fails_if_config_is_missing(hass, mocker):
|
|
|
"""Test initialisation when device has no matching entity"""
|
|
"""Test initialisation when device has no matching entity"""
|
|
|
entry = MockConfigEntry(
|
|
entry = MockConfigEntry(
|
|
|
domain=DOMAIN,
|
|
domain=DOMAIN,
|
|
@@ -73,8 +74,8 @@ async def test_init_entry_fails_if_config_is_missing(hass):
|
|
|
CONF_PROTOCOL_VERSION: "auto",
|
|
CONF_PROTOCOL_VERSION: "auto",
|
|
|
},
|
|
},
|
|
|
)
|
|
)
|
|
|
- m_add_entities = Mock()
|
|
|
|
|
- m_device = AsyncMock()
|
|
|
|
|
|
|
+ m_add_entities = mocker.Mock()
|
|
|
|
|
+ m_device = mocker.AsyncMock()
|
|
|
|
|
|
|
|
hass.data[DOMAIN] = {
|
|
hass.data[DOMAIN] = {
|
|
|
"dummy": {"device": m_device},
|
|
"dummy": {"device": m_device},
|
|
@@ -85,3 +86,83 @@ async def test_init_entry_fails_if_config_is_missing(hass):
|
|
|
except ValueError:
|
|
except ValueError:
|
|
|
pass
|
|
pass
|
|
|
m_add_entities.assert_not_called()
|
|
m_add_entities.assert_not_called()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_decimal(mocker):
|
|
|
|
|
+ """Test the decimal property."""
|
|
|
|
|
+ config = {
|
|
|
|
|
+ "entity": "number",
|
|
|
|
|
+ "dps": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": "1",
|
|
|
|
|
+ "type": "integer",
|
|
|
|
|
+ "name": "value",
|
|
|
|
|
+ "range": {
|
|
|
|
|
+ "min": 0,
|
|
|
|
|
+ "max": 100,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": "2",
|
|
|
|
|
+ "type": "integer",
|
|
|
|
|
+ "name": "decimal",
|
|
|
|
|
+ "mapping": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "scale": 10,
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "range": {
|
|
|
|
|
+ "min": 0,
|
|
|
|
|
+ "max": 9,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ }
|
|
|
|
|
+ tuyadevice = mocker.AsyncMock()
|
|
|
|
|
+ dps = {"1": 12, "2": 3}
|
|
|
|
|
+ device = mock_device(dps, mocker)
|
|
|
|
|
+ number = TuyaLocalNumber(device, TuyaEntityConfig(tuyadevice, config))
|
|
|
|
|
+ assert number.native_value == 12.3
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+@pytest.mark.asyncio
|
|
|
|
|
+async def test_set_decimal(mocker):
|
|
|
|
|
+ """Test the decimal property."""
|
|
|
|
|
+ config = {
|
|
|
|
|
+ "entity": "number",
|
|
|
|
|
+ "dps": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": "1",
|
|
|
|
|
+ "type": "integer",
|
|
|
|
|
+ "name": "value",
|
|
|
|
|
+ "range": {
|
|
|
|
|
+ "min": 0,
|
|
|
|
|
+ "max": 100,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ "id": "2",
|
|
|
|
|
+ "type": "integer",
|
|
|
|
|
+ "name": "decimal",
|
|
|
|
|
+ "mapping": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "scale": 10,
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "range": {
|
|
|
|
|
+ "min": 0,
|
|
|
|
|
+ "max": 9,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ }
|
|
|
|
|
+ tuyadevice = mocker.AsyncMock()
|
|
|
|
|
+ dps = {"1": 1, "2": 1}
|
|
|
|
|
+ device = mock_device(dps, mocker)
|
|
|
|
|
+ number = TuyaLocalNumber(device, TuyaEntityConfig(tuyadevice, config))
|
|
|
|
|
+
|
|
|
|
|
+ async with assert_device_properties_set(
|
|
|
|
|
+ device,
|
|
|
|
|
+ {"1": 10, "2": 5},
|
|
|
|
|
+ ):
|
|
|
|
|
+ await number.async_set_native_value(10.5)
|