hass-core/tests/components/roku/test_config_flow.py
Chris Talkington cf8dfdae47
Add config flow to roku (#31988)
* create a dedicated const.py

* add DEFAULT_PORT to const.py

* work on config flow conversion.

* remove discovery.

* work on config flow and add tests. other cleanup.

* work on config flow and add tests. other cleanup.

* add quality scale to manifest.

* work on config flow and add tests. other cleanup.

* review tweaks.

* Update manifest.json

* catch more specific errors

* catch more errors.

* impprt specific exceptions

* import specific exceptions

* Update __init__.py

* Update config_flow.py

* Update media_player.py

* Update remote.py

* Update media_player.py

* Update remote.py

* Update media_player.py

* Update remote.py

* Update config_flow.py

* Update config_flow.py

* Update media_player.py

* Update __init__.py

* Update __init__.py

* Update config_flow.py

* Update test_config_flow.py

* Update config_flow.py

* Update __init__.py

* Update test_config_flow.py

* Update remote.py

* Update test_init.py

* Update test_init.py

* Update media_player.py

* Update media_player.py

* Update media_player.py
2020-03-15 21:13:04 -07:00

247 lines
8.1 KiB
Python

"""Test the Roku config flow."""
from socket import gaierror as SocketGIAError
from typing import Any, Dict, Optional
from asynctest import patch
from requests.exceptions import RequestException
from roku import RokuException
from homeassistant.components.roku.const import DOMAIN
from homeassistant.components.ssdp import (
ATTR_SSDP_LOCATION,
ATTR_UPNP_FRIENDLY_NAME,
ATTR_UPNP_SERIAL,
)
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_SSDP, SOURCE_USER
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_SOURCE
from homeassistant.data_entry_flow import (
RESULT_TYPE_ABORT,
RESULT_TYPE_CREATE_ENTRY,
RESULT_TYPE_FORM,
)
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.setup import async_setup_component
from tests.components.roku import (
HOST,
SSDP_LOCATION,
UPNP_FRIENDLY_NAME,
UPNP_SERIAL,
MockDeviceInfo,
setup_integration,
)
async def async_configure_flow(
hass: HomeAssistantType, flow_id: str, user_input: Optional[Dict] = None
) -> Any:
"""Set up mock Roku integration flow."""
with patch(
"homeassistant.components.roku.config_flow.Roku.device_info",
new=MockDeviceInfo,
):
return await hass.config_entries.flow.async_configure(
flow_id=flow_id, user_input=user_input
)
async def async_init_flow(
hass: HomeAssistantType,
handler: str = DOMAIN,
context: Optional[Dict] = None,
data: Any = None,
) -> Any:
"""Set up mock Roku integration flow."""
with patch(
"homeassistant.components.roku.config_flow.Roku.device_info",
new=MockDeviceInfo,
):
return await hass.config_entries.flow.async_init(
handler=handler, context=context, data=data
)
async def test_duplicate_error(hass: HomeAssistantType) -> None:
"""Test that errors are shown when duplicates are added."""
await setup_integration(hass, skip_entry_setup=True)
result = await async_init_flow(
hass, context={CONF_SOURCE: SOURCE_IMPORT}, data={CONF_HOST: HOST}
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
result = await async_init_flow(
hass, context={CONF_SOURCE: SOURCE_USER}, data={CONF_HOST: HOST}
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
result = await async_init_flow(
hass,
context={CONF_SOURCE: SOURCE_SSDP},
data={
ATTR_UPNP_FRIENDLY_NAME: UPNP_FRIENDLY_NAME,
ATTR_SSDP_LOCATION: SSDP_LOCATION,
ATTR_UPNP_SERIAL: UPNP_SERIAL,
},
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
async def test_form(hass: HomeAssistantType) -> None:
"""Test the user step."""
await async_setup_component(hass, "persistent_notification", {})
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
)
assert result["type"] == RESULT_TYPE_FORM
assert result["errors"] == {}
with patch(
"homeassistant.components.roku.async_setup", return_value=True
) as mock_setup, patch(
"homeassistant.components.roku.async_setup_entry", return_value=True,
) as mock_setup_entry:
result = await async_configure_flow(hass, result["flow_id"], {CONF_HOST: HOST})
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["title"] == HOST
assert result["data"] == {CONF_HOST: HOST}
await hass.async_block_till_done()
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
async def test_form_cannot_connect(hass: HomeAssistantType) -> None:
"""Test we handle cannot connect roku error."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
)
with patch(
"homeassistant.components.roku.config_flow.validate_input",
side_effect=RokuException,
) as mock_validate_input:
result = await async_configure_flow(hass, result["flow_id"], {CONF_HOST: HOST},)
assert result["type"] == RESULT_TYPE_FORM
assert result["errors"] == {"base": "cannot_connect"}
await hass.async_block_till_done()
assert len(mock_validate_input.mock_calls) == 1
async def test_form_cannot_connect_request(hass: HomeAssistantType) -> None:
"""Test we handle cannot connect request error."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
)
with patch(
"homeassistant.components.roku.config_flow.validate_input",
side_effect=RequestException,
) as mock_validate_input:
result = await async_configure_flow(hass, result["flow_id"], {CONF_HOST: HOST},)
assert result["type"] == RESULT_TYPE_FORM
assert result["errors"] == {"base": "cannot_connect"}
await hass.async_block_till_done()
assert len(mock_validate_input.mock_calls) == 1
async def test_form_cannot_connect_socket(hass: HomeAssistantType) -> None:
"""Test we handle cannot connect socket error."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
)
with patch(
"homeassistant.components.roku.config_flow.validate_input",
side_effect=SocketGIAError,
) as mock_validate_input:
result = await async_configure_flow(hass, result["flow_id"], {CONF_HOST: HOST},)
assert result["type"] == RESULT_TYPE_FORM
assert result["errors"] == {"base": "cannot_connect"}
await hass.async_block_till_done()
assert len(mock_validate_input.mock_calls) == 1
async def test_form_unknown_error(hass: HomeAssistantType) -> None:
"""Test we handle unknown error."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
)
with patch(
"homeassistant.components.roku.config_flow.validate_input",
side_effect=Exception,
) as mock_validate_input:
result = await async_configure_flow(hass, result["flow_id"], {CONF_HOST: HOST},)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "unknown"
await hass.async_block_till_done()
assert len(mock_validate_input.mock_calls) == 1
async def test_import(hass: HomeAssistantType) -> None:
"""Test the import step."""
with patch(
"homeassistant.components.roku.async_setup", return_value=True
) as mock_setup, patch(
"homeassistant.components.roku.async_setup_entry", return_value=True,
) as mock_setup_entry:
result = await async_init_flow(
hass, context={CONF_SOURCE: SOURCE_IMPORT}, data={CONF_HOST: HOST}
)
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["title"] == HOST
assert result["data"] == {CONF_HOST: HOST}
await hass.async_block_till_done()
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
async def test_ssdp_discovery(hass: HomeAssistantType) -> None:
"""Test the ssdp discovery step."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={CONF_SOURCE: SOURCE_SSDP},
data={
ATTR_SSDP_LOCATION: SSDP_LOCATION,
ATTR_UPNP_FRIENDLY_NAME: UPNP_FRIENDLY_NAME,
ATTR_UPNP_SERIAL: UPNP_SERIAL,
},
)
assert result["type"] == RESULT_TYPE_FORM
assert result["step_id"] == "ssdp_confirm"
assert result["description_placeholders"] == {CONF_NAME: UPNP_FRIENDLY_NAME}
with patch(
"homeassistant.components.roku.async_setup", return_value=True
) as mock_setup, patch(
"homeassistant.components.roku.async_setup_entry", return_value=True,
) as mock_setup_entry:
result = await async_configure_flow(hass, result["flow_id"], {})
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["title"] == UPNP_FRIENDLY_NAME
assert result["data"] == {
CONF_HOST: HOST,
CONF_NAME: UPNP_FRIENDLY_NAME,
}
await hass.async_block_till_done()
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1