core/tests/components/melcloud/test_config_flow.py

178 lines
5.7 KiB
Python
Raw Normal View History

Add MELCloud integration (#30712) * Add MELCloud integration * Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. * Run isort * Fix pylint errors * Run black * Increase coverage * Update pymelcloud dependency * Add HVAC_MODE_OFF emulation * Remove print * Update pymelcloud to enable device type filtering * Collapse except blocks and chain ClientNotReadys * Add preliminary documentation URL * Use list comp for creating model info Filters out empty model names form units. * f-string galore Dropped 'HVAC' from AtaDevice name template. * Delegate fan mode mapping to pymelcloud * Fix type annotation * Access AtaDevice through self._device * Prefer list comprehension * Update pymelcloud to leverage device type grouping The updated backend lib returns devices in a dict grouped by the device type. The devices do not necessarily need to be in a single list and this way isinstance is not required to extract devices by type. * Remove DOMAIN presence check This does not seem to make much sense after all. * Fix async_setup_entry Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib. * Simplify empty model name check * Improve config validation * Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow. * Remove unused manifest properties * Remove redundant ClimateDevice property override * Add __init__.py to coverage exclusion * Use CONF_USERNAME instead of CONF_EMAIL * Use asyncio.gather instead of asyncio.wait * Misc fixes * any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list * Use _abort_if_unique_id_configured to update token * Fix them tests * Remove current state guards * Fix that gather call * Implement sensor definitions without str manipulation * Use relative intra-package imports * Update homeassistant/components/melcloud/config_flow.py Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 21:09:12 +00:00
"""Test the MELCloud config flow."""
import asyncio
from aiohttp import ClientError, ClientResponseError
import pymelcloud
import pytest
from homeassistant import config_entries
from homeassistant.components.melcloud.const import DOMAIN
from homeassistant.const import HTTP_FORBIDDEN, HTTP_INTERNAL_SERVER_ERROR
Add MELCloud integration (#30712) * Add MELCloud integration * Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. * Run isort * Fix pylint errors * Run black * Increase coverage * Update pymelcloud dependency * Add HVAC_MODE_OFF emulation * Remove print * Update pymelcloud to enable device type filtering * Collapse except blocks and chain ClientNotReadys * Add preliminary documentation URL * Use list comp for creating model info Filters out empty model names form units. * f-string galore Dropped 'HVAC' from AtaDevice name template. * Delegate fan mode mapping to pymelcloud * Fix type annotation * Access AtaDevice through self._device * Prefer list comprehension * Update pymelcloud to leverage device type grouping The updated backend lib returns devices in a dict grouped by the device type. The devices do not necessarily need to be in a single list and this way isinstance is not required to extract devices by type. * Remove DOMAIN presence check This does not seem to make much sense after all. * Fix async_setup_entry Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib. * Simplify empty model name check * Improve config validation * Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow. * Remove unused manifest properties * Remove redundant ClimateDevice property override * Add __init__.py to coverage exclusion * Use CONF_USERNAME instead of CONF_EMAIL * Use asyncio.gather instead of asyncio.wait * Misc fixes * any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list * Use _abort_if_unique_id_configured to update token * Fix them tests * Remove current state guards * Fix that gather call * Implement sensor definitions without str manipulation * Use relative intra-package imports * Update homeassistant/components/melcloud/config_flow.py Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 21:09:12 +00:00
from tests.async_mock import patch
Add MELCloud integration (#30712) * Add MELCloud integration * Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. * Run isort * Fix pylint errors * Run black * Increase coverage * Update pymelcloud dependency * Add HVAC_MODE_OFF emulation * Remove print * Update pymelcloud to enable device type filtering * Collapse except blocks and chain ClientNotReadys * Add preliminary documentation URL * Use list comp for creating model info Filters out empty model names form units. * f-string galore Dropped 'HVAC' from AtaDevice name template. * Delegate fan mode mapping to pymelcloud * Fix type annotation * Access AtaDevice through self._device * Prefer list comprehension * Update pymelcloud to leverage device type grouping The updated backend lib returns devices in a dict grouped by the device type. The devices do not necessarily need to be in a single list and this way isinstance is not required to extract devices by type. * Remove DOMAIN presence check This does not seem to make much sense after all. * Fix async_setup_entry Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib. * Simplify empty model name check * Improve config validation * Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow. * Remove unused manifest properties * Remove redundant ClimateDevice property override * Add __init__.py to coverage exclusion * Use CONF_USERNAME instead of CONF_EMAIL * Use asyncio.gather instead of asyncio.wait * Misc fixes * any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list * Use _abort_if_unique_id_configured to update token * Fix them tests * Remove current state guards * Fix that gather call * Implement sensor definitions without str manipulation * Use relative intra-package imports * Update homeassistant/components/melcloud/config_flow.py Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 21:09:12 +00:00
from tests.common import MockConfigEntry
@pytest.fixture
def mock_login():
"""Mock pymelcloud login."""
with patch(
"homeassistant.components.melcloud.config_flow.pymelcloud.login"
) as mock:
Add MELCloud integration (#30712) * Add MELCloud integration * Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. * Run isort * Fix pylint errors * Run black * Increase coverage * Update pymelcloud dependency * Add HVAC_MODE_OFF emulation * Remove print * Update pymelcloud to enable device type filtering * Collapse except blocks and chain ClientNotReadys * Add preliminary documentation URL * Use list comp for creating model info Filters out empty model names form units. * f-string galore Dropped 'HVAC' from AtaDevice name template. * Delegate fan mode mapping to pymelcloud * Fix type annotation * Access AtaDevice through self._device * Prefer list comprehension * Update pymelcloud to leverage device type grouping The updated backend lib returns devices in a dict grouped by the device type. The devices do not necessarily need to be in a single list and this way isinstance is not required to extract devices by type. * Remove DOMAIN presence check This does not seem to make much sense after all. * Fix async_setup_entry Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib. * Simplify empty model name check * Improve config validation * Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow. * Remove unused manifest properties * Remove redundant ClimateDevice property override * Add __init__.py to coverage exclusion * Use CONF_USERNAME instead of CONF_EMAIL * Use asyncio.gather instead of asyncio.wait * Misc fixes * any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list * Use _abort_if_unique_id_configured to update token * Fix them tests * Remove current state guards * Fix that gather call * Implement sensor definitions without str manipulation * Use relative intra-package imports * Update homeassistant/components/melcloud/config_flow.py Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 21:09:12 +00:00
mock.return_value = "test-token"
yield mock
@pytest.fixture
def mock_get_devices():
"""Mock pymelcloud get_devices."""
with patch(
"homeassistant.components.melcloud.config_flow.pymelcloud.get_devices"
) as mock:
Add MELCloud integration (#30712) * Add MELCloud integration * Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. * Run isort * Fix pylint errors * Run black * Increase coverage * Update pymelcloud dependency * Add HVAC_MODE_OFF emulation * Remove print * Update pymelcloud to enable device type filtering * Collapse except blocks and chain ClientNotReadys * Add preliminary documentation URL * Use list comp for creating model info Filters out empty model names form units. * f-string galore Dropped 'HVAC' from AtaDevice name template. * Delegate fan mode mapping to pymelcloud * Fix type annotation * Access AtaDevice through self._device * Prefer list comprehension * Update pymelcloud to leverage device type grouping The updated backend lib returns devices in a dict grouped by the device type. The devices do not necessarily need to be in a single list and this way isinstance is not required to extract devices by type. * Remove DOMAIN presence check This does not seem to make much sense after all. * Fix async_setup_entry Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib. * Simplify empty model name check * Improve config validation * Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow. * Remove unused manifest properties * Remove redundant ClimateDevice property override * Add __init__.py to coverage exclusion * Use CONF_USERNAME instead of CONF_EMAIL * Use asyncio.gather instead of asyncio.wait * Misc fixes * any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list * Use _abort_if_unique_id_configured to update token * Fix them tests * Remove current state guards * Fix that gather call * Implement sensor definitions without str manipulation * Use relative intra-package imports * Update homeassistant/components/melcloud/config_flow.py Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 21:09:12 +00:00
mock.return_value = {
pymelcloud.DEVICE_TYPE_ATA: [],
pymelcloud.DEVICE_TYPE_ATW: [],
}
yield mock
@pytest.fixture
def mock_request_info():
"""Mock RequestInfo to create ClientResponseErrors."""
with patch("aiohttp.RequestInfo") as mock_ri:
mock_ri.return_value.real_url.return_value = ""
yield mock_ri
async def test_form(hass, mock_login, mock_get_devices):
"""Test we get the form."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == "form"
assert result["errors"] is None
with patch(
"homeassistant.components.melcloud.async_setup", return_value=True
) as mock_setup, patch(
"homeassistant.components.melcloud.async_setup_entry", return_value=True
Add MELCloud integration (#30712) * Add MELCloud integration * Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. * Run isort * Fix pylint errors * Run black * Increase coverage * Update pymelcloud dependency * Add HVAC_MODE_OFF emulation * Remove print * Update pymelcloud to enable device type filtering * Collapse except blocks and chain ClientNotReadys * Add preliminary documentation URL * Use list comp for creating model info Filters out empty model names form units. * f-string galore Dropped 'HVAC' from AtaDevice name template. * Delegate fan mode mapping to pymelcloud * Fix type annotation * Access AtaDevice through self._device * Prefer list comprehension * Update pymelcloud to leverage device type grouping The updated backend lib returns devices in a dict grouped by the device type. The devices do not necessarily need to be in a single list and this way isinstance is not required to extract devices by type. * Remove DOMAIN presence check This does not seem to make much sense after all. * Fix async_setup_entry Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib. * Simplify empty model name check * Improve config validation * Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow. * Remove unused manifest properties * Remove redundant ClimateDevice property override * Add __init__.py to coverage exclusion * Use CONF_USERNAME instead of CONF_EMAIL * Use asyncio.gather instead of asyncio.wait * Misc fixes * any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list * Use _abort_if_unique_id_configured to update token * Fix them tests * Remove current state guards * Fix that gather call * Implement sensor definitions without str manipulation * Use relative intra-package imports * Update homeassistant/components/melcloud/config_flow.py Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 21:09:12 +00:00
) as mock_setup_entry:
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"username": "test-email@test-domain.com", "password": "test-password"},
)
assert result2["type"] == "create_entry"
assert result2["title"] == "test-email@test-domain.com"
assert result2["data"] == {
"username": "test-email@test-domain.com",
"token": "test-token",
}
await hass.async_block_till_done()
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
@pytest.mark.parametrize(
"error,reason",
[(ClientError(), "cannot_connect"), (asyncio.TimeoutError(), "cannot_connect")],
)
async def test_form_errors(hass, mock_login, mock_get_devices, error, reason):
"""Test we handle cannot connect error."""
mock_login.side_effect = error
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
data={"username": "test-email@test-domain.com", "password": "test-password"},
)
assert len(mock_login.mock_calls) == 1
assert result["type"] == "abort"
assert result["reason"] == reason
@pytest.mark.parametrize(
"error,message",
[
(401, "invalid_auth"),
(HTTP_FORBIDDEN, "invalid_auth"),
(HTTP_INTERNAL_SERVER_ERROR, "cannot_connect"),
],
Add MELCloud integration (#30712) * Add MELCloud integration * Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. * Run isort * Fix pylint errors * Run black * Increase coverage * Update pymelcloud dependency * Add HVAC_MODE_OFF emulation * Remove print * Update pymelcloud to enable device type filtering * Collapse except blocks and chain ClientNotReadys * Add preliminary documentation URL * Use list comp for creating model info Filters out empty model names form units. * f-string galore Dropped 'HVAC' from AtaDevice name template. * Delegate fan mode mapping to pymelcloud * Fix type annotation * Access AtaDevice through self._device * Prefer list comprehension * Update pymelcloud to leverage device type grouping The updated backend lib returns devices in a dict grouped by the device type. The devices do not necessarily need to be in a single list and this way isinstance is not required to extract devices by type. * Remove DOMAIN presence check This does not seem to make much sense after all. * Fix async_setup_entry Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib. * Simplify empty model name check * Improve config validation * Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow. * Remove unused manifest properties * Remove redundant ClimateDevice property override * Add __init__.py to coverage exclusion * Use CONF_USERNAME instead of CONF_EMAIL * Use asyncio.gather instead of asyncio.wait * Misc fixes * any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list * Use _abort_if_unique_id_configured to update token * Fix them tests * Remove current state guards * Fix that gather call * Implement sensor definitions without str manipulation * Use relative intra-package imports * Update homeassistant/components/melcloud/config_flow.py Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 21:09:12 +00:00
)
async def test_form_response_errors(
hass, mock_login, mock_get_devices, mock_request_info, error, message
):
"""Test we handle response errors."""
mock_login.side_effect = ClientResponseError(mock_request_info(), (), status=error)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
data={"username": "test-email@test-domain.com", "password": "test-password"},
)
assert result["type"] == "abort"
assert result["reason"] == message
async def test_import_with_token(hass, mock_login, mock_get_devices):
"""Test successful import."""
with patch(
"homeassistant.components.melcloud.async_setup", return_value=True
) as mock_setup, patch(
"homeassistant.components.melcloud.async_setup_entry", return_value=True
Add MELCloud integration (#30712) * Add MELCloud integration * Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. * Run isort * Fix pylint errors * Run black * Increase coverage * Update pymelcloud dependency * Add HVAC_MODE_OFF emulation * Remove print * Update pymelcloud to enable device type filtering * Collapse except blocks and chain ClientNotReadys * Add preliminary documentation URL * Use list comp for creating model info Filters out empty model names form units. * f-string galore Dropped 'HVAC' from AtaDevice name template. * Delegate fan mode mapping to pymelcloud * Fix type annotation * Access AtaDevice through self._device * Prefer list comprehension * Update pymelcloud to leverage device type grouping The updated backend lib returns devices in a dict grouped by the device type. The devices do not necessarily need to be in a single list and this way isinstance is not required to extract devices by type. * Remove DOMAIN presence check This does not seem to make much sense after all. * Fix async_setup_entry Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib. * Simplify empty model name check * Improve config validation * Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow. * Remove unused manifest properties * Remove redundant ClimateDevice property override * Add __init__.py to coverage exclusion * Use CONF_USERNAME instead of CONF_EMAIL * Use asyncio.gather instead of asyncio.wait * Misc fixes * any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list * Use _abort_if_unique_id_configured to update token * Fix them tests * Remove current state guards * Fix that gather call * Implement sensor definitions without str manipulation * Use relative intra-package imports * Update homeassistant/components/melcloud/config_flow.py Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 21:09:12 +00:00
) as mock_setup_entry:
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={"username": "test-email@test-domain.com", "token": "test-token"},
)
assert result["type"] == "create_entry"
assert result["title"] == "test-email@test-domain.com"
assert result["data"] == {
"username": "test-email@test-domain.com",
"token": "test-token",
}
await hass.async_block_till_done()
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
async def test_token_refresh(hass, mock_login, mock_get_devices):
"""Re-configuration with existing username should refresh token."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
data={"username": "test-email@test-domain.com", "token": "test-original-token"},
Add MELCloud integration (#30712) * Add MELCloud integration * Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. * Run isort * Fix pylint errors * Run black * Increase coverage * Update pymelcloud dependency * Add HVAC_MODE_OFF emulation * Remove print * Update pymelcloud to enable device type filtering * Collapse except blocks and chain ClientNotReadys * Add preliminary documentation URL * Use list comp for creating model info Filters out empty model names form units. * f-string galore Dropped 'HVAC' from AtaDevice name template. * Delegate fan mode mapping to pymelcloud * Fix type annotation * Access AtaDevice through self._device * Prefer list comprehension * Update pymelcloud to leverage device type grouping The updated backend lib returns devices in a dict grouped by the device type. The devices do not necessarily need to be in a single list and this way isinstance is not required to extract devices by type. * Remove DOMAIN presence check This does not seem to make much sense after all. * Fix async_setup_entry Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib. * Simplify empty model name check * Improve config validation * Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow. * Remove unused manifest properties * Remove redundant ClimateDevice property override * Add __init__.py to coverage exclusion * Use CONF_USERNAME instead of CONF_EMAIL * Use asyncio.gather instead of asyncio.wait * Misc fixes * any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list * Use _abort_if_unique_id_configured to update token * Fix them tests * Remove current state guards * Fix that gather call * Implement sensor definitions without str manipulation * Use relative intra-package imports * Update homeassistant/components/melcloud/config_flow.py Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 21:09:12 +00:00
unique_id="test-email@test-domain.com",
)
mock_entry.add_to_hass(hass)
with patch(
"homeassistant.components.melcloud.async_setup", return_value=True
) as mock_setup, patch(
"homeassistant.components.melcloud.async_setup_entry", return_value=True
Add MELCloud integration (#30712) * Add MELCloud integration * Provides a climate and sensor platforms. Multiple platforms on one go is not the best option, but it does not make sense to remove them and commit them later either. * Email and access token are stored to the ConfigEntry. The token can be updated by adding the integration again with the same email address. The config flow is aborted and the update is performed on the background. * Run isort * Fix pylint errors * Run black * Increase coverage * Update pymelcloud dependency * Add HVAC_MODE_OFF emulation * Remove print * Update pymelcloud to enable device type filtering * Collapse except blocks and chain ClientNotReadys * Add preliminary documentation URL * Use list comp for creating model info Filters out empty model names form units. * f-string galore Dropped 'HVAC' from AtaDevice name template. * Delegate fan mode mapping to pymelcloud * Fix type annotation * Access AtaDevice through self._device * Prefer list comprehension * Update pymelcloud to leverage device type grouping The updated backend lib returns devices in a dict grouped by the device type. The devices do not necessarily need to be in a single list and this way isinstance is not required to extract devices by type. * Remove DOMAIN presence check This does not seem to make much sense after all. * Fix async_setup_entry Entry setup used half-baked naming from few experimentations back. The naming conventiens were unified to match the platforms. A redundant noneness check was also removed after evaluating the possible return values from the backend lib. * Simplify empty model name check * Improve config validation * Use config_validation strings. * Add CONF_EMAIL to config schema. The value is not strictly required when configuring through configuration.yaml, but having it there makes things more consistent. * Use dict[key] to access required properties. * Add DOMAIN in config check back to async_setup. This is required if an integration is configured throught config_flow. * Remove unused manifest properties * Remove redundant ClimateDevice property override * Add __init__.py to coverage exclusion * Use CONF_USERNAME instead of CONF_EMAIL * Use asyncio.gather instead of asyncio.wait * Misc fixes * any -> Any * Better names for dict iterations * Proper dict access with mandatory/known keys * Remove unused 'name' argument * Remove unnecessary platform info from unique_ids * Remove redundant methods from climate platform * Remove redundant default value from dict get * Update ConfigFlow sub-classing * Define sensors in a dict instead of a list * Use _abort_if_unique_id_configured to update token * Fix them tests * Remove current state guards * Fix that gather call * Implement sensor definitions without str manipulation * Use relative intra-package imports * Update homeassistant/components/melcloud/config_flow.py Co-Authored-By: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2020-02-10 21:09:12 +00:00
) as mock_setup_entry:
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
data={
"username": "test-email@test-domain.com",
"password": "test-password",
},
)
assert result["type"] == "abort"
assert result["reason"] == "already_configured"
await hass.async_block_till_done()
assert len(mock_setup.mock_calls) == 0
assert len(mock_setup_entry.mock_calls) == 0
entries = hass.config_entries.async_entries(DOMAIN)
assert len(entries) == 1
entry = entries[0]
assert entry.data["username"] == "test-email@test-domain.com"
assert entry.data["token"] == "test-token"