mirror of
https://github.com/home-assistant/core.git
synced 2025-06-06 06:07:07 +00:00

* Fix velbusconfigflow * add tests * Paramtize the tests * Removed duplicate test in favor of another case * more comments
238 lines
7.3 KiB
Python
238 lines
7.3 KiB
Python
"""Tests for the Velbus config flow."""
|
|
|
|
from collections.abc import Generator
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import pytest
|
|
import serial.tools.list_ports
|
|
from velbusaio.exceptions import VelbusConnectionFailed
|
|
|
|
from homeassistant.components.velbus.const import CONF_TLS, DOMAIN
|
|
from homeassistant.config_entries import SOURCE_USB, SOURCE_USER
|
|
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_SOURCE
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.data_entry_flow import FlowResultType
|
|
from homeassistant.helpers.service_info.usb import UsbServiceInfo
|
|
|
|
from .const import PORT_SERIAL
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
DISCOVERY_INFO = UsbServiceInfo(
|
|
device=PORT_SERIAL,
|
|
pid="10CF",
|
|
vid="0B1B",
|
|
serial_number="1234",
|
|
description="Velbus VMB1USB",
|
|
manufacturer="Velleman",
|
|
)
|
|
|
|
USB_DEV = "/dev/ttyACME100 - Some serial port, s/n: 1234 - Virtual serial port"
|
|
|
|
|
|
def com_port():
|
|
"""Mock of a serial port."""
|
|
port = serial.tools.list_ports_common.ListPortInfo(PORT_SERIAL)
|
|
port.serial_number = "1234"
|
|
port.manufacturer = "Virtual serial port"
|
|
port.device = PORT_SERIAL
|
|
port.description = "Some serial port"
|
|
return port
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def override_async_setup_entry() -> Generator[AsyncMock]:
|
|
"""Override async_setup_entry."""
|
|
with (
|
|
patch(
|
|
"homeassistant.components.velbus.async_setup_entry", return_value=True
|
|
) as mock,
|
|
):
|
|
yield mock
|
|
|
|
|
|
@pytest.fixture(name="controller_connection_failed")
|
|
def mock_controller_connection_failed():
|
|
"""Mock the velbus controller with an assert."""
|
|
with patch("velbusaio.controller.Velbus", side_effect=VelbusConnectionFailed()):
|
|
yield
|
|
|
|
|
|
@pytest.mark.usefixtures("controller")
|
|
@pytest.mark.parametrize(
|
|
("inputParams", "expected"),
|
|
[
|
|
(
|
|
{
|
|
CONF_TLS: True,
|
|
CONF_PASSWORD: "password",
|
|
},
|
|
"tls://password@velbus:6000",
|
|
),
|
|
(
|
|
{
|
|
CONF_TLS: True,
|
|
CONF_PASSWORD: "",
|
|
},
|
|
"tls://velbus:6000",
|
|
),
|
|
({CONF_TLS: True}, "tls://velbus:6000"),
|
|
({CONF_TLS: False}, "velbus:6000"),
|
|
],
|
|
)
|
|
async def test_user_network_succes(
|
|
hass: HomeAssistant, inputParams: str, expected: str
|
|
) -> None:
|
|
"""Test user network config."""
|
|
# inttial menu show
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": SOURCE_USER}
|
|
)
|
|
assert result
|
|
assert result.get("flow_id")
|
|
assert result.get("type") is FlowResultType.MENU
|
|
assert result.get("step_id") == "user"
|
|
assert result.get("menu_options") == ["network", "usbselect"]
|
|
# select the network option
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result.get("flow_id"),
|
|
{"next_step_id": "network"},
|
|
)
|
|
assert result["type"] is FlowResultType.FORM
|
|
# fill in the network form
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result.get("flow_id"),
|
|
{
|
|
CONF_HOST: "velbus",
|
|
CONF_PORT: 6000,
|
|
**inputParams,
|
|
},
|
|
)
|
|
assert result
|
|
assert result.get("type") is FlowResultType.CREATE_ENTRY
|
|
assert result.get("title") == "Velbus Network"
|
|
data = result.get("data")
|
|
assert data
|
|
assert data[CONF_PORT] == expected
|
|
|
|
|
|
@pytest.mark.usefixtures("controller")
|
|
@patch("serial.tools.list_ports.comports", MagicMock(return_value=[com_port()]))
|
|
async def test_user_usb_succes(hass: HomeAssistant) -> None:
|
|
"""Test user usb step."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": SOURCE_USER}
|
|
)
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result.get("flow_id"),
|
|
{"next_step_id": "usbselect"},
|
|
)
|
|
assert result["type"] is FlowResultType.FORM
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_PORT: USB_DEV,
|
|
},
|
|
)
|
|
assert result
|
|
assert result.get("type") is FlowResultType.CREATE_ENTRY
|
|
assert result.get("title") == "Velbus USB"
|
|
data = result.get("data")
|
|
assert data
|
|
assert data[CONF_PORT] == PORT_SERIAL
|
|
|
|
|
|
@pytest.mark.usefixtures("controller")
|
|
async def test_network_abort_if_already_setup(hass: HomeAssistant) -> None:
|
|
"""Test we abort if Velbus is already setup."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={CONF_PORT: "127.0.0.1:3788"},
|
|
)
|
|
entry.add_to_hass(hass)
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": SOURCE_USER}
|
|
)
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result.get("flow_id"),
|
|
{"next_step_id": "network"},
|
|
)
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_TLS: False,
|
|
CONF_HOST: "127.0.0.1",
|
|
CONF_PORT: 3788,
|
|
CONF_PASSWORD: "",
|
|
},
|
|
)
|
|
assert result
|
|
assert result.get("type") is FlowResultType.ABORT
|
|
assert result.get("reason") == "already_configured"
|
|
|
|
|
|
@pytest.mark.usefixtures("controller")
|
|
@patch("serial.tools.list_ports.comports", MagicMock(return_value=[com_port()]))
|
|
async def test_flow_usb(hass: HomeAssistant) -> None:
|
|
"""Test usb discovery flow."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN,
|
|
context={CONF_SOURCE: SOURCE_USB},
|
|
data=DISCOVERY_INFO,
|
|
)
|
|
assert result
|
|
assert result.get("type") is FlowResultType.FORM
|
|
assert result.get("step_id") == "discovery_confirm"
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
user_input={},
|
|
)
|
|
assert result
|
|
assert result["result"].unique_id == "1234"
|
|
assert result.get("type") is FlowResultType.CREATE_ENTRY
|
|
|
|
|
|
@pytest.mark.usefixtures("controller")
|
|
@patch("serial.tools.list_ports.comports", MagicMock(return_value=[com_port()]))
|
|
async def test_flow_usb_if_already_setup(hass: HomeAssistant) -> None:
|
|
"""Test we abort if Velbus USB discovbery aborts in case it is already setup."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={CONF_PORT: PORT_SERIAL},
|
|
)
|
|
entry.add_to_hass(hass)
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": SOURCE_USER}
|
|
)
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result.get("flow_id"),
|
|
{"next_step_id": "usbselect"},
|
|
)
|
|
assert result
|
|
assert result["type"] is FlowResultType.FORM
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_PORT: USB_DEV,
|
|
},
|
|
)
|
|
assert result
|
|
assert result.get("type") is FlowResultType.ABORT
|
|
assert result.get("reason") == "already_configured"
|
|
|
|
|
|
@pytest.mark.usefixtures("controller_connection_failed")
|
|
@patch("serial.tools.list_ports.comports", MagicMock(return_value=[com_port()]))
|
|
async def test_flow_usb_failed(hass: HomeAssistant) -> None:
|
|
"""Test usb discovery flow with a failed velbus test."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN,
|
|
context={CONF_SOURCE: SOURCE_USB},
|
|
data=DISCOVERY_INFO,
|
|
)
|
|
assert result
|
|
assert result.get("type") is FlowResultType.ABORT
|
|
assert result.get("reason") == "cannot_connect"
|