Bump tuyaha to 0.0.10 and fix set temperature issues (#45732)

This commit is contained in:
ollo69 2021-02-16 03:20:45 +01:00 committed by GitHub
parent 1bb535aa67
commit 3c26235e78
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 318 additions and 52 deletions

View file

@ -2,11 +2,47 @@
from unittest.mock import Mock, patch
import pytest
from tuyaha.devices.climate import STEP_HALVES
from tuyaha.tuyaapi import TuyaAPIException, TuyaNetException
from homeassistant import config_entries, data_entry_flow, setup
from homeassistant.components.tuya.const import CONF_COUNTRYCODE, DOMAIN
from homeassistant.const import CONF_PASSWORD, CONF_PLATFORM, CONF_USERNAME
from homeassistant import config_entries, data_entry_flow
from homeassistant.components.tuya.config_flow import (
CONF_LIST_DEVICES,
ERROR_DEV_MULTI_TYPE,
ERROR_DEV_NOT_CONFIG,
ERROR_DEV_NOT_FOUND,
RESULT_AUTH_FAILED,
RESULT_CONN_ERROR,
RESULT_SINGLE_INSTANCE,
)
from homeassistant.components.tuya.const import (
CONF_BRIGHTNESS_RANGE_MODE,
CONF_COUNTRYCODE,
CONF_CURR_TEMP_DIVIDER,
CONF_DISCOVERY_INTERVAL,
CONF_MAX_KELVIN,
CONF_MAX_TEMP,
CONF_MIN_KELVIN,
CONF_MIN_TEMP,
CONF_QUERY_DEVICE,
CONF_QUERY_INTERVAL,
CONF_SET_TEMP_DIVIDED,
CONF_SUPPORT_COLOR,
CONF_TEMP_DIVIDER,
CONF_TEMP_STEP_OVERRIDE,
CONF_TUYA_MAX_COLTEMP,
DOMAIN,
TUYA_DATA,
)
from homeassistant.const import (
CONF_PASSWORD,
CONF_PLATFORM,
CONF_UNIT_OF_MEASUREMENT,
CONF_USERNAME,
TEMP_CELSIUS,
)
from .common import CLIMATE_ID, LIGHT_ID, LIGHT_ID_FAKE1, LIGHT_ID_FAKE2, MockTuya
from tests.common import MockConfigEntry
@ -30,9 +66,15 @@ def tuya_fixture() -> Mock:
yield tuya
@pytest.fixture(name="tuya_setup", autouse=True)
def tuya_setup_fixture():
"""Mock tuya entry setup."""
with patch("homeassistant.components.tuya.async_setup_entry", return_value=True):
yield
async def test_user(hass, tuya):
"""Test user config."""
await setup.async_setup_component(hass, "persistent_notification", {})
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
@ -40,15 +82,10 @@ async def test_user(hass, tuya):
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "user"
with patch(
"homeassistant.components.tuya.async_setup", return_value=True
) as mock_setup, patch(
"homeassistant.components.tuya.async_setup_entry", return_value=True
) as mock_setup_entry:
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=TUYA_USER_DATA
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=TUYA_USER_DATA
)
await hass.async_block_till_done()
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["title"] == USERNAME
@ -58,26 +95,15 @@ async def test_user(hass, tuya):
assert result["data"][CONF_PLATFORM] == TUYA_PLATFORM
assert not result["result"].unique_id
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
async def test_import(hass, tuya):
"""Test import step."""
await setup.async_setup_component(hass, "persistent_notification", {})
with patch(
"homeassistant.components.tuya.async_setup",
return_value=True,
) as mock_setup, patch(
"homeassistant.components.tuya.async_setup_entry",
return_value=True,
) as mock_setup_entry:
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=TUYA_USER_DATA,
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=TUYA_USER_DATA,
)
await hass.async_block_till_done()
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["title"] == USERNAME
@ -87,9 +113,6 @@ async def test_import(hass, tuya):
assert result["data"][CONF_PLATFORM] == TUYA_PLATFORM
assert not result["result"].unique_id
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
async def test_abort_if_already_setup(hass, tuya):
"""Test we abort if Tuya is already setup."""
@ -101,7 +124,7 @@ async def test_abort_if_already_setup(hass, tuya):
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "single_instance_allowed"
assert result["reason"] == RESULT_SINGLE_INSTANCE
# Should fail, config exist (flow)
result = await hass.config_entries.flow.async_init(
@ -109,7 +132,7 @@ async def test_abort_if_already_setup(hass, tuya):
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "single_instance_allowed"
assert result["reason"] == RESULT_SINGLE_INSTANCE
async def test_abort_on_invalid_credentials(hass, tuya):
@ -121,14 +144,14 @@ async def test_abort_on_invalid_credentials(hass, tuya):
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "invalid_auth"}
assert result["errors"] == {"base": RESULT_AUTH_FAILED}
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=TUYA_USER_DATA
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "invalid_auth"
assert result["reason"] == RESULT_AUTH_FAILED
async def test_abort_on_connection_error(hass, tuya):
@ -140,11 +163,143 @@ async def test_abort_on_connection_error(hass, tuya):
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "cannot_connect"
assert result["reason"] == RESULT_CONN_ERROR
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=TUYA_USER_DATA
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "cannot_connect"
assert result["reason"] == RESULT_CONN_ERROR
async def test_options_flow(hass):
"""Test config flow options."""
config_entry = MockConfigEntry(
domain=DOMAIN,
data=TUYA_USER_DATA,
)
config_entry.add_to_hass(hass)
# Test check for integration not loaded
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == RESULT_CONN_ERROR
# Load integration and enter options
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
hass.data[DOMAIN] = {TUYA_DATA: MockTuya()}
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"
# Test dev not found error
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={CONF_LIST_DEVICES: [f"light-{LIGHT_ID_FAKE1}"]},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"
assert result["errors"] == {"base": ERROR_DEV_NOT_FOUND}
# Test dev type error
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={CONF_LIST_DEVICES: [f"light-{LIGHT_ID_FAKE2}"]},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"
assert result["errors"] == {"base": ERROR_DEV_NOT_CONFIG}
# Test multi dev error
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={CONF_LIST_DEVICES: [f"climate-{CLIMATE_ID}", f"light-{LIGHT_ID}"]},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"
assert result["errors"] == {"base": ERROR_DEV_MULTI_TYPE}
# Test climate options form
result = await hass.config_entries.options.async_configure(
result["flow_id"], user_input={CONF_LIST_DEVICES: [f"climate-{CLIMATE_ID}"]}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "device"
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
CONF_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
CONF_TEMP_DIVIDER: 10,
CONF_CURR_TEMP_DIVIDER: 5,
CONF_SET_TEMP_DIVIDED: False,
CONF_TEMP_STEP_OVERRIDE: STEP_HALVES,
CONF_MIN_TEMP: 12,
CONF_MAX_TEMP: 22,
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"
# Test light options form
result = await hass.config_entries.options.async_configure(
result["flow_id"], user_input={CONF_LIST_DEVICES: [f"light-{LIGHT_ID}"]}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "device"
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
CONF_SUPPORT_COLOR: True,
CONF_BRIGHTNESS_RANGE_MODE: 1,
CONF_MIN_KELVIN: 4000,
CONF_MAX_KELVIN: 5000,
CONF_TUYA_MAX_COLTEMP: 12000,
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"
# Test common options
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
CONF_DISCOVERY_INTERVAL: 100,
CONF_QUERY_INTERVAL: 50,
CONF_QUERY_DEVICE: LIGHT_ID,
},
)
# Verify results
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
climate_options = config_entry.options[CLIMATE_ID]
assert climate_options[CONF_UNIT_OF_MEASUREMENT] == TEMP_CELSIUS
assert climate_options[CONF_TEMP_DIVIDER] == 10
assert climate_options[CONF_CURR_TEMP_DIVIDER] == 5
assert climate_options[CONF_SET_TEMP_DIVIDED] is False
assert climate_options[CONF_TEMP_STEP_OVERRIDE] == STEP_HALVES
assert climate_options[CONF_MIN_TEMP] == 12
assert climate_options[CONF_MAX_TEMP] == 22
light_options = config_entry.options[LIGHT_ID]
assert light_options[CONF_SUPPORT_COLOR] is True
assert light_options[CONF_BRIGHTNESS_RANGE_MODE] == 1
assert light_options[CONF_MIN_KELVIN] == 4000
assert light_options[CONF_MAX_KELVIN] == 5000
assert light_options[CONF_TUYA_MAX_COLTEMP] == 12000
assert config_entry.options[CONF_DISCOVERY_INTERVAL] == 100
assert config_entry.options[CONF_QUERY_INTERVAL] == 50
assert config_entry.options[CONF_QUERY_DEVICE] == LIGHT_ID