core/tests/components/owntracks/test_config_flow.py

187 lines
6.0 KiB
Python

"""Tests for OwnTracks config flow."""
from unittest.mock import patch
import pytest
from homeassistant import config_entries, data_entry_flow
from homeassistant.components.owntracks import config_flow
from homeassistant.components.owntracks.config_flow import CONF_CLOUDHOOK, CONF_SECRET
from homeassistant.components.owntracks.const import DOMAIN
from homeassistant.config import async_process_ha_core_config
from homeassistant.const import CONF_WEBHOOK_ID
from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry
CONF_WEBHOOK_URL = "webhook_url"
BASE_URL = "http://example.com"
CLOUDHOOK = False
SECRET = "test-secret"
WEBHOOK_ID = "webhook_id"
WEBHOOK_URL = f"{BASE_URL}/api/webhook/webhook_id"
@pytest.fixture(name="webhook_id")
def mock_webhook_id():
"""Mock webhook_id."""
with patch(
"homeassistant.components.webhook.async_generate_id", return_value=WEBHOOK_ID
):
yield
@pytest.fixture(name="secret")
def mock_secret():
"""Mock secret."""
with patch("secrets.token_hex", return_value=SECRET):
yield
@pytest.fixture(name="not_supports_encryption")
def mock_not_supports_encryption():
"""Mock non successful nacl import."""
with patch(
"homeassistant.components.owntracks.config_flow.supports_encryption",
return_value=False,
):
yield
async def init_config_flow(hass):
"""Init a configuration flow."""
await async_process_ha_core_config(
hass,
{"external_url": BASE_URL},
)
flow = config_flow.OwnTracksFlow()
flow.hass = hass
return flow
async def test_user(hass, webhook_id, secret):
"""Test user step."""
flow = await init_config_flow(hass)
result = await flow.async_step_user()
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "user"
result = await flow.async_step_user({})
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["title"] == "OwnTracks"
assert result["data"][CONF_WEBHOOK_ID] == WEBHOOK_ID
assert result["data"][CONF_SECRET] == SECRET
assert result["data"][CONF_CLOUDHOOK] == CLOUDHOOK
assert result["description_placeholders"][CONF_WEBHOOK_URL] == WEBHOOK_URL
async def test_import(hass, webhook_id, secret):
"""Test import step."""
flow = await init_config_flow(hass)
result = await flow.async_step_import({})
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["title"] == "OwnTracks"
assert result["data"][CONF_WEBHOOK_ID] == WEBHOOK_ID
assert result["data"][CONF_SECRET] == SECRET
assert result["data"][CONF_CLOUDHOOK] == CLOUDHOOK
assert result["description_placeholders"] is None
async def test_import_setup(hass):
"""Test that we automatically create a config flow."""
await async_process_ha_core_config(
hass,
{"external_url": "http://example.com"},
)
assert not hass.config_entries.async_entries(DOMAIN)
assert await async_setup_component(hass, DOMAIN, {"owntracks": {}})
await hass.async_block_till_done()
assert hass.config_entries.async_entries(DOMAIN)
async def test_abort_if_already_setup(hass):
"""Test that we can't add more than one instance."""
flow = await init_config_flow(hass)
MockConfigEntry(domain=DOMAIN, data={}).add_to_hass(hass)
assert hass.config_entries.async_entries(DOMAIN)
# Should fail, already setup (import)
result = await flow.async_step_import({})
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "single_instance_allowed"
# Should fail, already setup (flow)
result = await flow.async_step_user({})
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "single_instance_allowed"
async def test_user_not_supports_encryption(hass, not_supports_encryption):
"""Test user step."""
flow = await init_config_flow(hass)
result = await flow.async_step_user({})
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert (
result["description_placeholders"]["secret"]
== "Encryption is not supported because nacl is not installed."
)
async def test_unload(hass):
"""Test unloading a config flow."""
await async_process_ha_core_config(
hass,
{"external_url": "http://example.com"},
)
with patch(
"homeassistant.config_entries.ConfigEntries.async_forward_entry_setup"
) as mock_forward:
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data={}
)
assert len(mock_forward.mock_calls) == 1
entry = result["result"]
assert mock_forward.mock_calls[0][1][0] is entry
assert mock_forward.mock_calls[0][1][1] == "device_tracker"
assert entry.data["webhook_id"] in hass.data["webhook"]
with patch(
"homeassistant.config_entries.ConfigEntries.async_unload_platforms",
return_value=True,
) as mock_unload:
assert await hass.config_entries.async_unload(entry.entry_id)
assert len(mock_unload.mock_calls) == 1
assert mock_forward.mock_calls[0][1][0] is entry
assert mock_forward.mock_calls[0][1][1] == "device_tracker"
assert entry.data["webhook_id"] not in hass.data["webhook"]
async def test_with_cloud_sub(hass):
"""Test creating a config flow while subscribed."""
hass.config.components.add("cloud")
with patch(
"homeassistant.components.cloud.async_active_subscription", return_value=True
), patch(
"homeassistant.components.cloud.async_create_cloudhook",
return_value="https://hooks.nabu.casa/ABCD",
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data={}
)
entry = result["result"]
assert entry.data["cloudhook"]
assert (
result["description_placeholders"]["webhook_url"]
== "https://hooks.nabu.casa/ABCD"
)