Skip to content

Commit 3206b81

Browse files
committed
Fix non reuse of the service name generated by the api on the addition of the integration && allow user to specify his custom name
1 parent 5706fb2 commit 3206b81

File tree

9 files changed

+97
-20
lines changed

9 files changed

+97
-20
lines changed

homeassistant/components/freebox/config_flow.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Config flow to configure the Freebox integration."""
22

33
import logging
4+
import socket
45
from typing import Any
56

67
from freebox_api.exceptions import AuthorizationError, HttpRequestError
@@ -10,7 +11,7 @@
1011
from homeassistant.const import CONF_HOST, CONF_PORT
1112
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
1213

13-
from .const import DOMAIN
14+
from .const import CONF_SERVICE_USER_NAME, DOMAIN
1415
from .router import get_api, get_hosts_list_if_supported
1516

1617
_LOGGER = logging.getLogger(__name__)
@@ -36,6 +37,10 @@ async def async_step_user(
3637
{
3738
vol.Required(CONF_HOST): str,
3839
vol.Required(CONF_PORT): int,
40+
vol.Optional(
41+
CONF_SERVICE_USER_NAME,
42+
default=socket.gethostname(),
43+
): str,
3944
}
4045
),
4146
errors={},
@@ -62,7 +67,9 @@ async def async_step_link(
6267

6368
errors = {}
6469

65-
fbx = await get_api(self.hass, self._data[CONF_HOST])
70+
fbx = await get_api(
71+
self.hass, self._data[CONF_HOST], self._data[CONF_SERVICE_USER_NAME]
72+
)
6673
try:
6774
# Open connection and check authentication
6875
await fbx.open(self._data[CONF_HOST], self._data[CONF_PORT])

homeassistant/components/freebox/const.py

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
STORAGE_VERSION = 1
3636

3737

38+
CONF_SERVICE_USER_NAME = "service_user_name"
39+
3840
CONNECTION_SENSORS_KEYS = {"rate_down", "rate_up"}
3941

4042
# Icons

homeassistant/components/freebox/router.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,16 @@ def is_json(json_str: str) -> bool:
5353
return True
5454

5555

56-
async def get_api(hass: HomeAssistant, host: str) -> Freepybox:
56+
def read_device_name_from_file(token_file: Path) -> str:
57+
"""Read the device_name of the file."""
58+
with open(token_file, encoding="utf-8") as f:
59+
data = json.load(f)
60+
return data["device_name"]
61+
62+
63+
async def get_api(
64+
hass: HomeAssistant, host: str, serviceName: str | None = None
65+
) -> Freepybox:
5766
"""Get the Freebox API."""
5867
freebox_path = Store(hass, STORAGE_VERSION, STORAGE_KEY).path
5968

@@ -62,6 +71,13 @@ async def get_api(hass: HomeAssistant, host: str) -> Freepybox:
6271

6372
token_file = Path(f"{freebox_path}/{slugify(host)}.conf")
6473

74+
if os.path.exists(token_file):
75+
APP_DESC["device_name"] = await hass.async_add_executor_job(
76+
read_device_name_from_file, token_file
77+
)
78+
elif serviceName is not None:
79+
APP_DESC["device_name"] = serviceName
80+
6581
return Freepybox(APP_DESC, token_file, API_VERSION)
6682

6783

@@ -110,6 +126,7 @@ def __init__(
110126
self.hass = hass
111127
self._host = entry.data[CONF_HOST]
112128
self._port = entry.data[CONF_PORT]
129+
self._serviceName = APP_DESC["device_name"]
113130

114131
self._api: Freepybox = api
115132
self.name: str = freebox_config["model_info"]["pretty_name"]

homeassistant/components/freebox/strings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"user": {
55
"data": {
66
"host": "[%key:common::config_flow::data::host%]",
7-
"port": "[%key:common::config_flow::data::port%]"
7+
"port": "[%key:common::config_flow::data::port%]",
8+
"service_user_name": "Service name"
89
},
910
"data_description": {
1011
"host": "The hostname or IP address of your Freebox router."

tests/components/freebox/common.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
from unittest.mock import patch
44

5-
from homeassistant.components.freebox.const import DOMAIN
5+
from homeassistant.components.freebox.const import CONF_SERVICE_USER_NAME, DOMAIN
66
from homeassistant.const import CONF_HOST, CONF_PORT
77
from homeassistant.core import HomeAssistant
88
from homeassistant.setup import async_setup_component
99

10-
from .const import MOCK_HOST, MOCK_PORT
10+
from .const import MOCK_CONF_SERVICE_USER_NAME, MOCK_HOST, MOCK_PORT
1111

1212
from tests.common import MockConfigEntry
1313

@@ -16,7 +16,11 @@ async def setup_platform(hass: HomeAssistant, platform: str) -> MockConfigEntry:
1616
"""Set up the Freebox platform."""
1717
mock_entry = MockConfigEntry(
1818
domain=DOMAIN,
19-
data={CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT},
19+
data={
20+
CONF_HOST: MOCK_HOST,
21+
CONF_PORT: MOCK_PORT,
22+
CONF_SERVICE_USER_NAME: MOCK_CONF_SERVICE_USER_NAME,
23+
},
2024
unique_id=MOCK_HOST,
2125
)
2226
mock_entry.add_to_hass(hass)

tests/components/freebox/conftest.py

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def mock_path():
3434
with (
3535
patch("homeassistant.components.freebox.router.Path"),
3636
patch("homeassistant.components.freebox.router.os.makedirs"),
37+
patch("homeassistant.components.freebox.router.read_device_name_from_file"),
3738
):
3839
yield
3940

tests/components/freebox/const.py

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
MOCK_HOST = "myrouter.freeboxos.fr"
66
MOCK_PORT = 1234
7+
MOCK_CONF_SERVICE_USER_NAME = "My customer service name"
78

89
# router
910
DATA_SYSTEM_GET_CONFIG = load_json_object_fixture("freebox/system_get_config.json")

tests/components/freebox/test_config_flow.py

+32-8
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
InvalidTokenError,
1010
)
1111

12-
from homeassistant.components.freebox.const import DOMAIN
12+
from homeassistant.components.freebox.const import CONF_SERVICE_USER_NAME, DOMAIN
1313
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
1414
from homeassistant.const import CONF_HOST, CONF_PORT
1515
from homeassistant.core import HomeAssistant
1616
from homeassistant.data_entry_flow import FlowResultType
1717
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
1818

19-
from .const import MOCK_HOST, MOCK_PORT
19+
from .const import MOCK_CONF_SERVICE_USER_NAME, MOCK_HOST, MOCK_PORT
2020

2121
from tests.common import MockConfigEntry
2222

@@ -53,7 +53,11 @@ async def test_user(hass: HomeAssistant) -> None:
5353
result = await hass.config_entries.flow.async_init(
5454
DOMAIN,
5555
context={"source": SOURCE_USER},
56-
data={CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT},
56+
data={
57+
CONF_HOST: MOCK_HOST,
58+
CONF_PORT: MOCK_PORT,
59+
CONF_SERVICE_USER_NAME: MOCK_CONF_SERVICE_USER_NAME,
60+
},
5761
)
5862
assert result["type"] is FlowResultType.FORM
5963
assert result["step_id"] == "link"
@@ -79,7 +83,11 @@ async def internal_test_link(hass: HomeAssistant) -> None:
7983
result = await hass.config_entries.flow.async_init(
8084
DOMAIN,
8185
context={"source": SOURCE_USER},
82-
data={CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT},
86+
data={
87+
CONF_HOST: MOCK_HOST,
88+
CONF_PORT: MOCK_PORT,
89+
CONF_SERVICE_USER_NAME: MOCK_CONF_SERVICE_USER_NAME,
90+
},
8391
)
8492

8593
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
@@ -109,7 +117,11 @@ async def test_link_bridge_mode_error(
109117
result = await hass.config_entries.flow.async_init(
110118
DOMAIN,
111119
context={"source": SOURCE_USER},
112-
data={CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT},
120+
data={
121+
CONF_HOST: MOCK_HOST,
122+
CONF_PORT: MOCK_PORT,
123+
CONF_SERVICE_USER_NAME: MOCK_CONF_SERVICE_USER_NAME,
124+
},
113125
)
114126
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
115127
assert result["type"] is FlowResultType.FORM
@@ -120,15 +132,23 @@ async def test_abort_if_already_setup(hass: HomeAssistant) -> None:
120132
"""Test we abort if component is already setup."""
121133
MockConfigEntry(
122134
domain=DOMAIN,
123-
data={CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT},
135+
data={
136+
CONF_HOST: MOCK_HOST,
137+
CONF_PORT: MOCK_PORT,
138+
CONF_SERVICE_USER_NAME: MOCK_CONF_SERVICE_USER_NAME,
139+
},
124140
unique_id=MOCK_HOST,
125141
).add_to_hass(hass)
126142

127143
# Should fail, same MOCK_HOST (flow)
128144
result = await hass.config_entries.flow.async_init(
129145
DOMAIN,
130146
context={"source": SOURCE_USER},
131-
data={CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT},
147+
data={
148+
CONF_HOST: MOCK_HOST,
149+
CONF_PORT: MOCK_PORT,
150+
CONF_SERVICE_USER_NAME: MOCK_CONF_SERVICE_USER_NAME,
151+
},
132152
)
133153
assert result["type"] is FlowResultType.ABORT
134154
assert result["reason"] == "already_configured"
@@ -139,7 +159,11 @@ async def test_on_link_failed(hass: HomeAssistant) -> None:
139159
result = await hass.config_entries.flow.async_init(
140160
DOMAIN,
141161
context={"source": SOURCE_USER},
142-
data={CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT},
162+
data={
163+
CONF_HOST: MOCK_HOST,
164+
CONF_PORT: MOCK_PORT,
165+
CONF_SERVICE_USER_NAME: MOCK_CONF_SERVICE_USER_NAME,
166+
},
143167
)
144168

145169
with patch(

tests/components/freebox/test_init.py

+25-5
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@
55
from pytest_unordered import unordered
66

77
from homeassistant.components.device_tracker import DOMAIN as DT_DOMAIN
8-
from homeassistant.components.freebox.const import DOMAIN, SERVICE_REBOOT
8+
from homeassistant.components.freebox.const import (
9+
CONF_SERVICE_USER_NAME,
10+
DOMAIN,
11+
SERVICE_REBOOT,
12+
)
913
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
1014
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
1115
from homeassistant.config_entries import ConfigEntryState
1216
from homeassistant.const import CONF_HOST, CONF_PORT, STATE_UNAVAILABLE
1317
from homeassistant.core import HomeAssistant
1418
from homeassistant.setup import async_setup_component
1519

16-
from .const import MOCK_HOST, MOCK_PORT
20+
from .const import MOCK_CONF_SERVICE_USER_NAME, MOCK_HOST, MOCK_PORT
1721

1822
from tests.common import MockConfigEntry
1923

@@ -22,7 +26,11 @@ async def test_setup(hass: HomeAssistant, router: Mock) -> None:
2226
"""Test setup of integration."""
2327
entry = MockConfigEntry(
2428
domain=DOMAIN,
25-
data={CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT},
29+
data={
30+
CONF_HOST: MOCK_HOST,
31+
CONF_PORT: MOCK_PORT,
32+
CONF_SERVICE_USER_NAME: MOCK_CONF_SERVICE_USER_NAME,
33+
},
2634
unique_id=MOCK_HOST,
2735
)
2836
entry.add_to_hass(hass)
@@ -52,12 +60,24 @@ async def test_setup_import(hass: HomeAssistant, router: Mock) -> None:
5260

5361
entry = MockConfigEntry(
5462
domain=DOMAIN,
55-
data={CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT},
63+
data={
64+
CONF_HOST: MOCK_HOST,
65+
CONF_PORT: MOCK_PORT,
66+
CONF_SERVICE_USER_NAME: MOCK_CONF_SERVICE_USER_NAME,
67+
},
5668
unique_id=MOCK_HOST,
5769
)
5870
entry.add_to_hass(hass)
5971
assert await async_setup_component(
60-
hass, DOMAIN, {DOMAIN: {CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT}}
72+
hass,
73+
DOMAIN,
74+
{
75+
DOMAIN: {
76+
CONF_HOST: MOCK_HOST,
77+
CONF_PORT: MOCK_PORT,
78+
CONF_SERVICE_USER_NAME: MOCK_CONF_SERVICE_USER_NAME,
79+
}
80+
},
6181
)
6282
await hass.async_block_till_done()
6383
assert hass.config_entries.async_entries() == unordered([entry, ANY])

0 commit comments

Comments
 (0)