Handle more fritzbox edge cases (#34802)
parent
f47055a1b0
commit
996af94bb8
|
@ -2,6 +2,7 @@
|
|||
from urllib.parse import urlparse
|
||||
|
||||
from pyfritzhome import Fritzhome, LoginError
|
||||
from requests.exceptions import HTTPError
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
|
@ -32,6 +33,7 @@ DATA_SCHEMA_CONFIRM = vol.Schema(
|
|||
|
||||
RESULT_AUTH_FAILED = "auth_failed"
|
||||
RESULT_NOT_FOUND = "not_found"
|
||||
RESULT_NOT_SUPPORTED = "not_supported"
|
||||
RESULT_SUCCESS = "success"
|
||||
|
||||
|
||||
|
@ -67,12 +69,15 @@ class FritzboxConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
)
|
||||
try:
|
||||
fritzbox.login()
|
||||
fritzbox.get_device_elements()
|
||||
fritzbox.logout()
|
||||
return RESULT_SUCCESS
|
||||
except OSError:
|
||||
return RESULT_NOT_FOUND
|
||||
except LoginError:
|
||||
return RESULT_AUTH_FAILED
|
||||
except HTTPError:
|
||||
return RESULT_NOT_SUPPORTED
|
||||
except OSError:
|
||||
return RESULT_NOT_FOUND
|
||||
|
||||
async def async_step_import(self, user_input=None):
|
||||
"""Handle configuration by yaml file."""
|
||||
|
@ -129,7 +134,7 @@ class FritzboxConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
return self.async_abort(reason="already_configured")
|
||||
|
||||
self._host = host
|
||||
self._name = user_input[ATTR_UPNP_FRIENDLY_NAME]
|
||||
self._name = user_input.get(ATTR_UPNP_FRIENDLY_NAME) or host
|
||||
|
||||
self.context["title_placeholders"] = {"name": self._name}
|
||||
return await self.async_step_confirm()
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
"abort": {
|
||||
"already_in_progress": "AVM FRITZ!Box configuration is already in progress.",
|
||||
"already_configured": "This AVM FRITZ!Box is already configured.",
|
||||
"not_found": "No supported AVM FRITZ!Box found on the network."
|
||||
"not_found": "No supported AVM FRITZ!Box found on the network.",
|
||||
"not_supported": "Connected to AVM FRITZ!Box but it's unable to control Smart Home devices."
|
||||
},
|
||||
"error": {
|
||||
"auth_failed": "Username and/or password are incorrect."
|
||||
|
|
|
@ -4,6 +4,7 @@ from unittest.mock import Mock, patch
|
|||
|
||||
from pyfritzhome import LoginError
|
||||
import pytest
|
||||
from requests.exceptions import HTTPError
|
||||
|
||||
from homeassistant.components.fritzbox.const import DOMAIN
|
||||
from homeassistant.components.ssdp import (
|
||||
|
@ -121,6 +122,28 @@ async def test_ssdp(hass: HomeAssistantType, fritz: Mock):
|
|||
assert result["result"].unique_id == "only-a-test"
|
||||
|
||||
|
||||
async def test_ssdp_no_friendly_name(hass: HomeAssistantType, fritz: Mock):
|
||||
"""Test starting a flow from discovery without friendly name."""
|
||||
MOCK_NO_NAME = MOCK_SSDP_DATA.copy()
|
||||
del MOCK_NO_NAME[ATTR_UPNP_FRIENDLY_NAME]
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "ssdp"}, data=MOCK_NO_NAME
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "confirm"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={CONF_PASSWORD: "fake_pass", CONF_USERNAME: "fake_user"},
|
||||
)
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == "fake_host"
|
||||
assert result["data"][CONF_HOST] == "fake_host"
|
||||
assert result["data"][CONF_PASSWORD] == "fake_pass"
|
||||
assert result["data"][CONF_USERNAME] == "fake_user"
|
||||
assert result["result"].unique_id == "only-a-test"
|
||||
|
||||
|
||||
async def test_ssdp_auth_failed(hass: HomeAssistantType, fritz: Mock):
|
||||
"""Test starting a flow from discovery with authentication failure."""
|
||||
fritz().login.side_effect = LoginError("Boom")
|
||||
|
@ -159,6 +182,24 @@ async def test_ssdp_not_successful(hass: HomeAssistantType, fritz: Mock):
|
|||
assert result["reason"] == "not_found"
|
||||
|
||||
|
||||
async def test_ssdp_not_supported(hass: HomeAssistantType, fritz: Mock):
|
||||
"""Test starting a flow from discovery with unsupported device."""
|
||||
fritz().get_device_elements.side_effect = HTTPError("Boom")
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "confirm"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={CONF_PASSWORD: "whatever", CONF_USERNAME: "whatever"},
|
||||
)
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "not_supported"
|
||||
|
||||
|
||||
async def test_ssdp_already_in_progress_unique_id(hass: HomeAssistantType, fritz: Mock):
|
||||
"""Test starting a flow from discovery twice."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
|
Loading…
Reference in New Issue