2018-06-14 15:17:54 -04:00
|
|
|
"""Tests for the Config Entry Flow helper."""
|
2023-03-16 11:10:56 +01:00
|
|
|
from collections.abc import Generator
|
2022-01-26 19:57:45 +01:00
|
|
|
from unittest.mock import Mock, PropertyMock, patch
|
2021-01-01 22:31:56 +01:00
|
|
|
|
2018-06-14 15:17:54 -04:00
|
|
|
import pytest
|
|
|
|
|
2019-04-14 19:07:05 -07:00
|
|
|
from homeassistant import config_entries, data_entry_flow, setup
|
2020-05-08 17:52:32 +02:00
|
|
|
from homeassistant.config import async_process_ha_core_config
|
2023-02-20 11:42:56 +01:00
|
|
|
from homeassistant.core import HomeAssistant
|
2018-06-14 15:17:54 -04:00
|
|
|
from homeassistant.helpers import config_entry_flow
|
2019-12-09 16:52:24 +01:00
|
|
|
|
2023-11-16 16:55:08 +01:00
|
|
|
from tests.common import MockConfigEntry, MockModule, mock_integration, mock_platform
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
2023-03-16 11:10:56 +01:00
|
|
|
def discovery_flow_conf(hass: HomeAssistant) -> Generator[dict[str, bool], None, None]:
|
2018-06-14 15:17:54 -04:00
|
|
|
"""Register a handler."""
|
2019-07-31 12:25:30 -07:00
|
|
|
handler_conf = {"discovered": False}
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def has_discovered_devices(hass: HomeAssistant) -> bool:
|
2018-06-14 15:17:54 -04:00
|
|
|
"""Mock if we have discovered devices."""
|
2019-07-31 12:25:30 -07:00
|
|
|
return handler_conf["discovered"]
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
with patch.dict(config_entries.HANDLERS):
|
|
|
|
config_entry_flow.register_discovery_flow(
|
2021-04-29 23:12:58 +02:00
|
|
|
"test", "Test", has_discovered_devices
|
2019-07-31 12:25:30 -07:00
|
|
|
)
|
2018-06-14 15:17:54 -04:00
|
|
|
yield handler_conf
|
|
|
|
|
|
|
|
|
2018-10-23 02:14:46 -07:00
|
|
|
@pytest.fixture
|
2023-03-16 11:10:56 +01:00
|
|
|
def webhook_flow_conf(hass: HomeAssistant) -> Generator[None, None, None]:
|
2018-10-23 02:14:46 -07:00
|
|
|
"""Register a handler."""
|
|
|
|
with patch.dict(config_entries.HANDLERS):
|
2019-07-31 12:25:30 -07:00
|
|
|
config_entry_flow.register_webhook_flow("test_single", "Test Single", {}, False)
|
2018-10-23 02:14:46 -07:00
|
|
|
config_entry_flow.register_webhook_flow(
|
2019-07-31 12:25:30 -07:00
|
|
|
"test_multiple", "Test Multiple", {}, True
|
|
|
|
)
|
2023-03-16 11:10:56 +01:00
|
|
|
yield
|
2018-10-23 02:14:46 -07:00
|
|
|
|
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def test_single_entry_allowed(
|
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
|
|
|
|
) -> None:
|
2018-06-14 15:17:54 -04:00
|
|
|
"""Test only a single entry is allowed."""
|
2019-07-31 12:25:30 -07:00
|
|
|
flow = config_entries.HANDLERS["test"]()
|
2018-06-14 15:17:54 -04:00
|
|
|
flow.hass = hass
|
2020-04-26 23:35:04 -07:00
|
|
|
flow.context = {}
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2019-07-31 12:25:30 -07:00
|
|
|
MockConfigEntry(domain="test").add_to_hass(hass)
|
2018-08-09 04:24:14 -07:00
|
|
|
result = await flow.async_step_user()
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
2019-07-31 12:25:30 -07:00
|
|
|
assert result["reason"] == "single_instance_allowed"
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def test_user_no_devices_found(
|
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
|
|
|
|
) -> None:
|
2018-06-14 15:17:54 -04:00
|
|
|
"""Test if no devices found."""
|
2019-07-31 12:25:30 -07:00
|
|
|
flow = config_entries.HANDLERS["test"]()
|
2018-06-14 15:17:54 -04:00
|
|
|
flow.hass = hass
|
2019-07-31 12:25:30 -07:00
|
|
|
flow.context = {"source": config_entries.SOURCE_USER}
|
2018-09-21 16:34:37 +02:00
|
|
|
result = await flow.async_step_confirm(user_input={})
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
2019-07-31 12:25:30 -07:00
|
|
|
assert result["reason"] == "no_devices_found"
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def test_user_has_confirmation(
|
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
|
|
|
|
) -> None:
|
2020-06-13 06:43:13 +02:00
|
|
|
"""Test user requires confirmation to setup."""
|
2019-07-31 12:25:30 -07:00
|
|
|
discovery_flow_conf["discovered"] = True
|
2023-11-16 16:55:08 +01:00
|
|
|
mock_platform(hass, "test.config_flow", None)
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2020-06-13 06:43:13 +02:00
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
|
|
"test", context={"source": config_entries.SOURCE_USER}, data={}
|
|
|
|
)
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
2020-06-13 06:43:13 +02:00
|
|
|
assert result["step_id"] == "confirm"
|
|
|
|
|
2021-03-08 10:54:51 -08:00
|
|
|
progress = hass.config_entries.flow.async_progress()
|
|
|
|
assert len(progress) == 1
|
|
|
|
assert progress[0]["flow_id"] == result["flow_id"]
|
|
|
|
assert progress[0]["context"] == {
|
|
|
|
"confirm_only": True,
|
|
|
|
"source": config_entries.SOURCE_USER,
|
|
|
|
"unique_id": "test",
|
|
|
|
}
|
|
|
|
|
2020-06-13 06:43:13 +02:00
|
|
|
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
|
2021-04-25 12:27:40 +03:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"source",
|
|
|
|
[
|
2022-07-08 18:55:31 -05:00
|
|
|
config_entries.SOURCE_BLUETOOTH,
|
2021-04-25 12:27:40 +03:00
|
|
|
config_entries.SOURCE_DISCOVERY,
|
|
|
|
config_entries.SOURCE_MQTT,
|
|
|
|
config_entries.SOURCE_SSDP,
|
|
|
|
config_entries.SOURCE_ZEROCONF,
|
|
|
|
config_entries.SOURCE_DHCP,
|
|
|
|
],
|
|
|
|
)
|
2023-02-20 11:42:56 +01:00
|
|
|
async def test_discovery_single_instance(
|
2023-03-16 11:10:56 +01:00
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool], source: str
|
2023-02-20 11:42:56 +01:00
|
|
|
) -> None:
|
2019-05-30 14:08:05 -07:00
|
|
|
"""Test we not allow duplicates."""
|
2019-07-31 12:25:30 -07:00
|
|
|
flow = config_entries.HANDLERS["test"]()
|
2018-06-14 15:17:54 -04:00
|
|
|
flow.hass = hass
|
2019-08-16 16:19:00 -07:00
|
|
|
flow.context = {}
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2019-07-31 12:25:30 -07:00
|
|
|
MockConfigEntry(domain="test").add_to_hass(hass)
|
2020-01-03 15:47:06 +02:00
|
|
|
result = await getattr(flow, f"async_step_{source}")({})
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
2019-07-31 12:25:30 -07:00
|
|
|
assert result["reason"] == "single_instance_allowed"
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
|
2021-04-25 12:27:40 +03:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"source",
|
|
|
|
[
|
2022-07-08 18:55:31 -05:00
|
|
|
config_entries.SOURCE_BLUETOOTH,
|
2021-04-25 12:27:40 +03:00
|
|
|
config_entries.SOURCE_DISCOVERY,
|
|
|
|
config_entries.SOURCE_MQTT,
|
|
|
|
config_entries.SOURCE_SSDP,
|
|
|
|
config_entries.SOURCE_ZEROCONF,
|
|
|
|
config_entries.SOURCE_DHCP,
|
|
|
|
],
|
|
|
|
)
|
2023-02-20 11:42:56 +01:00
|
|
|
async def test_discovery_confirmation(
|
2023-03-16 11:10:56 +01:00
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool], source: str
|
2023-02-20 11:42:56 +01:00
|
|
|
) -> None:
|
2018-06-14 15:17:54 -04:00
|
|
|
"""Test we ask for confirmation via discovery."""
|
2019-07-31 12:25:30 -07:00
|
|
|
flow = config_entries.HANDLERS["test"]()
|
2018-06-14 15:17:54 -04:00
|
|
|
flow.hass = hass
|
2020-04-26 23:35:04 -07:00
|
|
|
flow.context = {"source": source}
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2020-01-03 15:47:06 +02:00
|
|
|
result = await getattr(flow, f"async_step_{source}")({})
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
2019-07-31 12:25:30 -07:00
|
|
|
assert result["step_id"] == "confirm"
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
result = await flow.async_step_confirm({})
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
|
2022-06-22 22:37:49 +02:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"source",
|
|
|
|
[
|
2022-07-08 18:55:31 -05:00
|
|
|
config_entries.SOURCE_BLUETOOTH,
|
2022-06-22 22:37:49 +02:00
|
|
|
config_entries.SOURCE_DISCOVERY,
|
|
|
|
config_entries.SOURCE_MQTT,
|
|
|
|
config_entries.SOURCE_SSDP,
|
|
|
|
config_entries.SOURCE_ZEROCONF,
|
|
|
|
config_entries.SOURCE_DHCP,
|
|
|
|
],
|
|
|
|
)
|
2023-02-20 11:42:56 +01:00
|
|
|
async def test_discovery_during_onboarding(
|
2023-03-16 11:10:56 +01:00
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool], source: str
|
2023-02-20 11:42:56 +01:00
|
|
|
) -> None:
|
2022-06-22 22:37:49 +02:00
|
|
|
"""Test we create config entry via discovery during onboarding."""
|
|
|
|
flow = config_entries.HANDLERS["test"]()
|
|
|
|
flow.hass = hass
|
|
|
|
flow.context = {"source": source}
|
|
|
|
|
|
|
|
with patch(
|
|
|
|
"homeassistant.components.onboarding.async_is_onboarded", return_value=False
|
|
|
|
):
|
|
|
|
result = await getattr(flow, f"async_step_{source}")({})
|
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
2022-06-22 22:37:49 +02:00
|
|
|
|
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def test_multiple_discoveries(
|
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
|
|
|
|
) -> None:
|
2018-06-14 15:17:54 -04:00
|
|
|
"""Test we only create one instance for multiple discoveries."""
|
2023-11-16 16:55:08 +01:00
|
|
|
mock_platform(hass, "test.config_flow", None)
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
2019-07-31 12:25:30 -07:00
|
|
|
"test", context={"source": config_entries.SOURCE_DISCOVERY}, data={}
|
|
|
|
)
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
# Second discovery
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
2019-07-31 12:25:30 -07:00
|
|
|
"test", context={"source": config_entries.SOURCE_DISCOVERY}, data={}
|
|
|
|
)
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def test_only_one_in_progress(
|
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
|
|
|
|
) -> None:
|
2018-06-14 15:17:54 -04:00
|
|
|
"""Test a user initialized one will finish and cancel discovered one."""
|
2023-11-16 16:55:08 +01:00
|
|
|
mock_platform(hass, "test.config_flow", None)
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
# Discovery starts flow
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
2019-07-31 12:25:30 -07:00
|
|
|
"test", context={"source": config_entries.SOURCE_DISCOVERY}, data={}
|
|
|
|
)
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
2018-06-14 15:17:54 -04:00
|
|
|
|
|
|
|
# User starts flow
|
2018-08-13 02:27:18 -07:00
|
|
|
result = await hass.config_entries.flow.async_init(
|
2019-07-31 12:25:30 -07:00
|
|
|
"test", context={"source": config_entries.SOURCE_USER}, data={}
|
|
|
|
)
|
2018-06-14 15:17:54 -04:00
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
2018-09-21 16:34:37 +02:00
|
|
|
|
|
|
|
# Discovery flow has not been aborted
|
|
|
|
assert len(hass.config_entries.flow.async_progress()) == 2
|
|
|
|
|
|
|
|
# Discovery should be aborted once user confirms
|
2019-07-31 12:25:30 -07:00
|
|
|
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
2018-06-14 15:17:54 -04:00
|
|
|
assert len(hass.config_entries.flow.async_progress()) == 0
|
2018-07-23 15:08:03 +02:00
|
|
|
|
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def test_import_abort_discovery(
|
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
|
|
|
|
) -> None:
|
2020-06-10 22:46:14 +02:00
|
|
|
"""Test import will finish and cancel discovered one."""
|
2023-11-16 16:55:08 +01:00
|
|
|
mock_platform(hass, "test.config_flow", None)
|
2020-06-10 22:46:14 +02:00
|
|
|
|
|
|
|
# Discovery starts flow
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
|
|
"test", context={"source": config_entries.SOURCE_DISCOVERY}, data={}
|
|
|
|
)
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
2020-06-10 22:46:14 +02:00
|
|
|
|
|
|
|
# Start import flow
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
|
|
"test", context={"source": config_entries.SOURCE_IMPORT}, data={}
|
|
|
|
)
|
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
2020-06-10 22:46:14 +02:00
|
|
|
|
|
|
|
# Discovery flow has been aborted
|
|
|
|
assert len(hass.config_entries.flow.async_progress()) == 0
|
|
|
|
|
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def test_import_no_confirmation(
|
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
|
|
|
|
) -> None:
|
2018-08-19 22:29:08 +02:00
|
|
|
"""Test import requires no confirmation to set up."""
|
2019-07-31 12:25:30 -07:00
|
|
|
flow = config_entries.HANDLERS["test"]()
|
2018-07-23 15:08:03 +02:00
|
|
|
flow.hass = hass
|
2020-04-26 23:35:04 -07:00
|
|
|
flow.context = {}
|
2019-07-31 12:25:30 -07:00
|
|
|
discovery_flow_conf["discovered"] = True
|
2018-07-23 15:08:03 +02:00
|
|
|
|
|
|
|
result = await flow.async_step_import(None)
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
2018-07-23 15:08:03 +02:00
|
|
|
|
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def test_import_single_instance(
|
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
|
|
|
|
) -> None:
|
2018-07-23 15:08:03 +02:00
|
|
|
"""Test import doesn't create second instance."""
|
2019-07-31 12:25:30 -07:00
|
|
|
flow = config_entries.HANDLERS["test"]()
|
2018-07-23 15:08:03 +02:00
|
|
|
flow.hass = hass
|
2020-04-26 23:35:04 -07:00
|
|
|
flow.context = {}
|
2019-07-31 12:25:30 -07:00
|
|
|
discovery_flow_conf["discovered"] = True
|
|
|
|
MockConfigEntry(domain="test").add_to_hass(hass)
|
2018-07-23 15:08:03 +02:00
|
|
|
|
|
|
|
result = await flow.async_step_import(None)
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
2018-10-23 02:14:46 -07:00
|
|
|
|
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def test_ignored_discoveries(
|
|
|
|
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
|
|
|
|
) -> None:
|
2020-04-26 23:35:04 -07:00
|
|
|
"""Test we can ignore discovered entries."""
|
2023-11-16 16:55:08 +01:00
|
|
|
mock_platform(hass, "test.config_flow", None)
|
2020-04-26 23:35:04 -07:00
|
|
|
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
|
|
"test", context={"source": config_entries.SOURCE_DISCOVERY}, data={}
|
|
|
|
)
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
2020-04-26 23:35:04 -07:00
|
|
|
|
|
|
|
flow = next(
|
|
|
|
(
|
|
|
|
flw
|
|
|
|
for flw in hass.config_entries.flow.async_progress()
|
|
|
|
if flw["flow_id"] == result["flow_id"]
|
|
|
|
),
|
|
|
|
None,
|
|
|
|
)
|
|
|
|
|
|
|
|
# Ignore it.
|
|
|
|
await hass.config_entries.flow.async_init(
|
|
|
|
flow["handler"],
|
|
|
|
context={"source": config_entries.SOURCE_IGNORE},
|
2021-01-12 09:26:20 +01:00
|
|
|
data={"unique_id": flow["context"]["unique_id"], "title": "Ignored Entry"},
|
2020-04-26 23:35:04 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
# Second discovery should be aborted
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
|
|
"test", context={"source": config_entries.SOURCE_DISCOVERY}, data={}
|
|
|
|
)
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
2020-04-26 23:35:04 -07:00
|
|
|
|
|
|
|
|
2023-02-20 11:42:56 +01:00
|
|
|
async def test_webhook_single_entry_allowed(
|
2023-03-16 11:10:56 +01:00
|
|
|
hass: HomeAssistant, webhook_flow_conf: None
|
2023-02-20 11:42:56 +01:00
|
|
|
) -> None:
|
2018-10-23 02:14:46 -07:00
|
|
|
"""Test only a single entry is allowed."""
|
2019-07-31 12:25:30 -07:00
|
|
|
flow = config_entries.HANDLERS["test_single"]()
|
2018-10-23 02:14:46 -07:00
|
|
|
flow.hass = hass
|
|
|
|
|
2019-07-31 12:25:30 -07:00
|
|
|
MockConfigEntry(domain="test_single").add_to_hass(hass)
|
2018-10-23 02:14:46 -07:00
|
|
|
result = await flow.async_step_user()
|
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
2020-10-01 20:44:13 +02:00
|
|
|
assert result["reason"] == "single_instance_allowed"
|
2018-10-23 02:14:46 -07:00
|
|
|
|
|
|
|
|
2023-02-20 11:42:56 +01:00
|
|
|
async def test_webhook_multiple_entries_allowed(
|
2023-03-16 11:10:56 +01:00
|
|
|
hass: HomeAssistant, webhook_flow_conf: None
|
2023-02-20 11:42:56 +01:00
|
|
|
) -> None:
|
2018-10-23 02:14:46 -07:00
|
|
|
"""Test multiple entries are allowed when specified."""
|
2019-07-31 12:25:30 -07:00
|
|
|
flow = config_entries.HANDLERS["test_multiple"]()
|
2018-10-23 02:14:46 -07:00
|
|
|
flow.hass = hass
|
|
|
|
|
2019-07-31 12:25:30 -07:00
|
|
|
MockConfigEntry(domain="test_multiple").add_to_hass(hass)
|
|
|
|
hass.config.api = Mock(base_url="http://example.com")
|
2018-10-23 02:14:46 -07:00
|
|
|
|
|
|
|
result = await flow.async_step_user()
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
2018-10-23 02:14:46 -07:00
|
|
|
|
|
|
|
|
2023-02-20 11:42:56 +01:00
|
|
|
async def test_webhook_config_flow_registers_webhook(
|
2023-03-16 11:10:56 +01:00
|
|
|
hass: HomeAssistant, webhook_flow_conf: None
|
2023-02-20 11:42:56 +01:00
|
|
|
) -> None:
|
2018-10-23 02:14:46 -07:00
|
|
|
"""Test setting up an entry creates a webhook."""
|
2019-07-31 12:25:30 -07:00
|
|
|
flow = config_entries.HANDLERS["test_single"]()
|
2018-10-23 02:14:46 -07:00
|
|
|
flow.hass = hass
|
|
|
|
|
2020-05-08 17:52:32 +02:00
|
|
|
await async_process_ha_core_config(
|
2020-08-27 13:56:20 +02:00
|
|
|
hass,
|
|
|
|
{"external_url": "https://example.com"},
|
2020-05-08 17:52:32 +02:00
|
|
|
)
|
2018-10-23 02:14:46 -07:00
|
|
|
result = await flow.async_step_user(user_input={})
|
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
2019-07-31 12:25:30 -07:00
|
|
|
assert result["data"]["webhook_id"] is not None
|
2019-04-01 05:07:12 -07:00
|
|
|
|
|
|
|
|
2023-03-16 11:10:56 +01:00
|
|
|
async def test_webhook_create_cloudhook(
|
|
|
|
hass: HomeAssistant, webhook_flow_conf: None
|
|
|
|
) -> None:
|
2022-01-26 19:57:45 +01:00
|
|
|
"""Test cloudhook will be created if subscribed."""
|
2019-07-31 12:25:30 -07:00
|
|
|
assert await setup.async_setup_component(hass, "cloud", {})
|
2019-04-01 05:07:12 -07:00
|
|
|
|
2020-04-25 15:52:50 -07:00
|
|
|
async_setup_entry = Mock(return_value=True)
|
|
|
|
async_unload_entry = Mock(return_value=True)
|
2019-04-01 05:07:12 -07:00
|
|
|
|
2019-07-31 12:25:30 -07:00
|
|
|
mock_integration(
|
|
|
|
hass,
|
|
|
|
MockModule(
|
|
|
|
"test_single",
|
|
|
|
async_setup_entry=async_setup_entry,
|
|
|
|
async_unload_entry=async_unload_entry,
|
|
|
|
async_remove_entry=config_entry_flow.webhook_async_remove_entry,
|
|
|
|
),
|
|
|
|
)
|
2023-11-16 16:55:08 +01:00
|
|
|
mock_platform(hass, "test_single.config_flow", None)
|
2019-04-01 05:07:12 -07:00
|
|
|
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
2019-07-31 12:25:30 -07:00
|
|
|
"test_single", context={"source": config_entries.SOURCE_USER}
|
|
|
|
)
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
2019-07-31 12:25:30 -07:00
|
|
|
|
|
|
|
with patch(
|
2020-04-25 15:52:50 -07:00
|
|
|
"hass_nabucasa.cloudhooks.Cloudhooks.async_create",
|
|
|
|
return_value={"cloudhook_url": "https://example.com"},
|
2019-07-31 12:25:30 -07:00
|
|
|
) as mock_create, patch(
|
2022-01-26 19:57:45 +01:00
|
|
|
"hass_nabucasa.Cloud.subscription_expired",
|
|
|
|
new_callable=PropertyMock(return_value=False),
|
|
|
|
), patch(
|
|
|
|
"hass_nabucasa.Cloud.is_logged_in",
|
|
|
|
new_callable=PropertyMock(return_value=True),
|
2019-07-31 12:25:30 -07:00
|
|
|
), patch(
|
2022-01-26 19:57:45 +01:00
|
|
|
"hass_nabucasa.iot_base.BaseIoT.connected",
|
|
|
|
new_callable=PropertyMock(return_value=True),
|
2019-07-31 12:25:30 -07:00
|
|
|
):
|
|
|
|
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
2019-07-31 12:25:30 -07:00
|
|
|
assert result["description_placeholders"]["webhook_url"] == "https://example.com"
|
2019-04-01 05:07:12 -07:00
|
|
|
assert len(mock_create.mock_calls) == 1
|
|
|
|
assert len(async_setup_entry.mock_calls) == 1
|
|
|
|
|
2019-07-31 12:25:30 -07:00
|
|
|
with patch(
|
2020-04-25 15:52:50 -07:00
|
|
|
"hass_nabucasa.cloudhooks.Cloudhooks.async_delete",
|
|
|
|
return_value={"cloudhook_url": "https://example.com"},
|
2019-07-31 12:25:30 -07:00
|
|
|
) as mock_delete:
|
|
|
|
result = await hass.config_entries.async_remove(result["result"].entry_id)
|
2019-04-01 05:07:12 -07:00
|
|
|
|
|
|
|
assert len(mock_delete.mock_calls) == 1
|
2019-07-31 12:25:30 -07:00
|
|
|
assert result["require_restart"] is False
|
2021-04-29 23:12:58 +02:00
|
|
|
|
|
|
|
|
2023-02-20 11:42:56 +01:00
|
|
|
async def test_webhook_create_cloudhook_aborts_not_connected(
|
2023-03-16 11:10:56 +01:00
|
|
|
hass: HomeAssistant, webhook_flow_conf: None
|
2023-02-20 11:42:56 +01:00
|
|
|
) -> None:
|
2022-01-26 19:57:45 +01:00
|
|
|
"""Test cloudhook aborts if subscribed but not connected."""
|
|
|
|
assert await setup.async_setup_component(hass, "cloud", {})
|
|
|
|
|
|
|
|
async_setup_entry = Mock(return_value=True)
|
|
|
|
async_unload_entry = Mock(return_value=True)
|
|
|
|
|
|
|
|
mock_integration(
|
|
|
|
hass,
|
|
|
|
MockModule(
|
|
|
|
"test_single",
|
|
|
|
async_setup_entry=async_setup_entry,
|
|
|
|
async_unload_entry=async_unload_entry,
|
|
|
|
async_remove_entry=config_entry_flow.webhook_async_remove_entry,
|
|
|
|
),
|
|
|
|
)
|
2023-11-16 16:55:08 +01:00
|
|
|
mock_platform(hass, "test_single.config_flow", None)
|
2022-01-26 19:57:45 +01:00
|
|
|
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
|
|
"test_single", context={"source": config_entries.SOURCE_USER}
|
|
|
|
)
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
2022-01-26 19:57:45 +01:00
|
|
|
|
|
|
|
with patch(
|
|
|
|
"hass_nabucasa.cloudhooks.Cloudhooks.async_create",
|
|
|
|
return_value={"cloudhook_url": "https://example.com"},
|
|
|
|
), patch(
|
|
|
|
"hass_nabucasa.Cloud.subscription_expired",
|
|
|
|
new_callable=PropertyMock(return_value=False),
|
|
|
|
), patch(
|
|
|
|
"hass_nabucasa.Cloud.is_logged_in",
|
|
|
|
new_callable=PropertyMock(return_value=True),
|
|
|
|
), patch(
|
|
|
|
"hass_nabucasa.iot_base.BaseIoT.connected",
|
|
|
|
new_callable=PropertyMock(return_value=False),
|
|
|
|
):
|
|
|
|
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
|
|
|
|
2022-07-07 18:57:36 +02:00
|
|
|
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
2022-01-26 19:57:45 +01:00
|
|
|
assert result["reason"] == "cloud_not_connected"
|