Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions custom_components/schellenberg_usb/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,21 @@ async def async_step_user(

Home Assistant initiates user-triggered subentry flows via the `user`
step (per HA config-subentry docs) — NOT async_step_{subentry_type}.
Show the menu so the user can choose between auto-pair and manual-add.
Selecting an option routes to async_step_{option}: 'pair' or
'manual_add'.
Delegate to the menu so the user can choose auto-pair or manual-add.
"""
_LOGGER.debug("Subentry blind flow initiated")
return await self.async_step_menu(user_input)

async def async_step_menu(
self, user_input: dict[str, Any] | None = None
) -> SubentryFlowResult:
"""Show menu: Pair automatically or Add manually.

async_show_menu(step_id="menu") REQUIRES a matching async_step_menu
method to exist — HA validates that a shown step_id resolves to a handler
(it raises UnknownStep otherwise). Selecting an option routes to
async_step_{option}: 'pair' or 'manual_add'.
"""
return self.async_show_menu(
step_id="menu",
menu_options=["pair", "manual_add"],
Expand Down
2 changes: 1 addition & 1 deletion custom_components/schellenberg_usb/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
"manufacturer": "van ooijen"
}
],
"version": "1.1.1"
"version": "1.1.2"
}
35 changes: 35 additions & 0 deletions tests/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import pytest
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from pytest_homeassistant_custom_component.common import MockConfigEntry

from custom_components.schellenberg_usb.const import (
CONF_BIDIRECTIONAL,
Expand Down Expand Up @@ -88,6 +90,39 @@ async def test_pair_step_shows_form(
assert result["step_id"] == "pair"


@pytest.mark.asyncio
async def test_subentry_flow_entry_step_is_menu(
hass: HomeAssistant,
enable_custom_integrations: None,
) -> None:
"""Driving the real HA subentry-flow seam must land on the menu.

Regression for the v1.1.0 bug: the menu was wired to async_step_blind on the
false assumption that HA initiates a subentry flow at async_step_{subentry_type}.
HA actually initiates user-triggered subentry flows at async_step_user, so the
menu was never reachable. This test goes through
hass.config_entries.subentries.async_init — the ACTUAL seam HA uses — rather
than calling a handler method directly, so it would fail if the entry step
regressed back to async_step_blind / the old auto-pair form.
"""
entry = MockConfigEntry(
domain=DOMAIN,
title="Schellenberg USB",
data={CONF_SERIAL_PORT: "/dev/ttyUSB0"},
)
entry.add_to_hass(hass)

result = await hass.config_entries.subentries.async_init(
(entry.entry_id, SUBENTRY_TYPE_BLIND),
context={"source": "user"},
)

assert result["type"] == FlowResultType.MENU
assert result["step_id"] == "menu"
assert "pair" in result["menu_options"]
assert "manual_add" in result["menu_options"]


@pytest.mark.asyncio
async def test_manual_add_creates_subentry(
hass: HomeAssistant, mock_hub_entry: ConfigEntry
Expand Down