Refactor Vilfo tests (#115020)

* Refactor Vilfo tests

* Patch is_host_valid
This commit is contained in:
Joost Lekkerkerker 2024-04-06 15:48:52 +02:00 committed by GitHub
parent 81d682874f
commit b743a86aa9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 213 additions and 180 deletions

View file

@ -0,0 +1,61 @@
"""Vilfo tests conftest."""
from collections.abc import Generator
from unittest.mock import AsyncMock, patch
import pytest
from homeassistant.components.vilfo import DOMAIN
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
from tests.common import MockConfigEntry
@pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock, None, None]:
"""Override async_setup_entry."""
with patch(
"homeassistant.components.vilfo.async_setup_entry",
return_value=True,
) as mock_setup_entry:
yield mock_setup_entry
@pytest.fixture
def mock_vilfo_client() -> Generator[AsyncMock, None, None]:
"""Mock a Vilfo client."""
with patch(
"homeassistant.components.vilfo.config_flow.VilfoClient",
autospec=True,
) as mock_client:
client = mock_client.return_value
client.get_board_information.return_value = None
client.ping.return_value = None
client.resolve_firmware_version.return_value = "1.1.0"
client.resolve_mac_address.return_value = "FF-00-00-00-00-00"
client.mac = "FF-00-00-00-00-00"
yield client
@pytest.fixture
def mock_is_valid_host() -> Generator[AsyncMock, None, None]:
"""Mock is_valid_host."""
with patch(
"homeassistant.components.vilfo.config_flow.is_host_valid",
return_value=True,
) as mock_is_valid_host:
yield mock_is_valid_host
@pytest.fixture
def mock_config_entry() -> MockConfigEntry:
"""Mock a config entry."""
return MockConfigEntry(
domain=DOMAIN,
title="testadmin.vilfo.com",
unique_id="FF-00-00-00-00-00",
data={
CONF_HOST: "testadmin.vilfo.com",
CONF_ACCESS_TOKEN: "test-token",
},
)

View file

