Skip to content

Commit

Permalink
WIP : Add link step to config flow
Browse files Browse the repository at this point in the history
  • Loading branch information
Quentame committed Jan 10, 2020
1 parent 9459053 commit 737e13d
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 14 deletions.
9 changes: 8 additions & 1 deletion homeassistant/components/freebox/.translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@
"already_configured": "Host already configured"
},
"error": {
"already_configured": "Host already configured"
"already_configured": "Host already configured",
"connection_failed": "Failed to connect, please try again",
"register_failed": "Failed to register, please try again",
"unknown": "Unknown error: please retry later"
},
"step": {
"link": {
"description": "Press the right arrow on the router to register Freebox with Home Assistant.\n\n![Location of button on the router](/static/images/config_freebox.png)",
"title": "Link Freebox router"
},
"user": {
"data": {
"host": "Host",
Expand Down
44 changes: 37 additions & 7 deletions homeassistant/components/freebox/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging

from aiofreepybox import Freepybox
from aiofreepybox.exceptions import HttpRequestError
from aiofreepybox.exceptions import AuthorizationError, HttpRequestError
import voluptuous as vol

from homeassistant import config_entries
Expand Down Expand Up @@ -51,26 +51,56 @@ async def async_step_user(self, user_input=None):
errors = {}

if user_input is None:
return self._show_setup_form(user_input, None)

host = user_input[CONF_HOST]
port = user_input[CONF_PORT]
return self._show_setup_form(user_input, errors)

if self._configuration_exists(host):
if self._configuration_exists(user_input[CONF_HOST]):
errors["base"] = "already_configured"
return self._show_setup_form(user_input, errors)

return await self.async_step_link(user_input)

async def async_step_link(self, user_input=None):
"""Attempt to link with the Freebox router.
Given a configured host, will ask the user to press the button
to connect to the router.
"""
errors = {}
if user_input is None:
return self.async_show_form(step_id="link", errors=errors)

host = user_input[CONF_HOST]
port = user_input[CONF_PORT]

token_file = self.hass.config.path(CONFIG_FILE)

fbx = Freepybox(APP_DESC, token_file, API_VERSION)

try:
# Check connection and authentification
await fbx.open(host, port)

# Check permissions
await fbx.system.get_config()
await fbx.lan.get_hosts_list()

except AuthorizationError as error:
_LOGGER.error(error)
errors["base"] = "register_failed"
return self._show_setup_form(user_input, errors)

except HttpRequestError:
_LOGGER.exception("Failed to connect to Freebox")
_LOGGER.error("Error connecting to the Freebox router at %s", host)
errors["base"] = "connection_failed"
return self._show_setup_form(user_input, errors)

except Exception: # pylint: disable=broad-except
_LOGGER.exception(
"Unknown error connecting with Freebox router at %s", host
)
errors["base"] = "unknown"
return self._show_setup_form(user_input, errors)

return self.async_create_entry(
title=host, data={CONF_HOST: host, CONF_PORT: port},
)
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/freebox/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
APP_DESC = {
"app_id": "hass",
"app_name": "Home Assistant",
"app_version": "0.104",
"app_version": "0.105",
"device_name": socket.gethostname(),
}
API_VERSION = "v6"
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/freebox/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ async def reboot(self) -> None:

async def close(self) -> None:
"""Close the connection."""
await self._api.close()
if self._api is not None:
await self._api.close()
self._api = None

@property
Expand Down
9 changes: 8 additions & 1 deletion homeassistant/components/freebox/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@
"host": "Host",
"port": "Port"
}
},
"link": {
"title": "Link Freebox router",
"description": "Press the right arrow on the router to register Freebox with Home Assistant.\n\n![Location of button on the router](/static/images/config_freebox.png)"
}
},
"error":{
"already_configured": "Host already configured"
"already_configured": "Host already configured",
"register_failed": "Failed to register, please try again",
"connection_failed": "Failed to connect, please try again",
"unknown": "Unknown error: please retry later"
},
"abort":{
"already_configured": "Host already configured"
Expand Down
36 changes: 33 additions & 3 deletions tests/components/freebox/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
import asyncio
from unittest.mock import MagicMock, patch

from aiofreepybox.exceptions import HttpRequestError
from aiofreepybox.exceptions import (
AuthorizationError,
HttpRequestError,
InvalidTokenError,
)
import pytest

from homeassistant import data_entry_flow
Expand All @@ -24,6 +28,16 @@ def mock_controller_connect():
) as service_mock:
service_mock.return_value.open = MagicMock(return_value=asyncio.Future())
service_mock.return_value.open.return_value.set_result(None)

service_mock.return_value.system.get_config = MagicMock(
return_value=asyncio.Future()
)
service_mock.return_value.system.get_config.return_value.set_result(None)

service_mock.return_value.lan.get_hosts_list = MagicMock(
return_value=asyncio.Future()
)
service_mock.return_value.lan.get_hosts_list.return_value.set_result(None)
yield service_mock


Expand Down Expand Up @@ -79,14 +93,30 @@ async def test_abort_if_already_setup(hass):
assert result["errors"] == {"base": "already_configured"}


async def test_abort_on_connection_failed(hass):
"""Test when we have errors during connection."""
async def test_abort_on_link_failed(hass):
"""Test when we have errors during linking the router."""
flow = init_config_flow(hass)

with patch(
"homeassistant.components.freebox.config_flow.Freepybox.open",
side_effect=AuthorizationError(),
):
result = await flow.async_step_user({CONF_HOST: HOST, CONF_PORT: PORT})
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "register_failed"}

with patch(
"homeassistant.components.freebox.config_flow.Freepybox.open",
side_effect=HttpRequestError(),
):
result = await flow.async_step_user({CONF_HOST: HOST, CONF_PORT: PORT})
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "connection_failed"}

with patch(
"homeassistant.components.freebox.config_flow.Freepybox.open",
side_effect=InvalidTokenError(),
):
result = await flow.async_step_user({CONF_HOST: HOST, CONF_PORT: PORT})
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "unknown"}

0 comments on commit 737e13d

Please sign in to comment.