core/tests/components/acaia/test_config_flow.py

243 lines
6.8 KiB
Python

"""Test the acaia config flow."""
from collections.abc import Generator
from unittest.mock import AsyncMock, patch
from aioacaia.exceptions import AcaiaDeviceNotFound, AcaiaError, AcaiaUnknownDevice
import pytest
from homeassistant.components.acaia.const import CONF_IS_NEW_STYLE_SCALE, DOMAIN
from homeassistant.config_entries import SOURCE_BLUETOOTH, SOURCE_USER
from homeassistant.const import CONF_ADDRESS
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers.service_info.bluetooth import BluetoothServiceInfo
from tests.common import MockConfigEntry
service_info = BluetoothServiceInfo(
name="LUNAR-DDEEFF",
address="aa:bb:cc:dd:ee:ff",
rssi=-63,
manufacturer_data={},
service_data={},
service_uuids=[],
source="local",
)
@pytest.fixture
def mock_discovered_service_info() -> Generator[AsyncMock]:
"""Override getting Bluetooth service info."""
with patch(
"homeassistant.components.acaia.config_flow.async_discovered_service_info",
return_value=[service_info],
) as mock_discovered_service_info:
yield mock_discovered_service_info
async def test_form(
hass: HomeAssistant,
mock_setup_entry: AsyncMock,
mock_verify: AsyncMock,
mock_discovered_service_info: AsyncMock,
) -> None:
"""Test we get the form."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
user_input = {
CONF_ADDRESS: "aa:bb:cc:dd:ee:ff",
}
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=user_input,
)
assert result2["type"] is FlowResultType.CREATE_ENTRY
assert result2["title"] == "LUNAR-DDEEFF"
assert result2["data"] == {
**user_input,
CONF_IS_NEW_STYLE_SCALE: True,
}
async def test_bluetooth_discovery(
hass: HomeAssistant,
mock_setup_entry: AsyncMock,
mock_verify: AsyncMock,
) -> None:
"""Test we can discover a device."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_BLUETOOTH}, data=service_info
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "bluetooth_confirm"
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={},
)
assert result2["type"] is FlowResultType.CREATE_ENTRY
assert result2["title"] == service_info.name
assert result2["data"] == {
CONF_ADDRESS: service_info.address,
CONF_IS_NEW_STYLE_SCALE: True,
}
@pytest.mark.parametrize(
("exception", "error"),
[
(AcaiaDeviceNotFound("Error"), "device_not_found"),
(AcaiaError, "unknown"),
(AcaiaUnknownDevice, "unsupported_device"),
],
)
async def test_bluetooth_discovery_errors(
hass: HomeAssistant,
mock_verify: AsyncMock,
exception: Exception,
error: str,
) -> None:
"""Test abortions of Bluetooth discovery."""
mock_verify.side_effect = exception
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_BLUETOOTH}, data=service_info
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == error
async def test_already_configured(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_verify: AsyncMock,
mock_discovered_service_info: AsyncMock,
) -> None:
"""Ensure we can't add the same device twice."""
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
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_ADDRESS: "aa:bb:cc:dd:ee:ff",
},
)
await hass.async_block_till_done()
assert result2["type"] is FlowResultType.ABORT
assert result2["reason"] == "already_configured"
async def test_already_configured_bluetooth_discovery(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
"""Ensure configure device is not discovered again."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_BLUETOOTH}, data=service_info
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
@pytest.mark.parametrize(
("exception", "error"),
[
(AcaiaDeviceNotFound("Error"), "device_not_found"),
(AcaiaError, "unknown"),
],
)
async def test_recoverable_config_flow_errors(
hass: HomeAssistant,
mock_setup_entry: AsyncMock,
mock_verify: AsyncMock,
mock_discovered_service_info: AsyncMock,
exception: Exception,
error: str,
) -> None:
"""Test recoverable errors."""
mock_verify.side_effect = exception
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_ADDRESS: "aa:bb:cc:dd:ee:ff",
},
)
assert result2["type"] is FlowResultType.FORM
assert result2["errors"] == {"base": error}
# recover
mock_verify.side_effect = None
result3 = await hass.config_entries.flow.async_configure(
result2["flow_id"],
{
CONF_ADDRESS: "aa:bb:cc:dd:ee:ff",
},
)
assert result3["type"] is FlowResultType.CREATE_ENTRY
async def test_unsupported_device(
hass: HomeAssistant,
mock_setup_entry: AsyncMock,
mock_verify: AsyncMock,
mock_discovered_service_info: AsyncMock,
) -> None:
"""Test flow aborts on unsupported device."""
mock_verify.side_effect = AcaiaUnknownDevice
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_ADDRESS: "aa:bb:cc:dd:ee:ff",
},
)
assert result2["type"] is FlowResultType.ABORT
assert result2["reason"] == "unsupported_device"
async def test_no_bluetooth_devices(
hass: HomeAssistant,
mock_setup_entry: AsyncMock,
mock_discovered_service_info: AsyncMock,
) -> None:
"""Test flow aborts on unsupported device."""
mock_discovered_service_info.return_value = []
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "no_devices_found"