Initial commit: Main Gate Controller HACS integration
Tests / pytest + ruff (3.12) (push) Has been cancelled
Validate / HACS validation (push) Has been cancelled
Validate / Hassfest validation (push) Has been cancelled

This commit is contained in:
bot
2026-09-07 23:19:12 +02:00
commit 988a30cbf7
27 changed files with 2456 additions and 0 deletions
+131
View File
@@ -0,0 +1,131 @@
"""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]