1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-25 05:26:47 +00:00
Files
core/tests/components/vivotek/test_config_flow.py
2025-12-02 19:47:22 +01:00

253 lines
7.3 KiB
Python

"""Tests for the Vivotek config flow."""
from unittest.mock import AsyncMock
from libpyvivotek.vivotek import VivotekCameraError
import pytest
from homeassistant.components.vivotek.camera import DEFAULT_FRAMERATE, DEFAULT_NAME
from homeassistant.components.vivotek.const import (
CONF_FRAMERATE,
CONF_SECURITY_LEVEL,
CONF_STREAM_PATH,
DOMAIN,
)
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER
from homeassistant.const import (
CONF_AUTHENTICATION,
CONF_IP_ADDRESS,
CONF_PASSWORD,
CONF_PORT,
CONF_SSL,
CONF_USERNAME,
CONF_VERIFY_SSL,
HTTP_BASIC_AUTHENTICATION,
)
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from tests.common import MockConfigEntry
USER_DATA = {
CONF_IP_ADDRESS: "1.2.3.4",
CONF_PORT: 80,
CONF_USERNAME: "admin",
CONF_PASSWORD: "pass1234",
CONF_AUTHENTICATION: HTTP_BASIC_AUTHENTICATION,
CONF_SSL: False,
CONF_VERIFY_SSL: True,
CONF_SECURITY_LEVEL: "admin",
CONF_STREAM_PATH: "/live.sdp",
}
IMPORT_DATA = {
CONF_IP_ADDRESS: "1.2.3.4",
CONF_USERNAME: "admin",
CONF_PASSWORD: "pass1234",
CONF_AUTHENTICATION: HTTP_BASIC_AUTHENTICATION,
CONF_SSL: False,
CONF_VERIFY_SSL: True,
CONF_SECURITY_LEVEL: "admin",
CONF_STREAM_PATH: "/live.sdp",
CONF_FRAMERATE: DEFAULT_FRAMERATE,
}
async def test_full_flow(
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_vivotek_camera: AsyncMock
) -> None:
"""Test full user initiated flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {}
result = await hass.config_entries.flow.async_configure(
result["flow_id"], USER_DATA
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == DEFAULT_NAME
assert result["data"] == USER_DATA
assert result["options"] == {CONF_FRAMERATE: DEFAULT_FRAMERATE}
assert result["result"].unique_id == "11:22:33:44:55:66"
@pytest.mark.parametrize(
("exception", "error"),
[
(VivotekCameraError, "cannot_connect"),
(Exception, "unknown"),
],
)
async def test_user_exceptions(
hass: HomeAssistant,
mock_setup_entry: AsyncMock,
mock_vivotek_camera: AsyncMock,
exception: Exception,
error: str,
) -> None:
"""Test user initiated flow with exceptions."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {}
mock_vivotek_camera.get_mac.side_effect = exception
result = await hass.config_entries.flow.async_configure(
result["flow_id"], USER_DATA
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {"base": error}
mock_vivotek_camera.get_mac.side_effect = None
result = await hass.config_entries.flow.async_configure(
result["flow_id"], USER_DATA
)
assert result["type"] is FlowResultType.CREATE_ENTRY
async def test_duplicate_entry(
hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Test flow abort on duplicate entry."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {}
result = await hass.config_entries.flow.async_configure(
result["flow_id"], USER_DATA
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_duplicate_entry_mac(
hass: HomeAssistant,
mock_vivotek_camera: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test flow abort on duplicate MAC address."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {}
result = await hass.config_entries.flow.async_configure(
result["flow_id"], {**USER_DATA, CONF_IP_ADDRESS: "1.1.1.1"}
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_import_flow(
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_vivotek_camera: AsyncMock
) -> None:
"""Test import initiated flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=IMPORT_DATA
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == DEFAULT_NAME
assert result["data"] == USER_DATA
assert result["options"] == {CONF_FRAMERATE: DEFAULT_FRAMERATE}
assert result["result"].unique_id == "11:22:33:44:55:66"
@pytest.mark.parametrize(
("exception", "reason"),
[
(VivotekCameraError, "cannot_connect"),
(Exception, "unknown"),
],
)
async def test_import_flow_exceptions(
hass: HomeAssistant,
mock_setup_entry: AsyncMock,
mock_vivotek_camera: AsyncMock,
exception: Exception,
reason: str,
) -> None:
"""Test import initiated flow with exceptions."""
mock_vivotek_camera.get_mac.side_effect = exception
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=IMPORT_DATA
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == reason
async def test_import_flow_duplicate(
hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Test import initiated flow."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=IMPORT_DATA
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_import_flow_duplicate_mac(
hass: HomeAssistant,
mock_vivotek_camera: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test import initiated flow."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data={**IMPORT_DATA, CONF_IP_ADDRESS: "1.1.1.1"},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_options_flow(
hass: HomeAssistant,
mock_vivotek_camera: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test options flow."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.options.async_init(mock_config_entry.entry_id)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "init"
result = await hass.config_entries.options.async_configure(
result["flow_id"],
{
CONF_FRAMERATE: 15,
},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert mock_config_entry.options[CONF_FRAMERATE] == 15