@ -1,219 +1,191 @@
"""Test the Vilfo Router config flow.""" """Test the Vilfo Router config flow."""
from unittest.mock import Mock, patch from typing import Any
from unittest.mock import AsyncMock
import vilfo import pytest
from vilfo.exceptions import AuthenticationException, VilfoException
from homeassistant import config_entries
from homeassistant.components.vilfo import config_flow
from homeassistant.components.vilfo.const import DOMAIN from homeassistant.components.vilfo.const import DOMAIN
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST, CONF_ID, CONF_MAC from homeassistant.config_entries import SOURCE_USER
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType from homeassistant.data_entry_flow import FlowResultType
from tests.common import MockConfigEntry
async def test_form(hass: HomeAssistant) -> None:
"""Test we get the form."""
mock_mac = "FF-00-00-00-00-00" @pytest.mark.parametrize(
firmware_version = "1.1.0" ("user_input", "expected_unique_id", "mac"),
result = await hass.config_entries.flow.async_init( [
DOMAIN, context={"source": config_entries.SOURCE_USER} (
)
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {}
with (
patch("vilfo.Client.ping", return_value=None),
patch("vilfo.Client.get_board_information", return_value=None),
patch("vilfo.Client.resolve_firmware_version", return_value=firmware_version),
patch("vilfo.Client.resolve_mac_address", return_value=mock_mac),
patch("homeassistant.components.vilfo.async_setup_entry") as mock_setup_entry,
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "testadmin.vilfo.com", CONF_ACCESS_TOKEN: "test-token"}, {CONF_HOST: "testadmin.vilfo.com", CONF_ACCESS_TOKEN: "test-token"},
) "testadmin.vilfo.com",
await hass.async_block_till_done() None,
),
(
{CONF_HOST: "testadmin.vilfo.com", CONF_ACCESS_TOKEN: "test-token"},
"FF-00-00-00-00-00",
"FF-00-00-00-00-00",
),
(
{CONF_HOST: "192.168.0.1", CONF_ACCESS_TOKEN: "test-token"},
"FF-00-00-00-00-00",
"FF-00-00-00-00-00",
),
(
{CONF_HOST: "2001:db8::1428:57ab", CONF_ACCESS_TOKEN: "test-token"},
"FF-00-00-00-00-00",
"FF-00-00-00-00-00",
),
],
)
async def test_full_flow(
hass: HomeAssistant,
mock_vilfo_client: AsyncMock,
mock_setup_entry: AsyncMock,
mock_is_valid_host: AsyncMock,
user_input: dict[str, Any],
expected_unique_id: str,
mac: str | None,
) -> None:
"""Test we can finish a config flow."""
assert result2["type"] is FlowResultType.CREATE_ENTRY mock_vilfo_client.resolve_mac_address.return_value = mac
assert result2["title"] == "testadmin.vilfo.com" mock_vilfo_client.mac = mac
assert result2["data"] == {
"host": "testadmin.vilfo.com", result = await hass.config_entries.flow.async_init(
"access_token": "test-token", DOMAIN, context={"source": SOURCE_USER}
} )
await hass.async_block_till_done()
assert result["type"] is FlowResultType.FORM
assert not result["errors"]
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input,
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == user_input[CONF_HOST]
assert result["data"] == user_input
assert result["result"].unique_id == expected_unique_id
assert len(mock_setup_entry.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1
async def test_form_invalid_auth(hass: HomeAssistant) -> None: async def test_form_invalid_auth(
hass: HomeAssistant,
mock_vilfo_client: AsyncMock,
mock_is_valid_host: AsyncMock,
mock_setup_entry: AsyncMock,
) -> None:
"""Test we handle invalid auth.""" """Test we handle invalid auth."""
mock_vilfo_client.get_board_information.side_effect = AuthenticationException
mock_vilfo_client.resolve_mac_address.return_value = None
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": SOURCE_USER}
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.FORM
assert not result["errors"]
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "testadmin.vilfo.com", CONF_ACCESS_TOKEN: "test-token"},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "invalid_auth"}
mock_vilfo_client.get_board_information.side_effect = None
mock_vilfo_client.resolve_mac_address.return_value = "FF-00-00-00-00-00"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "testadmin.vilfo.com", CONF_ACCESS_TOKEN: "test-token"},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.CREATE_ENTRY
@pytest.mark.parametrize(
("side_effect", "error"),
[(VilfoException, "cannot_connect"), (Exception, "unknown")],
)
async def test_form_exceptions(
hass: HomeAssistant,
mock_vilfo_client: AsyncMock,
mock_is_valid_host: AsyncMock,
mock_setup_entry: AsyncMock,
side_effect: Exception,
error: str,
) -> None:
"""Test we handle exceptions."""
mock_vilfo_client.ping.side_effect = side_effect
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
) )
with ( result = await hass.config_entries.flow.async_configure(
patch("vilfo.Client.ping", return_value=None), result["flow_id"],
patch("vilfo.Client.resolve_mac_address", return_value=None), {CONF_HOST: "testadmin.vilfo.com", CONF_ACCESS_TOKEN: "test-token"},
patch(
"vilfo.Client.get_board_information",
side_effect=vilfo.exceptions.AuthenticationException,
),
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": "testadmin.vilfo.com", "access_token": "test-token"},
)
assert result2["type"] is FlowResultType.FORM
assert result2["errors"] == {"base": "invalid_auth"}
async def test_form_cannot_connect(hass: HomeAssistant) -> None:
"""Test we handle cannot connect error."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
with ( assert result["type"] is FlowResultType.FORM
patch("vilfo.Client.ping", side_effect=vilfo.exceptions.VilfoException), assert result["errors"] == {"base": error}
patch("vilfo.Client.resolve_mac_address"),
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": "testadmin.vilfo.com", "access_token": "test-token"},
)
assert result2["type"] is FlowResultType.FORM mock_vilfo_client.ping.side_effect = None
assert result2["errors"] == {"base": "cannot_connect"}
with ( result = await hass.config_entries.flow.async_configure(
patch("vilfo.Client.ping", side_effect=vilfo.exceptions.VilfoException), result["flow_id"],
patch("vilfo.Client.resolve_mac_address"), {CONF_HOST: "testadmin.vilfo.com", CONF_ACCESS_TOKEN: "test-token"},
): )
result3 = await hass.config_entries.flow.async_configure( await hass.async_block_till_done()
result["flow_id"],
{"host": "testadmin.vilfo.com", "access_token": "test-token"},
)
assert result3["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.CREATE_ENTRY
assert result3["errors"] == {"base": "cannot_connect"}
async def test_form_wrong_host(hass: HomeAssistant) -> None: async def test_form_wrong_host(
hass: HomeAssistant,
mock_is_valid_host: AsyncMock,
) -> None:
"""Test we handle wrong host errors.""" """Test we handle wrong host errors."""
mock_is_valid_host.return_value = False
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
context={"source": config_entries.SOURCE_USER}, context={"source": SOURCE_USER},
data={"host": "this is an invalid hostname", "access_token": "test-token"}, data={
CONF_HOST: "this is an invalid hostname",
CONF_ACCESS_TOKEN: "test-token",
},
) )
assert result["errors"] == {"host": "wrong_host"} assert result["errors"] == {"host": "wrong_host"}
async def test_form_already_configured(hass: HomeAssistant) -> None: async def test_form_already_configured(
hass: HomeAssistant,
mock_vilfo_client: AsyncMock,
mock_setup_entry: AsyncMock,
mock_config_entry: MockConfigEntry,
mock_is_valid_host: AsyncMock,
) -> None:
"""Test that we handle already configured exceptions appropriately.""" """Test that we handle already configured exceptions appropriately."""
first_flow_result1 = await hass.config_entries.flow.async_init( mock_config_entry.add_to_hass(hass)
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
firmware_version = "1.1.0"
with (
patch("vilfo.Client.ping", return_value=None),
patch(
"vilfo.Client.get_board_information",
return_value=None,
),
patch("vilfo.Client.resolve_firmware_version", return_value=firmware_version),
patch("vilfo.Client.resolve_mac_address", return_value=None),
):
first_flow_result2 = await hass.config_entries.flow.async_configure(
first_flow_result1["flow_id"],
{CONF_HOST: "testadmin.vilfo.com", CONF_ACCESS_TOKEN: "test-token"},
)
second_flow_result1 = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with (
patch("vilfo.Client.ping", return_value=None),
patch(
"vilfo.Client.get_board_information",
return_value=None,
),
patch("vilfo.Client.resolve_firmware_version", return_value=firmware_version),
patch("vilfo.Client.resolve_mac_address", return_value=None),
):
second_flow_result2 = await hass.config_entries.flow.async_configure(
second_flow_result1["flow_id"],
{CONF_HOST: "testadmin.vilfo.com", CONF_ACCESS_TOKEN: "test-token"},
)
assert first_flow_result2["type"] is FlowResultType.CREATE_ENTRY
assert second_flow_result2["type"] is FlowResultType.ABORT
assert second_flow_result2["reason"] == "already_configured"
async def test_form_unexpected_exception(hass: HomeAssistant) -> None:
"""Test that we handle unexpected exceptions."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": SOURCE_USER}
) )
await hass.async_block_till_done()
with patch( result = await hass.config_entries.flow.async_configure(
"homeassistant.components.vilfo.config_flow.VilfoClient", result["flow_id"],
) as mock_client: {CONF_HOST: "testadmin.vilfo.com", CONF_ACCESS_TOKEN: "test-token"},
mock_client.return_value.ping = Mock(side_effect=Exception) )
result2 = await hass.config_entries.flow.async_configure( await hass.async_block_till_done()
result["flow_id"], assert result["type"] is FlowResultType.ABORT
{"host": "testadmin.vilfo.com", "access_token": "test-token"}, assert result["reason"] == "already_configured"
)
assert result2["errors"] == {"base": "unknown"}
async def test_validate_input_returns_data(hass: HomeAssistant) -> None:
"""Test we handle the MAC address being resolved or not."""
mock_data = {"host": "testadmin.vilfo.com", "access_token": "test-token"}
mock_data_with_ip = {"host": "192.168.0.1", "access_token": "test-token"}
mock_data_with_ipv6 = {"host": "2001:db8::1428:57ab", "access_token": "test-token"}
mock_mac = "FF-00-00-00-00-00"
firmware_version = "1.1.0"
with (
patch("vilfo.Client.ping", return_value=None),
patch("vilfo.Client.get_board_information", return_value=None),
patch("vilfo.Client.resolve_firmware_version", return_value=firmware_version),
patch("vilfo.Client.resolve_mac_address", return_value=None),
):
result = await config_flow.validate_input(hass, data=mock_data)
assert result["title"] == mock_data["host"]
assert result[CONF_HOST] == mock_data["host"]
assert result[CONF_MAC] is None
assert result[CONF_ID] == mock_data["host"]
with (
patch("vilfo.Client.ping", return_value=None),
patch("vilfo.Client.get_board_information", return_value=None),
patch("vilfo.Client.resolve_firmware_version", return_value=firmware_version),
patch("vilfo.Client.resolve_mac_address", return_value=mock_mac),
):
result2 = await config_flow.validate_input(hass, data=mock_data)
result3 = await config_flow.validate_input(hass, data=mock_data_with_ip)
result4 = await config_flow.validate_input(hass, data=mock_data_with_ipv6)
assert result2["title"] == mock_data["host"]
assert result2[CONF_HOST] == mock_data["host"]
assert result2[CONF_MAC] == mock_mac
assert result2[CONF_ID] == mock_mac
assert result3["title"] == mock_data_with_ip["host"]
assert result3[CONF_HOST] == mock_data_with_ip["host"]
assert result3[CONF_MAC] == mock_mac
assert result3[CONF_ID] == mock_mac
assert result4["title"] == mock_data_with_ipv6["host"]
assert result4[CONF_HOST] == mock_data_with_ipv6["host"]
assert result4[CONF_MAC] == mock_mac
assert result4[CONF_ID] == mock_mac