Skip to content

Commit

Permalink
Refactor onewire options flow tests (home-assistant#87711)
Browse files Browse the repository at this point in the history
  • Loading branch information
epenet authored Feb 9, 2023
1 parent 330e1c6 commit 678d1e3
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 219 deletions.
199 changes: 195 additions & 4 deletions tests/components/onewire/test_config_flow.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,53 @@
"""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
) as mock_setup_entry:
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}
Expand Down Expand Up @@ -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()
Expand All @@ -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."
Loading

0 comments on commit 678d1e3

Please sign in to comment.