mirror of
https://github.com/home-assistant/core.git
synced 2025-07-07 21:37:07 +00:00
Refactor onewire options flow tests (#87711)
This commit is contained in:
parent
330e1c6cbb
commit
678d1e367d
@ -1,18 +1,27 @@
|
||||
"""Tests for 1-Wire config flow."""
|
||||
from collections.abc import Generator
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from pyownet import protocol
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.onewire.const import DOMAIN
|
||||
from homeassistant.components.onewire.const import (
|
||||
DOMAIN,
|
||||
INPUT_ENTRY_CLEAR_OPTIONS,
|
||||
INPUT_ENTRY_DEVICE_SELECTION,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_USER, ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.config_validation import ensure_list
|
||||
|
||||
from .const import MOCK_OWPROXY_DEVICES
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, name="mock_setup_entry")
|
||||
def override_async_setup_entry() -> AsyncMock:
|
||||
def override_async_setup_entry() -> Generator[AsyncMock, None, None]:
|
||||
"""Override async_setup_entry."""
|
||||
with patch(
|
||||
"homeassistant.components.onewire.async_setup_entry", return_value=True
|
||||
@ -20,7 +29,25 @@ def override_async_setup_entry() -> AsyncMock:
|
||||
yield mock_setup_entry
|
||||
|
||||
|
||||
async def test_user_flow(hass: HomeAssistant, mock_setup_entry: AsyncMock):
|
||||
@pytest.fixture
|
||||
async def filled_device_registry(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry, device_registry: dr.DeviceRegistry
|
||||
) -> dr.DeviceRegistry:
|
||||
"""Fill device registry with mock devices."""
|
||||
for device_details in MOCK_OWPROXY_DEVICES.values():
|
||||
if infos := device_details.get("device_info"):
|
||||
for info in ensure_list(infos):
|
||||
device_registry.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
identifiers=info["identifiers"],
|
||||
manufacturer=info["manufacturer"],
|
||||
model=info["model"],
|
||||
name=info["name"],
|
||||
)
|
||||
return device_registry
|
||||
|
||||
|
||||
async def test_user_flow(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
||||
"""Test user flow."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
@ -63,7 +90,7 @@ async def test_user_flow(hass: HomeAssistant, mock_setup_entry: AsyncMock):
|
||||
|
||||
async def test_user_duplicate(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry, mock_setup_entry: AsyncMock
|
||||
):
|
||||
) -> None:
|
||||
"""Test user duplicate flow."""
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
@ -85,3 +112,167 @@ async def test_user_duplicate(
|
||||
assert result["reason"] == "already_configured"
|
||||
await hass.async_block_till_done()
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("filled_device_registry")
|
||||
async def test_user_options_clear(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> None:
|
||||
"""Test clearing the options."""
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
# Verify that first config step comes back with a selection list of all the 28-family devices
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["data_schema"].schema["device_selection"].options == {
|
||||
"28.111111111111": False,
|
||||
"28.222222222222": False,
|
||||
"28.222222222223": False,
|
||||
}
|
||||
|
||||
# Verify that the clear-input action clears the options dict
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={INPUT_ENTRY_CLEAR_OPTIONS: True},
|
||||
)
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["data"] == {}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("filled_device_registry")
|
||||
async def test_user_options_empty_selection(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> None:
|
||||
"""Test leaving the selection of devices empty."""
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
# Verify that first config step comes back with a selection list of all the 28-family devices
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["data_schema"].schema["device_selection"].options == {
|
||||
"28.111111111111": False,
|
||||
"28.222222222222": False,
|
||||
"28.222222222223": False,
|
||||
}
|
||||
|
||||
# Verify that an empty selection does not modify the options
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={INPUT_ENTRY_DEVICE_SELECTION: []},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == "device_selection"
|
||||
assert result["errors"] == {"base": "device_not_selected"}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("filled_device_registry")
|
||||
async def test_user_options_set_single(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> None:
|
||||
"""Test configuring a single device."""
|
||||
# Clear config options to certify functionality when starting from scratch
|
||||
config_entry.options = {}
|
||||
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
# Verify that first config step comes back with a selection list of all the 28-family devices
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["data_schema"].schema["device_selection"].options == {
|
||||
"28.111111111111": False,
|
||||
"28.222222222222": False,
|
||||
"28.222222222223": False,
|
||||
}
|
||||
|
||||
# Verify that a single selected device to configure comes back as a form with the device to configure
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={INPUT_ENTRY_DEVICE_SELECTION: ["28.111111111111"]},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["description_placeholders"]["sensor_id"] == "28.111111111111"
|
||||
|
||||
# Verify that the setting for the device comes back as default when no input is given
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={},
|
||||
)
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert (
|
||||
result["data"]["device_options"]["28.111111111111"]["precision"]
|
||||
== "temperature"
|
||||
)
|
||||
|
||||
|
||||
async def test_user_options_set_multiple(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
filled_device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test configuring multiple consecutive devices in a row."""
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
# Verify that first config step comes back with a selection list of all the 28-family devices
|
||||
for entry in dr.async_entries_for_config_entry(
|
||||
filled_device_registry, config_entry.entry_id
|
||||
):
|
||||
filled_device_registry.async_update_device(entry.id, name_by_user="Given Name")
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["data_schema"].schema["device_selection"].options == {
|
||||
"Given Name (28.111111111111)": False,
|
||||
"Given Name (28.222222222222)": False,
|
||||
"Given Name (28.222222222223)": False,
|
||||
}
|
||||
|
||||
# Verify that selecting two devices to configure comes back as a
|
||||
# form with the first device to configure using it's long name as entry
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
INPUT_ENTRY_DEVICE_SELECTION: [
|
||||
"Given Name (28.111111111111)",
|
||||
"Given Name (28.222222222222)",
|
||||
]
|
||||
},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert (
|
||||
result["description_placeholders"]["sensor_id"]
|
||||
== "Given Name (28.222222222222)"
|
||||
)
|
||||
|
||||
# Verify that next sensor is coming up for configuration after the first
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"precision": "temperature"},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert (
|
||||
result["description_placeholders"]["sensor_id"]
|
||||
== "Given Name (28.111111111111)"
|
||||
)
|
||||
|
||||
# Verify that the setting for the device comes back as default when no input is given
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"precision": "temperature9"},
|
||||
)
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert (
|
||||
result["data"]["device_options"]["28.222222222222"]["precision"]
|
||||
== "temperature"
|
||||
)
|
||||
assert (
|
||||
result["data"]["device_options"]["28.111111111111"]["precision"]
|
||||
== "temperature9"
|
||||
)
|
||||
|
||||
|
||||
async def test_user_options_no_devices(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> None:
|
||||
"""Test that options does not change when no devices are available."""
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
# Verify that first config step comes back with an empty list of possible devices to choose from
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert result["type"] == FlowResultType.ABORT
|
||||
assert result["reason"] == "No configurable devices found."
|
||||
|
@ -1,215 +0,0 @@
|
||||
"""Tests for 1-Wire config flow."""
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from homeassistant.components.onewire.const import (
|
||||
INPUT_ENTRY_CLEAR_OPTIONS,
|
||||
INPUT_ENTRY_DEVICE_SELECTION,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
|
||||
from . import setup_owproxy_mock_devices
|
||||
from .const import MOCK_OWPROXY_DEVICES
|
||||
|
||||
|
||||
class FakeDevice:
|
||||
"""Mock Class for mocking DeviceEntry."""
|
||||
|
||||
name_by_user = "Given Name"
|
||||
|
||||
|
||||
async def test_user_options_clear(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
owproxy: MagicMock,
|
||||
):
|
||||
"""Test clearing the options."""
|
||||
setup_owproxy_mock_devices(
|
||||
owproxy, Platform.SENSOR, [x for x in MOCK_OWPROXY_DEVICES if "28." in x]
|
||||
)
|
||||
|
||||
# Verify that first config step comes back with a selection list of all the 28-family devices
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["data_schema"].schema["device_selection"].options == {
|
||||
"28.111111111111": False,
|
||||
"28.222222222222": False,
|
||||
"28.222222222223": False,
|
||||
}
|
||||
|
||||
# Verify that the clear-input action clears the options dict
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={INPUT_ENTRY_CLEAR_OPTIONS: True},
|
||||
)
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["data"] == {}
|
||||
|
||||
|
||||
async def test_user_options_empty_selection(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
owproxy: MagicMock,
|
||||
):
|
||||
"""Test leaving the selection of devices empty."""
|
||||
setup_owproxy_mock_devices(
|
||||
owproxy, Platform.SENSOR, [x for x in MOCK_OWPROXY_DEVICES if "28." in x]
|
||||
)
|
||||
|
||||
# Verify that first config step comes back with a selection list of all the 28-family devices
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["data_schema"].schema["device_selection"].options == {
|
||||
"28.111111111111": False,
|
||||
"28.222222222222": False,
|
||||
"28.222222222223": False,
|
||||
}
|
||||
|
||||
# Verify that an empty selection does not modify the options
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={INPUT_ENTRY_DEVICE_SELECTION: []},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == "device_selection"
|
||||
assert result["errors"] == {"base": "device_not_selected"}
|
||||
|
||||
|
||||
async def test_user_options_set_single(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
owproxy: MagicMock,
|
||||
):
|
||||
"""Test configuring a single device."""
|
||||
setup_owproxy_mock_devices(
|
||||
owproxy, Platform.SENSOR, [x for x in MOCK_OWPROXY_DEVICES if "28." in x]
|
||||
)
|
||||
|
||||
# Clear config options to certify functionality when starting from scratch
|
||||
config_entry.options = {}
|
||||
|
||||
# Verify that first config step comes back with a selection list of all the 28-family devices
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["data_schema"].schema["device_selection"].options == {
|
||||
"28.111111111111": False,
|
||||
"28.222222222222": False,
|
||||
"28.222222222223": False,
|
||||
}
|
||||
|
||||
# Verify that a single selected device to configure comes back as a form with the device to configure
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={INPUT_ENTRY_DEVICE_SELECTION: ["28.111111111111"]},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["description_placeholders"]["sensor_id"] == "28.111111111111"
|
||||
|
||||
# Verify that the setting for the device comes back as default when no input is given
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={},
|
||||
)
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert (
|
||||
result["data"]["device_options"]["28.111111111111"]["precision"]
|
||||
== "temperature"
|
||||
)
|
||||
|
||||
|
||||
async def test_user_options_set_multiple(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
owproxy: MagicMock,
|
||||
):
|
||||
"""Test configuring multiple consecutive devices in a row."""
|
||||
setup_owproxy_mock_devices(
|
||||
owproxy, Platform.SENSOR, [x for x in MOCK_OWPROXY_DEVICES if "28." in x]
|
||||
)
|
||||
|
||||
# Initialize onewire hub
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify that first config step comes back with a selection list of all the 28-family devices
|
||||
device_registry = dr.async_get(hass)
|
||||
for entry in dr.async_entries_for_config_entry(
|
||||
device_registry, config_entry.entry_id
|
||||
):
|
||||
device_registry.async_update_device(entry.id, name_by_user="Given Name")
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["data_schema"].schema["device_selection"].options == {
|
||||
"Given Name (28.111111111111)": False,
|
||||
"Given Name (28.222222222222)": False,
|
||||
"Given Name (28.222222222223)": False,
|
||||
}
|
||||
|
||||
# Verify that selecting two devices to configure comes back as a
|
||||
# form with the first device to configure using it's long name as entry
|
||||
with patch(
|
||||
"homeassistant.helpers.device_registry.DeviceRegistry.async_get_device",
|
||||
return_value=FakeDevice(),
|
||||
):
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
INPUT_ENTRY_DEVICE_SELECTION: [
|
||||
"Given Name (28.111111111111)",
|
||||
"Given Name (28.222222222222)",
|
||||
]
|
||||
},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert (
|
||||
result["description_placeholders"]["sensor_id"]
|
||||
== "Given Name (28.222222222222)"
|
||||
)
|
||||
|
||||
# Verify that next sensor is coming up for configuration after the first
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"precision": "temperature"},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert (
|
||||
result["description_placeholders"]["sensor_id"]
|
||||
== "Given Name (28.111111111111)"
|
||||
)
|
||||
|
||||
# Verify that the setting for the device comes back as default when no input is given
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"precision": "temperature9"},
|
||||
)
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert (
|
||||
result["data"]["device_options"]["28.222222222222"]["precision"]
|
||||
== "temperature"
|
||||
)
|
||||
assert (
|
||||
result["data"]["device_options"]["28.111111111111"]["precision"]
|
||||
== "temperature9"
|
||||
)
|
||||
|
||||
|
||||
async def test_user_options_no_devices(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
owproxy: MagicMock,
|
||||
):
|
||||
"""Test that options does not change when no devices are available."""
|
||||
# Initialize onewire hub
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify that first config step comes back with an empty list of possible devices to choose from
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert result["type"] == FlowResultType.ABORT
|
||||
assert result["reason"] == "No configurable devices found."
|
Loading…
x
Reference in New Issue
Block a user