366 lines
12 KiB
Python
366 lines
12 KiB
Python
"""Test the SenseME config flow."""
|
|
from unittest.mock import patch
|
|
|
|
from homeassistant import config_entries
|
|
from homeassistant.components import dhcp
|
|
from homeassistant.components.senseme.const import DOMAIN
|
|
from homeassistant.const import CONF_HOST, CONF_ID
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.data_entry_flow import (
|
|
RESULT_TYPE_ABORT,
|
|
RESULT_TYPE_CREATE_ENTRY,
|
|
RESULT_TYPE_FORM,
|
|
)
|
|
|
|
from . import (
|
|
MOCK_ADDRESS,
|
|
MOCK_DEVICE,
|
|
MOCK_DEVICE2,
|
|
MOCK_DEVICE_ALTERNATE_IP,
|
|
MOCK_DEVICE_NO_UUID,
|
|
MOCK_MAC,
|
|
MOCK_UUID,
|
|
_patch_discovery,
|
|
)
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
DHCP_DISCOVERY = dhcp.DhcpServiceInfo(
|
|
hostname="any",
|
|
ip=MOCK_ADDRESS,
|
|
macaddress=MOCK_MAC,
|
|
)
|
|
|
|
|
|
async def test_form_user(hass: HomeAssistant) -> None:
|
|
"""Test we get the form as a user."""
|
|
|
|
with _patch_discovery(), patch(
|
|
"homeassistant.components.senseme.async_setup_entry",
|
|
return_value=True,
|
|
) as mock_setup_entry:
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
assert result["type"] == RESULT_TYPE_FORM
|
|
assert not result["errors"]
|
|
|
|
result2 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
"device": MOCK_UUID,
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result2["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
assert result2["title"] == "Haiku Fan"
|
|
assert result2["data"] == {
|
|
"info": MOCK_DEVICE.get_device_info,
|
|
}
|
|
assert len(mock_setup_entry.mock_calls) == 1
|
|
|
|
|
|
async def test_form_user_manual_entry(hass: HomeAssistant) -> None:
|
|
"""Test we get the form as a user with a discovery but user chooses manual."""
|
|
|
|
with _patch_discovery():
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
assert result["type"] == RESULT_TYPE_FORM
|
|
assert not result["errors"]
|
|
|
|
result2 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
"device": None,
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result2["type"] == RESULT_TYPE_FORM
|
|
assert result2["step_id"] == "manual"
|
|
|
|
with patch(
|
|
"homeassistant.components.senseme.config_flow.async_get_device_by_ip_address",
|
|
return_value=MOCK_DEVICE,
|
|
), patch(
|
|
"homeassistant.components.senseme.async_setup_entry",
|
|
return_value=True,
|
|
) as mock_setup_entry:
|
|
result3 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_HOST: MOCK_ADDRESS,
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result3["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
assert result3["title"] == "Haiku Fan"
|
|
assert result3["data"] == {
|
|
"info": MOCK_DEVICE.get_device_info,
|
|
}
|
|
assert len(mock_setup_entry.mock_calls) == 1
|
|
|
|
|
|
async def test_form_user_no_discovery(hass: HomeAssistant) -> None:
|
|
"""Test we get the form as a user with no discovery."""
|
|
|
|
with _patch_discovery(no_device=True), patch(
|
|
"homeassistant.components.senseme.config_flow.async_get_device_by_ip_address",
|
|
return_value=MOCK_DEVICE,
|
|
), patch(
|
|
"homeassistant.components.senseme.async_setup_entry",
|
|
return_value=True,
|
|
) as mock_setup_entry:
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
assert result["type"] == RESULT_TYPE_FORM
|
|
assert not result["errors"]
|
|
|
|
result2 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_HOST: "not a valid address",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result2["type"] == RESULT_TYPE_FORM
|
|
assert result2["step_id"] == "manual"
|
|
assert result2["errors"] == {CONF_HOST: "invalid_host"}
|
|
|
|
result3 = await hass.config_entries.flow.async_configure(
|
|
result2["flow_id"],
|
|
{
|
|
CONF_HOST: MOCK_ADDRESS,
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result3["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
assert result3["title"] == "Haiku Fan"
|
|
assert result3["data"] == {
|
|
"info": MOCK_DEVICE.get_device_info,
|
|
}
|
|
assert len(mock_setup_entry.mock_calls) == 1
|
|
|
|
|
|
async def test_form_user_manual_entry_cannot_connect(hass: HomeAssistant) -> None:
|
|
"""Test we get the form as a user."""
|
|
|
|
with _patch_discovery():
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
assert result["type"] == RESULT_TYPE_FORM
|
|
assert not result["errors"]
|
|
|
|
result2 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
"device": None,
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result2["type"] == RESULT_TYPE_FORM
|
|
assert result2["step_id"] == "manual"
|
|
|
|
with patch(
|
|
"homeassistant.components.senseme.config_flow.async_get_device_by_ip_address",
|
|
return_value=None,
|
|
):
|
|
result3 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_HOST: MOCK_ADDRESS,
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result3["type"] == RESULT_TYPE_FORM
|
|
assert result3["step_id"] == "manual"
|
|
assert result3["errors"] == {CONF_HOST: "cannot_connect"}
|
|
|
|
|
|
async def test_discovery(hass: HomeAssistant) -> None:
|
|
"""Test we can setup a discovered device."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={
|
|
"info": MOCK_DEVICE2.get_device_info,
|
|
},
|
|
unique_id=MOCK_DEVICE2.uuid,
|
|
)
|
|
entry.add_to_hass(hass)
|
|
|
|
with _patch_discovery(), patch(
|
|
"homeassistant.components.senseme.async_get_device_by_device_info",
|
|
return_value=(True, MOCK_DEVICE2),
|
|
):
|
|
await hass.config_entries.async_setup(entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
with _patch_discovery(), patch(
|
|
"homeassistant.components.senseme.async_setup_entry",
|
|
return_value=True,
|
|
) as mock_setup_entry:
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN,
|
|
context={"source": config_entries.SOURCE_DISCOVERY},
|
|
data={CONF_ID: MOCK_UUID},
|
|
)
|
|
assert result["type"] == RESULT_TYPE_FORM
|
|
assert not result["errors"]
|
|
|
|
result2 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
"device": MOCK_UUID,
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result2["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
assert result2["title"] == "Haiku Fan"
|
|
assert result2["data"] == {
|
|
"info": MOCK_DEVICE.get_device_info,
|
|
}
|
|
assert len(mock_setup_entry.mock_calls) == 1
|
|
|
|
|
|
async def test_discovery_existing_device_no_ip_change(hass: HomeAssistant) -> None:
|
|
"""Test we can setup a discovered device."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={
|
|
"info": MOCK_DEVICE.get_device_info,
|
|
},
|
|
unique_id=MOCK_DEVICE.uuid,
|
|
)
|
|
entry.add_to_hass(hass)
|
|
|
|
with _patch_discovery(), patch(
|
|
"homeassistant.components.senseme.async_get_device_by_device_info",
|
|
return_value=(True, MOCK_DEVICE),
|
|
):
|
|
await hass.config_entries.async_setup(entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
with _patch_discovery():
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN,
|
|
context={"source": config_entries.SOURCE_DISCOVERY},
|
|
data={CONF_ID: MOCK_UUID},
|
|
)
|
|
assert result["type"] == RESULT_TYPE_ABORT
|
|
assert result["reason"] == "already_configured"
|
|
|
|
|
|
async def test_discovery_existing_device_ip_change(hass: HomeAssistant) -> None:
|
|
"""Test a config entry ips get updated from discovery."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={
|
|
"info": MOCK_DEVICE.get_device_info,
|
|
},
|
|
unique_id=MOCK_DEVICE.uuid,
|
|
)
|
|
entry.add_to_hass(hass)
|
|
|
|
with _patch_discovery(device=MOCK_DEVICE_ALTERNATE_IP), patch(
|
|
"homeassistant.components.senseme.async_get_device_by_device_info",
|
|
return_value=(True, MOCK_DEVICE),
|
|
):
|
|
await hass.config_entries.async_setup(entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN,
|
|
context={"source": config_entries.SOURCE_DISCOVERY},
|
|
data={CONF_ID: MOCK_UUID},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] == RESULT_TYPE_ABORT
|
|
assert result["reason"] == "already_configured"
|
|
assert entry.data["info"]["address"] == "127.0.0.8"
|
|
|
|
|
|
async def test_dhcp_discovery_existing_config_entry(hass: HomeAssistant) -> None:
|
|
"""Test dhcp discovery is aborted if there is an existing config entry."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={
|
|
"info": MOCK_DEVICE2.get_device_info,
|
|
},
|
|
unique_id=MOCK_DEVICE2.uuid,
|
|
)
|
|
entry.add_to_hass(hass)
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_DHCP}, data=DHCP_DISCOVERY
|
|
)
|
|
assert result["type"] == RESULT_TYPE_ABORT
|
|
assert result["reason"] == "already_configured"
|
|
|
|
|
|
async def test_dhcp_discovery(hass: HomeAssistant) -> None:
|
|
"""Test we can setup a dhcp discovered device."""
|
|
with _patch_discovery(), patch(
|
|
"homeassistant.components.senseme.config_flow.async_get_device_by_ip_address",
|
|
return_value=MOCK_DEVICE,
|
|
), patch(
|
|
"homeassistant.components.senseme.async_setup_entry",
|
|
return_value=True,
|
|
) as mock_setup_entry:
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_DHCP}, data=DHCP_DISCOVERY
|
|
)
|
|
assert result["type"] == RESULT_TYPE_FORM
|
|
assert not result["errors"]
|
|
|
|
result2 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
"device": MOCK_UUID,
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result2["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
assert result2["title"] == "Haiku Fan"
|
|
assert result2["data"] == {
|
|
"info": MOCK_DEVICE.get_device_info,
|
|
}
|
|
assert len(mock_setup_entry.mock_calls) == 1
|
|
|
|
|
|
async def test_dhcp_discovery_cannot_connect(hass: HomeAssistant) -> None:
|
|
"""Test we abort if we cannot cannot to a dhcp discovered device."""
|
|
with _patch_discovery(), patch(
|
|
"homeassistant.components.senseme.config_flow.async_get_device_by_ip_address",
|
|
return_value=None,
|
|
):
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_DHCP}, data=DHCP_DISCOVERY
|
|
)
|
|
assert result["type"] == RESULT_TYPE_ABORT
|
|
assert result["reason"] == "cannot_connect"
|
|
|
|
|
|
async def test_dhcp_discovery_cannot_connect_no_uuid(hass: HomeAssistant) -> None:
|
|
"""Test we abort if the discovered device has no uuid."""
|
|
with _patch_discovery(), patch(
|
|
"homeassistant.components.senseme.config_flow.async_get_device_by_ip_address",
|
|
return_value=MOCK_DEVICE_NO_UUID,
|
|
):
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_DHCP}, data=DHCP_DISCOVERY
|
|
)
|
|
assert result["type"] == RESULT_TYPE_ABORT
|
|
assert result["reason"] == "cannot_connect"
|