Add Xiaomi Miio EU gateway support (#47955)
* Add EU gateway support * add options flow translations * fix options flow * fix missing import * try to fix async_add_executor_job * try to fix async_add_executor_job * fix unload * check for login succes * fix not reloading * use cloud option * fix styling * Return after if Co-authored-by: Nathan Tilley <nathan@tilley.xyz> * cleanup * add options flow tests * fix new tests * fix typo in docstring * add missing blank line * Use async_on_unload Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Use async_on_unload Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Use async_setup_platforms Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Use async_unload_platforms Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Update homeassistant/components/xiaomi_miio/__init__.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Update homeassistant/components/xiaomi_miio/const.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * default use_cloud False * add options flow checks * fix styling * fix issort * add MiCloud check tests * fix indent * fix styling * fix tests * fix tests * fix black * re-write config flow * add explicit return type * update strings.json * black formatting * fix config flow Tested the config flow and it is now fully working * fix styling * Fix current tests * Add missing tests * fix styling * add re-auth flow * fix styling * fix reauth flow * Add reauth flow test * use ConfigEntryAuthFailed * also trigger reauth @ login error * fix styling * remove unused import * fix spelling Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Fix spelling Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * fix spelling Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * remove unessesary .keys() Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * combine async_add_executor_job calls * remove async_step_model * fix wrong indent * fix gatway.py * fix tests Co-authored-by: Nathan Tilley <nathan@tilley.xyz> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
8705168fe6
commit
3a2d50fe23
10 changed files with 1050 additions and 198 deletions
|
@ -2,27 +2,86 @@
|
|||
from unittest.mock import Mock, patch
|
||||
|
||||
from miio import DeviceException
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant import config_entries, data_entry_flow
|
||||
from homeassistant.components.xiaomi_miio import const
|
||||
from homeassistant.components.xiaomi_miio.config_flow import DEFAULT_GATEWAY_NAME
|
||||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_TOKEN
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
ZEROCONF_NAME = "name"
|
||||
ZEROCONF_PROP = "properties"
|
||||
ZEROCONF_MAC = "mac"
|
||||
|
||||
TEST_HOST = "1.2.3.4"
|
||||
TEST_HOST2 = "5.6.7.8"
|
||||
TEST_CLOUD_USER = "username"
|
||||
TEST_CLOUD_PASS = "password"
|
||||
TEST_CLOUD_COUNTRY = "cn"
|
||||
TEST_TOKEN = "12345678901234567890123456789012"
|
||||
TEST_NAME = "Test_Gateway"
|
||||
TEST_NAME2 = "Test_Gateway_2"
|
||||
TEST_MODEL = const.MODELS_GATEWAY[0]
|
||||
TEST_MAC = "ab:cd:ef:gh:ij:kl"
|
||||
TEST_MAC2 = "mn:op:qr:st:uv:wx"
|
||||
TEST_MAC_DEVICE = "abcdefghijkl"
|
||||
TEST_MAC_DEVICE2 = "mnopqrstuvwx"
|
||||
TEST_GATEWAY_ID = TEST_MAC
|
||||
TEST_HARDWARE_VERSION = "AB123"
|
||||
TEST_FIRMWARE_VERSION = "1.2.3_456"
|
||||
TEST_ZEROCONF_NAME = "lumi-gateway-v3_miio12345678._miio._udp.local."
|
||||
TEST_SUB_DEVICE_LIST = []
|
||||
TEST_CLOUD_DEVICES_1 = [
|
||||
{
|
||||
"parent_id": None,
|
||||
"name": TEST_NAME,
|
||||
"model": TEST_MODEL,
|
||||
"localip": TEST_HOST,
|
||||
"mac": TEST_MAC_DEVICE,
|
||||
"token": TEST_TOKEN,
|
||||
}
|
||||
]
|
||||
TEST_CLOUD_DEVICES_2 = [
|
||||
{
|
||||
"parent_id": None,
|
||||
"name": TEST_NAME,
|
||||
"model": TEST_MODEL,
|
||||
"localip": TEST_HOST,
|
||||
"mac": TEST_MAC_DEVICE,
|
||||
"token": TEST_TOKEN,
|
||||
},
|
||||
{
|
||||
"parent_id": None,
|
||||
"name": TEST_NAME2,
|
||||
"model": TEST_MODEL,
|
||||
"localip": TEST_HOST2,
|
||||
"mac": TEST_MAC_DEVICE2,
|
||||
"token": TEST_TOKEN,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(name="xiaomi_miio_connect", autouse=True)
|
||||
def xiaomi_miio_connect_fixture():
|
||||
"""Mock denonavr connection and entry setup."""
|
||||
mock_info = get_mock_info()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.device.Device.info",
|
||||
return_value=mock_info,
|
||||
), patch(
|
||||
"homeassistant.components.xiaomi_miio.config_flow.MiCloud.login",
|
||||
return_value=True,
|
||||
), patch(
|
||||
"homeassistant.components.xiaomi_miio.config_flow.MiCloud.get_devices",
|
||||
return_value=TEST_CLOUD_DEVICES_1,
|
||||
), patch(
|
||||
"homeassistant.components.xiaomi_miio.async_setup_entry", return_value=True
|
||||
), patch(
|
||||
"homeassistant.components.xiaomi_miio.async_unload_entry", return_value=True
|
||||
):
|
||||
yield
|
||||
|
||||
|
||||
def get_mock_info(
|
||||
|
@ -48,7 +107,16 @@ async def test_config_flow_step_gateway_connect_error(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{const.CONF_MANUAL: True},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "manual"
|
||||
assert result["errors"] == {}
|
||||
|
||||
with patch(
|
||||
|
@ -61,7 +129,7 @@ async def test_config_flow_step_gateway_connect_error(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "connect"
|
||||
assert result["errors"] == {"base": "cannot_connect"}
|
||||
|
||||
|
||||
|
@ -72,26 +140,30 @@ async def test_config_flow_gateway_success(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
mock_info = get_mock_info()
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{const.CONF_MANUAL: True},
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.device.Device.info",
|
||||
return_value=mock_info,
|
||||
), patch(
|
||||
"homeassistant.components.xiaomi_miio.async_setup_entry", return_value=True
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN},
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "manual"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN},
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == DEFAULT_GATEWAY_NAME
|
||||
assert result["title"] == TEST_MODEL
|
||||
assert result["data"] == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_GATEWAY,
|
||||
const.CONF_CLOUD_USERNAME: None,
|
||||
const.CONF_CLOUD_PASSWORD: None,
|
||||
const.CONF_CLOUD_COUNTRY: None,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: TEST_MODEL,
|
||||
|
@ -99,6 +171,202 @@ async def test_config_flow_gateway_success(hass):
|
|||
}
|
||||
|
||||
|
||||
async def test_config_flow_gateway_cloud_success(hass):
|
||||
"""Test a successful config flow using cloud."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
const.DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == TEST_NAME
|
||||
assert result["data"] == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_GATEWAY,
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: TEST_MODEL,
|
||||
const.CONF_MAC: TEST_MAC,
|
||||
}
|
||||
|
||||
|
||||
async def test_config_flow_gateway_cloud_multiple_success(hass):
|
||||
"""Test a successful config flow using cloud with multiple devices."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
const.DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.config_flow.MiCloud.get_devices",
|
||||
return_value=TEST_CLOUD_DEVICES_2,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "select"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"select_device": f"{TEST_NAME2} - {TEST_MODEL}"},
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == TEST_NAME2
|
||||
assert result["data"] == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_GATEWAY,
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
CONF_HOST: TEST_HOST2,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: TEST_MODEL,
|
||||
const.CONF_MAC: TEST_MAC2,
|
||||
}
|
||||
|
||||
|
||||
async def test_config_flow_gateway_cloud_incomplete(hass):
|
||||
"""Test a failed config flow using incomplete cloud credentials."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
const.DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {"base": "cloud_credentials_incomplete"}
|
||||
|
||||
|
||||
async def test_config_flow_gateway_cloud_login_error(hass):
|
||||
"""Test a failed config flow using cloud login error."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
const.DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.config_flow.MiCloud.login",
|
||||
return_value=False,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {"base": "cloud_login_error"}
|
||||
|
||||
|
||||
async def test_config_flow_gateway_cloud_no_devices(hass):
|
||||
"""Test a failed config flow using cloud with no devices."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
const.DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.config_flow.MiCloud.get_devices",
|
||||
return_value=[],
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {"base": "cloud_no_devices"}
|
||||
|
||||
|
||||
async def test_config_flow_gateway_cloud_missing_token(hass):
|
||||
"""Test a failed config flow using cloud with a missing token."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
const.DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
cloud_device = [
|
||||
{
|
||||
"parent_id": None,
|
||||
"name": TEST_NAME,
|
||||
"model": TEST_MODEL,
|
||||
"localip": TEST_HOST,
|
||||
"mac": TEST_MAC_DEVICE,
|
||||
"token": None,
|
||||
}
|
||||
]
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.config_flow.MiCloud.get_devices",
|
||||
return_value=cloud_device,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "incomplete_info"
|
||||
|
||||
|
||||
async def test_zeroconf_gateway_success(hass):
|
||||
"""Test a successful zeroconf discovery of a gateway."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -112,26 +380,25 @@ async def test_zeroconf_gateway_success(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
mock_info = get_mock_info()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.device.Device.info",
|
||||
return_value=mock_info,
|
||||
), patch(
|
||||
"homeassistant.components.xiaomi_miio.async_setup_entry", return_value=True
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{CONF_TOKEN: TEST_TOKEN},
|
||||
)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == DEFAULT_GATEWAY_NAME
|
||||
assert result["title"] == TEST_NAME
|
||||
assert result["data"] == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_GATEWAY,
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: TEST_MODEL,
|
||||
|
@ -184,7 +451,16 @@ async def test_config_flow_step_device_connect_error(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{const.CONF_MANUAL: True},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "manual"
|
||||
assert result["errors"] == {}
|
||||
|
||||
with patch(
|
||||
|
@ -197,7 +473,7 @@ async def test_config_flow_step_device_connect_error(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "connect"
|
||||
assert result["errors"] == {"base": "cannot_connect"}
|
||||
|
||||
|
||||
|
@ -208,7 +484,16 @@ async def test_config_flow_step_unknown_device(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{const.CONF_MANUAL: True},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "manual"
|
||||
assert result["errors"] == {}
|
||||
|
||||
mock_info = get_mock_info(model="UNKNOWN")
|
||||
|
@ -223,7 +508,7 @@ async def test_config_flow_step_unknown_device(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "connect"
|
||||
assert result["errors"] == {"base": "unknown_device"}
|
||||
|
||||
|
||||
|
@ -234,8 +519,6 @@ async def test_import_flow_success(hass):
|
|||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.device.Device.info",
|
||||
return_value=mock_info,
|
||||
), patch(
|
||||
"homeassistant.components.xiaomi_miio.async_setup_entry", return_value=True
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
const.DOMAIN,
|
||||
|
@ -247,6 +530,9 @@ async def test_import_flow_success(hass):
|
|||
assert result["title"] == TEST_NAME
|
||||
assert result["data"] == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_DEVICE,
|
||||
const.CONF_CLOUD_USERNAME: None,
|
||||
const.CONF_CLOUD_PASSWORD: None,
|
||||
const.CONF_CLOUD_COUNTRY: None,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: const.MODELS_SWITCH[0],
|
||||
|
@ -261,7 +547,16 @@ async def test_config_flow_step_device_manual_model_succes(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{const.CONF_MANUAL: True},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "manual"
|
||||
assert result["errors"] == {}
|
||||
|
||||
with patch(
|
||||
|
@ -274,7 +569,7 @@ async def test_config_flow_step_device_manual_model_succes(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "connect"
|
||||
assert result["errors"] == {"base": "cannot_connect"}
|
||||
|
||||
overwrite_model = const.MODELS_VACUUM[0]
|
||||
|
@ -282,18 +577,19 @@ async def test_config_flow_step_device_manual_model_succes(hass):
|
|||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.device.Device.info",
|
||||
side_effect=DeviceException({}),
|
||||
), patch(
|
||||
"homeassistant.components.xiaomi_miio.async_setup_entry", return_value=True
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{CONF_TOKEN: TEST_TOKEN, const.CONF_MODEL: overwrite_model},
|
||||
{const.CONF_MODEL: overwrite_model},
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == overwrite_model
|
||||
assert result["data"] == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_DEVICE,
|
||||
const.CONF_CLOUD_USERNAME: None,
|
||||
const.CONF_CLOUD_PASSWORD: None,
|
||||
const.CONF_CLOUD_COUNTRY: None,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: overwrite_model,
|
||||
|
@ -308,7 +604,16 @@ async def config_flow_device_success(hass, model_to_test):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{const.CONF_MANUAL: True},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "manual"
|
||||
assert result["errors"] == {}
|
||||
|
||||
mock_info = get_mock_info(model=model_to_test)
|
||||
|
@ -316,8 +621,6 @@ async def config_flow_device_success(hass, model_to_test):
|
|||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.device.Device.info",
|
||||
return_value=mock_info,
|
||||
), patch(
|
||||
"homeassistant.components.xiaomi_miio.async_setup_entry", return_value=True
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
|
@ -328,6 +631,9 @@ async def config_flow_device_success(hass, model_to_test):
|
|||
assert result["title"] == model_to_test
|
||||
assert result["data"] == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_DEVICE,
|
||||
const.CONF_CLOUD_USERNAME: None,
|
||||
const.CONF_CLOUD_PASSWORD: None,
|
||||
const.CONF_CLOUD_COUNTRY: None,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: model_to_test,
|
||||
|
@ -348,7 +654,16 @@ async def zeroconf_device_success(hass, zeroconf_name_to_test, model_to_test):
|
|||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "device"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{const.CONF_MANUAL: True},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "manual"
|
||||
assert result["errors"] == {}
|
||||
|
||||
mock_info = get_mock_info(model=model_to_test)
|
||||
|
@ -356,8 +671,6 @@ async def zeroconf_device_success(hass, zeroconf_name_to_test, model_to_test):
|
|||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.device.Device.info",
|
||||
return_value=mock_info,
|
||||
), patch(
|
||||
"homeassistant.components.xiaomi_miio.async_setup_entry", return_value=True
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
|
@ -368,6 +681,9 @@ async def zeroconf_device_success(hass, zeroconf_name_to_test, model_to_test):
|
|||
assert result["title"] == model_to_test
|
||||
assert result["data"] == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_DEVICE,
|
||||
const.CONF_CLOUD_USERNAME: None,
|
||||
const.CONF_CLOUD_PASSWORD: None,
|
||||
const.CONF_CLOUD_COUNTRY: None,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: model_to_test,
|
||||
|
@ -399,3 +715,147 @@ async def test_zeroconf_vacuum_success(hass):
|
|||
test_vacuum_model = const.MODELS_VACUUM[0]
|
||||
test_zeroconf_name = const.MODELS_VACUUM[0].replace(".", "-")
|
||||
await zeroconf_device_success(hass, test_zeroconf_name, test_vacuum_model)
|
||||
|
||||
|
||||
async def test_options_flow(hass):
|
||||
"""Test specifying non default settings using options flow."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=const.DOMAIN,
|
||||
unique_id=TEST_GATEWAY_ID,
|
||||
data={
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
const.CONF_FLOW_TYPE: const.CONF_GATEWAY,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: TEST_MODEL,
|
||||
const.CONF_MAC: TEST_MAC,
|
||||
},
|
||||
title=TEST_NAME,
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
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"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
const.CONF_CLOUD_SUBDEVICES: True,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert config_entry.options == {
|
||||
const.CONF_CLOUD_SUBDEVICES: True,
|
||||
}
|
||||
|
||||
|
||||
async def test_options_flow_incomplete(hass):
|
||||
"""Test specifying incomplete settings using options flow."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=const.DOMAIN,
|
||||
unique_id=TEST_GATEWAY_ID,
|
||||
data={
|
||||
const.CONF_CLOUD_USERNAME: None,
|
||||
const.CONF_CLOUD_PASSWORD: None,
|
||||
const.CONF_CLOUD_COUNTRY: None,
|
||||
const.CONF_FLOW_TYPE: const.CONF_GATEWAY,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: TEST_MODEL,
|
||||
const.CONF_MAC: TEST_MAC,
|
||||
},
|
||||
title=TEST_NAME,
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
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"
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
const.CONF_CLOUD_SUBDEVICES: True,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "init"
|
||||
assert result["errors"] == {"base": "cloud_credentials_incomplete"}
|
||||
|
||||
|
||||
async def test_reauth(hass):
|
||||
"""Test a reauth flow."""
|
||||
# await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
config_entry = MockConfigEntry(
|
||||
domain=const.DOMAIN,
|
||||
unique_id=TEST_GATEWAY_ID,
|
||||
data={
|
||||
const.CONF_CLOUD_USERNAME: None,
|
||||
const.CONF_CLOUD_PASSWORD: None,
|
||||
const.CONF_CLOUD_COUNTRY: None,
|
||||
const.CONF_FLOW_TYPE: const.CONF_GATEWAY,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: TEST_MODEL,
|
||||
const.CONF_MAC: TEST_MAC,
|
||||
},
|
||||
title=TEST_NAME,
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
const.DOMAIN,
|
||||
context={"source": config_entries.SOURCE_REAUTH},
|
||||
data=config_entry.data,
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{},
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {}
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "reauth_successful"
|
||||
|
||||
config_data = config_entry.data.copy()
|
||||
assert config_data == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_GATEWAY,
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
const.CONF_MODEL: TEST_MODEL,
|
||||
const.CONF_MAC: TEST_MAC,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue