Skip to content

Commit

Permalink
fix test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
CFenner committed Jan 15, 2024
1 parent d8c9d8a commit bfb9fb4
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 84 deletions.
43 changes: 24 additions & 19 deletions homeassistant/components/vicare/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from homeassistant.helpers.storage import STORAGE_DIR

from .const import (
CONF_ACTIVE_DEVICES,
CONF_ACTIVE_DEVICE,
CONF_HEATING_TYPE,
DOMAIN,
HEATING_TYPE_TO_CREATOR_METHOD,
Expand All @@ -33,27 +33,27 @@
_LOGGER = logging.getLogger(__name__)


def _get_active_device_list(hass: HomeAssistant, entry: ConfigEntry) -> list[str]:
def _get_active_device_for_migration(hass: HomeAssistant, entry: ConfigEntry) -> str:
"""Return the serial of the first element of the device config list (migration helper)."""
device_list = get_device_config_list(hass, entry.data)
# Currently we only support a single device
return [get_serial(device_list[0])]
return get_serial(device_list[0])


async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Migrate old entry."""

if entry.version == 1:
_LOGGER.debug("Migrating from version %s", entry.version)
serials = await hass.async_add_executor_job(
_get_active_device_list, hass, entry
serial = await hass.async_add_executor_job(
_get_active_device_for_migration, hass, entry
)
entry.version = 2
hass.config_entries.async_update_entry(
entry,
data={
**entry.data,
CONF_ACTIVE_DEVICES: serials,
CONF_ACTIVE_DEVICE: serial,
},
)
_LOGGER.debug("Migration to version %s successful", entry.version)
Expand All @@ -78,14 +78,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True


async def async_update_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Update a given config entry."""
await hass.config_entries.async_reload(entry.entry_id)


def setup_vicare_api(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Set up PyVicare API."""
device_list = get_configured_devices(
get_device_config_list(hass, entry.data), entry
)

device_list = get_device_config_list(hass, entry.data)
# Currently we only support a single device
device = device_list[0]
device = get_configured_device(device_list, entry)
hass.data[DOMAIN][entry.entry_id][VICARE_DEVICE_CONFIG_LIST] = device_list
hass.data[DOMAIN][entry.entry_id][VICARE_DEVICE_CONFIG] = device
hass.data[DOMAIN][entry.entry_id][VICARE_API] = getattr(
Expand All @@ -108,13 +110,16 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return unload_ok


def get_configured_devices(
def get_configured_device(
devices: list[PyViCareDeviceConfig],
entry: ConfigEntry,
) -> list[PyViCareDeviceConfig]:
"""Return list of configured devices."""
return [
device_config
for device_config in devices
if get_serial(device_config) in entry.data[CONF_ACTIVE_DEVICES]
]
) -> PyViCareDeviceConfig:
"""Return the configured device."""
active_device: str = entry.options.get(
CONF_ACTIVE_DEVICE, entry.data.get(CONF_ACTIVE_DEVICE)
)

for device_config in devices:
if get_serial(device_config) == active_device:
return device_config
return None
88 changes: 39 additions & 49 deletions homeassistant/components/vicare/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@
)

from .const import (
CONF_ACTIVE_DEVICES,
CONF_ACTIVE_DEVICE,
CONF_HEATING_TYPE,
DEFAULT_HEATING_TYPE,
DOMAIN,
VICARE_NAME,
HeatingType,
)
from .utils import get_device_config_list, login
from .utils import get_device_config_list, get_device_serial_model_list, vicare_login

_LOGGER = logging.getLogger(__name__)

Expand All @@ -54,32 +54,22 @@
)


def _get_option_list(
hass: HomeAssistant, entry: config_entries.ConfigEntry
) -> list[SelectOptionDict]:
device_list = get_device_config_list(hass, entry.data)
return [
# we cannot always use device_config.getConfig().serial as it returns the gateway serial for all connected devices
SelectOptionDict(
value=device_config.getConfig().serial,
label=f"{device_config.getConfig().serial} ({device_config.getModel()})",
)
if device_config.getModel() == "Heatbox1"
# we cannot always use device.getSerial() either as there is a different API endpoint used for gateways that does not provide the serial (yet)
else SelectOptionDict(
value=device_config.asAutoDetectDevice().getSerial(),
label=f"{device_config.asAutoDetectDevice().getSerial()} ({device_config.getModel()})",
)
for device_config in device_list
]
def _get_device_list(
hass: HomeAssistant, entry_data: dict[str, Any]
) -> list[tuple[str, str]]:
# device_list = hass.data[DOMAIN][entry.entry_id].get(
# VICARE_DEVICE_CONFIG_LIST, get_device_config_list(hass, entry.data)
# )
device_list = get_device_config_list(hass, entry_data)
return get_device_serial_model_list(hass, device_list)


class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for ViCare."""

VERSION = 2
entry: config_entries.ConfigEntry | None
available_devices: list[SelectOptionDict] = []
available_devices: list[tuple[str, str]] = []

async def async_step_user(
self, user_input: dict[str, Any] | None = None
Expand All @@ -92,23 +82,24 @@ async def async_step_user(
if user_input is not None:
try:
self.available_devices = await self.hass.async_add_executor_job(
_get_option_list,
_get_device_list,
self.hass,
user_input,
)
except (PyViCareInvalidConfigurationError, PyViCareInvalidCredentialsError):
errors["base"] = "invalid_auth"
else:
if len(self.available_devices) > 1:
return await self.async_step_select()

Check warning on line 93 in homeassistant/components/vicare/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/vicare/config_flow.py#L93

Added line #L93 was not covered by tests
if len(self.available_devices) == 1:
return self.async_create_entry(
title=VICARE_NAME,
data={
**user_input,
CONF_ACTIVE_DEVICES: self.available_devices[0]["value"],
CONF_ACTIVE_DEVICE: self.available_devices[0][0],
},
)
return await self.async_step_select()

errors["base"] = "no_devices"

Check warning on line 102 in homeassistant/components/vicare/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/vicare/config_flow.py#L102

Added line #L102 was not covered by tests
return self.async_show_form(
step_id="user",
data_schema=USER_SCHEMA,
Expand All @@ -123,18 +114,17 @@ async def async_step_select(
if user_input is not None:
return self.async_create_entry(title="", data=user_input)

Check warning on line 115 in homeassistant/components/vicare/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/vicare/config_flow.py#L113-L115

Added lines #L113 - L115 were not covered by tests

suggested_values: Mapping[str, Any] = {}
if self.entry is not None:
suggested_values = {
CONF_ACTIVE_DEVICES: self.entry.data[CONF_ACTIVE_DEVICES]
}

schema = (

Check warning on line 117 in homeassistant/components/vicare/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/vicare/config_flow.py#L117

Added line #L117 was not covered by tests
vol.Schema(
{
vol.Required(CONF_ACTIVE_DEVICES): SelectSelector(
vol.Required(CONF_ACTIVE_DEVICE): SelectSelector(
SelectSelectorConfig(
options=self.available_devices,
options=[
SelectOptionDict(
value=serial, label=f"{serial} ({model})"
)
for serial, model in self.available_devices
],
multiple=False,
mode=SelectSelectorMode.LIST,
),
Expand All @@ -145,10 +135,7 @@ async def async_step_select(

return self.async_show_form(

Check warning on line 136 in homeassistant/components/vicare/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/vicare/config_flow.py#L136

Added line #L136 was not covered by tests
step_id="select",
data_schema=self.add_suggested_values_to_schema(
schema,
suggested_values,
),
data_schema=schema,
errors=errors,
)

Expand All @@ -171,7 +158,7 @@ async def async_step_reauth_confirm(
}

try:
await self.hass.async_add_executor_job(login, self.hass, data)
await self.hass.async_add_executor_job(vicare_login, self.hass, data)
except (PyViCareInvalidConfigurationError, PyViCareInvalidCredentialsError):
errors["base"] = "invalid_auth"
else:
Expand Down Expand Up @@ -215,6 +202,8 @@ def async_get_options_flow(
class OptionsFlowHandler(config_entries.OptionsFlow):
"""Options flow handler."""

available_devices: list[tuple[str, str]] = []

def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
"""Initialize options flow."""
self.entry = config_entry

Check warning on line 209 in homeassistant/components/vicare/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/vicare/config_flow.py#L209

Added line #L209 was not covered by tests
Expand All @@ -228,33 +217,34 @@ async def async_step_init(
return self.async_create_entry(data=user_input)

Check warning on line 217 in homeassistant/components/vicare/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/vicare/config_flow.py#L215-L217

Added lines #L215 - L217 were not covered by tests

try:
options_list: list[
SelectOptionDict
] = await self.hass.async_add_executor_job(
_get_option_list, self.hass, self.entry
self.available_devices = await self.hass.async_add_executor_job(

Check warning on line 220 in homeassistant/components/vicare/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/vicare/config_flow.py#L219-L220

Added lines #L219 - L220 were not covered by tests
_get_device_list,
self.hass,
user_input,
)
except (PyViCareInvalidConfigurationError, PyViCareInvalidCredentialsError):
errors["base"] = "invalid_auth"

Check warning on line 226 in homeassistant/components/vicare/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/vicare/config_flow.py#L225-L226

Added lines #L225 - L226 were not covered by tests

suggested_values: Mapping[str, Any] = {
CONF_ACTIVE_DEVICES: self.entry.data[CONF_ACTIVE_DEVICES]
}

return self.async_show_form(

Check warning on line 228 in homeassistant/components/vicare/config_flow.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/vicare/config_flow.py#L228

Added line #L228 was not covered by tests
step_id="init",
data_schema=self.add_suggested_values_to_schema(
vol.Schema(
{
vol.Required(CONF_ACTIVE_DEVICES): SelectSelector(
vol.Required(CONF_ACTIVE_DEVICE): SelectSelector(
SelectSelectorConfig(
options=options_list,
options=[
SelectOptionDict(
value=serial, label=f"{serial} ({model})"
)
for serial, model in self.available_devices
],
multiple=False,
mode=SelectSelectorMode.LIST,
),
),
}
),
suggested_values,
user_input or dict(self.entry.data),
),
errors=errors,
)
2 changes: 1 addition & 1 deletion homeassistant/components/vicare/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

CONF_CIRCUIT = "circuit"
CONF_HEATING_TYPE = "heating_type"
CONF_ACTIVE_DEVICES = "active_devices"
CONF_ACTIVE_DEVICE = "active_devices"

DEFAULT_SCAN_INTERVAL = 60

Expand Down
15 changes: 12 additions & 3 deletions homeassistant/components/vicare/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
_LOGGER = logging.getLogger(__name__)


def login(hass: HomeAssistant, entry_data: Mapping[str, Any]) -> PyViCare:
def vicare_login(hass: HomeAssistant, entry_data: Mapping[str, Any]) -> PyViCare:
"""Login via PyVicare API."""
api = PyViCare()
api.setCacheDuration(DEFAULT_SCAN_INTERVAL)
Expand Down Expand Up @@ -55,7 +55,7 @@ def get_device_config_list(
hass: HomeAssistant, entry_data: Mapping[str, Any]
) -> list[PyViCareDeviceConfig]:
"""Return the list of device configs."""
api = login(hass, entry_data)
api = vicare_login(hass, entry_data)
for device in api.devices:
_LOGGER.info(
"Found device: %s (online: %s)", device.getModel(), str(device.isOnline())
Expand Down Expand Up @@ -101,6 +101,15 @@ def get_serial(device_config: PyViCareDeviceConfig) -> str:
# we cannot always use device_config.getConfig().serial as it returns the gateway serial for all connected devices
if device_config.getModel() == "Heatbox1":
return device_config.getConfig().serial

# we cannot always use device.getSerial() either as there is a different API endpoint used for gateways that does not provide the serial (yet)
return device_config.asAutoDetectDevice().getSerial()


def get_device_serial_model_list(
hass: HomeAssistant, device_list: list[PyViCareDeviceConfig]
) -> list[tuple[str, str]]:
"""Return a list of serial / model per device config."""
return [
(get_serial(device_config), device_config.getModel())
for device_config in device_list
]
7 changes: 6 additions & 1 deletion tests/components/vicare/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from typing import Final

from homeassistant.components.vicare.const import CONF_HEATING_TYPE
from homeassistant.components.vicare.const import CONF_ACTIVE_DEVICE, CONF_HEATING_TYPE
from homeassistant.const import CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME

MODULE = "homeassistant.components.vicare"
Expand All @@ -13,6 +13,11 @@
CONF_PASSWORD: "1234",
CONF_CLIENT_ID: "5678",
CONF_HEATING_TYPE: "auto",
CONF_ACTIVE_DEVICE: "1234567890",
}

ENTRY_OPTIONS: Final[dict[str, str]] = {
CONF_ACTIVE_DEVICE: "1234567890",
}

MOCK_MAC = "B874241B7B9"
8 changes: 6 additions & 2 deletions tests/components/vicare/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def mock_config_entry() -> MockConfigEntry:
unique_id="ViCare",
entry_id="1234",
data=ENTRY_CONFIG,
version=2,
)


Expand All @@ -59,8 +60,11 @@ async def mock_vicare_gas_boiler(
"""Return a mocked ViCare API representing a single gas boiler device."""
fixtures = ["vicare/Vitodens300W.json"]
with patch(
f"{MODULE}.vicare_login",
return_value=MockPyViCare(fixtures),
f"{MODULE}.get_device_config_list",
return_value=MockPyViCare(fixtures).devices,
), patch(
f"{MODULE}.get_serial",
return_value="qwertz",
):
mock_config_entry.add_to_hass(hass)

Expand Down
2 changes: 2 additions & 0 deletions tests/components/vicare/snapshots/test_config_flow.ambr
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# serializer version: 1
# name: test_form_dhcp
dict({
'active_devices': 'qwertz',
'client_id': '5678',
'heating_type': 'auto',
'password': '1234',
Expand All @@ -9,6 +10,7 @@
# ---
# name: test_user_create_entry
dict({
'active_devices': 'qwertz',
'client_id': '5678',
'heating_type': 'auto',
'password': '1234',
Expand Down
3 changes: 2 additions & 1 deletion tests/components/vicare/snapshots/test_diagnostics.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -4697,6 +4697,7 @@
]),
'entry': dict({
'data': dict({
'active_devices': '1234567890',
'client_id': '**REDACTED**',
'heating_type': 'auto',
'password': '**REDACTED**',
Expand All @@ -4713,7 +4714,7 @@
'source': 'user',
'title': 'Mock Title',
'unique_id': 'ViCare',
'version': 1,
'version': 2,
}),
})
# ---

0 comments on commit bfb9fb4

Please sign in to comment.