"""Tests for the user-initiated config flow.""" from __future__ import annotations from homeassistant import config_entries from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType from custom_components.main_gate_controller.const import ( CONF_NAME, CONF_NOTIFY_ENABLED, CONF_NOTIFY_ENTITIES, CONF_SWITCH_ENTITY_ID, DOMAIN, ) from tests.conftest import make_entry_data async def _start_user_flow(hass: HomeAssistant) -> str: """Initiate the user config flow and return its flow_id.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) assert result["type"] == FlowResultType.FORM assert result["step_id"] == "user" return result["flow_id"] async def test_user_flow_creates_entry( hass: HomeAssistant, gate_switch: str, notify_entity: str ): """Valid input creates a config entry.""" flow_id = await _start_user_flow(hass) user_input = make_entry_data( switch_entity_id=gate_switch, name="Main Gate", open_duration=20, pulse_duration=1.0, notify_enabled=False, notify_entities=[], ) result = await hass.config_entries.flow.async_configure(flow_id, user_input) await hass.async_block_till_done() assert result["type"] == FlowResultType.CREATE_ENTRY assert result["title"] == "Main Gate" assert result["data"][CONF_SWITCH_ENTITY_ID] == gate_switch assert result["data"][CONF_NAME] == "Main Gate" async def test_duplicate_switch_aborts(hass: HomeAssistant, gate_switch: str): """Setting up the same switch twice aborts with ``already_configured``.""" flow_id = await _start_user_flow(hass) user_input = make_entry_data(switch_entity_id=gate_switch, name="Gate A") first = await hass.config_entries.flow.async_configure(flow_id, user_input) await hass.async_block_till_done() assert first["type"] == FlowResultType.CREATE_ENTRY # Start a second flow with the same switch. result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) assert result["type"] == FlowResultType.FORM flow_id = result["flow_id"] second = await hass.config_entries.flow.async_configure(flow_id, user_input) await hass.async_block_till_done() assert second["type"] == FlowResultType.ABORT assert second["reason"] == "already_configured" async def test_missing_notify_targets_shows_error( hass: HomeAssistant, gate_switch: str, notify_entity: str ): """Enabling notifications without targets reports a validation error.""" flow_id = await _start_user_flow(hass) user_input = make_entry_data( switch_entity_id=gate_switch, name="Main Gate", notify_enabled=True, notify_entities=[], ) result = await hass.config_entries.flow.async_configure(flow_id, user_input) await hass.async_block_till_done() assert result["type"] == FlowResultType.FORM assert result["errors"] == {CONF_NOTIFY_ENTITIES: "notify_no_targets"} async def test_unknown_switch_entity_shows_error( hass: HomeAssistant, gate_switch: str ): """A non-existent switch entity surfaces a ``switch_not_found`` error.""" flow_id = await _start_user_flow(hass) user_input = make_entry_data(switch_entity_id="switch.ghost") result = await hass.config_entries.flow.async_configure(flow_id, user_input) await hass.async_block_till_done() assert result["type"] == FlowResultType.FORM # The error key is the field name; the exact key depends on whether the # entity selector also rejects the value. Either path must surface an error. assert any(k == CONF_SWITCH_ENTITY_ID for k in result["errors"]) async def test_blank_name_shows_error(hass: HomeAssistant, gate_switch: str): """An empty/whitespace-only name is rejected.""" flow_id = await _start_user_flow(hass) user_input = make_entry_data(switch_entity_id=gate_switch, name=" ") result = await hass.config_entries.flow.async_configure(flow_id, user_input) await hass.async_block_till_done() assert result["type"] == FlowResultType.FORM assert result["errors"] == {CONF_NAME: "invalid_name"} async def test_notify_with_targets_succeeds( hass: HomeAssistant, gate_switch: str, notify_entity: str ): """Enabling notifications with at least one target is accepted.""" flow_id = await _start_user_flow(hass) user_input = make_entry_data( switch_entity_id=gate_switch, name="Main Gate", notify_enabled=True, notify_entities=[notify_entity], ) result = await hass.config_entries.flow.async_configure(flow_id, user_input) await hass.async_block_till_done() assert result["type"] == FlowResultType.CREATE_ENTRY assert result["data"][CONF_NOTIFY_ENABLED] is True assert result["data"][CONF_NOTIFY_ENTITIES] == [notify_entity]