Detect use of deprecated base_url (#35353)
* Detect use of deprecated base_url * Update get_url helper * Update core migration * Migrate all tests
This commit is contained in:
parent
1be41b9de8
commit
e56dd8ed50
21 changed files with 308 additions and 73 deletions
|
@ -3,6 +3,7 @@ from ipaddress import ip_network
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import ssl
|
import ssl
|
||||||
|
from traceback import extract_stack
|
||||||
from typing import Optional, cast
|
from typing import Optional, cast
|
||||||
|
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
|
@ -119,14 +120,66 @@ class ApiConfig:
|
||||||
|
|
||||||
host = host.rstrip("/")
|
host = host.rstrip("/")
|
||||||
if host.startswith(("http://", "https://")):
|
if host.startswith(("http://", "https://")):
|
||||||
self.base_url = host
|
self.deprecated_base_url = host
|
||||||
elif use_ssl:
|
elif use_ssl:
|
||||||
self.base_url = f"https://{host}"
|
self.deprecated_base_url = f"https://{host}"
|
||||||
else:
|
else:
|
||||||
self.base_url = f"http://{host}"
|
self.deprecated_base_url = f"http://{host}"
|
||||||
|
|
||||||
if port is not None:
|
if port is not None:
|
||||||
self.base_url += f":{port}"
|
self.deprecated_base_url += f":{port}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def base_url(self) -> str:
|
||||||
|
"""Proxy property to find caller of this deprecated property."""
|
||||||
|
found_frame = None
|
||||||
|
for frame in reversed(extract_stack()):
|
||||||
|
for path in ("custom_components/", "homeassistant/components/"):
|
||||||
|
try:
|
||||||
|
index = frame.filename.index(path)
|
||||||
|
|
||||||
|
# Skip webhook from the stack
|
||||||
|
if frame.filename[index:].startswith(
|
||||||
|
"homeassistant/components/webhook/"
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
|
found_frame = frame
|
||||||
|
break
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if found_frame is not None:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Did not source from an integration? Hard error.
|
||||||
|
if found_frame is None:
|
||||||
|
raise RuntimeError(
|
||||||
|
"Detected use of deprecated `base_url` property in the Home Assistant core. Please report this issue."
|
||||||
|
)
|
||||||
|
|
||||||
|
# If a frame was found, it originated from an integration
|
||||||
|
if found_frame:
|
||||||
|
start = index + len(path)
|
||||||
|
end = found_frame.filename.index("/", start)
|
||||||
|
|
||||||
|
integration = found_frame.filename[start:end]
|
||||||
|
|
||||||
|
if path == "custom_components/":
|
||||||
|
extra = " to the custom component author"
|
||||||
|
else:
|
||||||
|
extra = ""
|
||||||
|
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Detected use of deprecated `base_url` property, use `homeassistant.helpers.network.async_get_url` method instead. Please report issue%s for %s using this method at %s, line %s: %s",
|
||||||
|
extra,
|
||||||
|
integration,
|
||||||
|
found_frame.filename[index:],
|
||||||
|
found_frame.lineno,
|
||||||
|
found_frame.line.strip(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.deprecated_base_url
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass, config):
|
async def async_setup(hass, config):
|
||||||
|
|
|
@ -1463,7 +1463,7 @@ class Config:
|
||||||
if self.hass.config.api is None:
|
if self.hass.config.api is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
base_url = yarl.URL(self.hass.config.api.base_url)
|
base_url = yarl.URL(self.hass.config.api.deprecated_base_url)
|
||||||
|
|
||||||
# Check if this is an internal URL
|
# Check if this is an internal URL
|
||||||
if str(base_url.host).endswith(".local") or (
|
if str(base_url.host).endswith(".local") or (
|
||||||
|
|
|
@ -195,10 +195,10 @@ def _async_get_deprecated_base_url(
|
||||||
require_standard_port: bool = False,
|
require_standard_port: bool = False,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Work with the deprecated `base_url`, used as fallback."""
|
"""Work with the deprecated `base_url`, used as fallback."""
|
||||||
if hass.config.api is None or not hass.config.api.base_url:
|
if hass.config.api is None or not hass.config.api.deprecated_base_url:
|
||||||
raise NoURLAvailableError
|
raise NoURLAvailableError
|
||||||
|
|
||||||
base_url = yarl.URL(hass.config.api.base_url)
|
base_url = yarl.URL(hass.config.api.deprecated_base_url)
|
||||||
# Rules that apply to both internal and external
|
# Rules that apply to both internal and external
|
||||||
if (
|
if (
|
||||||
(allow_ip or not is_ip_address(str(base_url.host)))
|
(allow_ip or not is_ip_address(str(base_url.host)))
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
"""Test Home Assistant Cast."""
|
"""Test Home Assistant Cast."""
|
||||||
from homeassistant.components.cast import home_assistant_cast
|
from homeassistant.components.cast import home_assistant_cast
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
|
|
||||||
from tests.async_mock import Mock, patch
|
from tests.async_mock import patch
|
||||||
from tests.common import MockConfigEntry, async_mock_signal
|
from tests.common import MockConfigEntry, async_mock_signal
|
||||||
|
|
||||||
|
|
||||||
async def test_service_show_view(hass):
|
async def test_service_show_view(hass):
|
||||||
"""Test we don't set app id in prod."""
|
"""Test we don't set app id in prod."""
|
||||||
hass.config.api = Mock(base_url="https://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "https://example.com"},
|
||||||
|
)
|
||||||
await home_assistant_cast.async_setup_ha_cast(hass, MockConfigEntry())
|
await home_assistant_cast.async_setup_ha_cast(hass, MockConfigEntry())
|
||||||
calls = async_mock_signal(hass, home_assistant_cast.SIGNAL_HASS_CAST_SHOW_VIEW)
|
calls = async_mock_signal(hass, home_assistant_cast.SIGNAL_HASS_CAST_SHOW_VIEW)
|
||||||
|
|
||||||
|
@ -31,7 +34,9 @@ async def test_service_show_view(hass):
|
||||||
|
|
||||||
async def test_service_show_view_dashboard(hass):
|
async def test_service_show_view_dashboard(hass):
|
||||||
"""Test casting a specific dashboard."""
|
"""Test casting a specific dashboard."""
|
||||||
hass.config.api = Mock(base_url="https://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "https://example.com"},
|
||||||
|
)
|
||||||
await home_assistant_cast.async_setup_ha_cast(hass, MockConfigEntry())
|
await home_assistant_cast.async_setup_ha_cast(hass, MockConfigEntry())
|
||||||
calls = async_mock_signal(hass, home_assistant_cast.SIGNAL_HASS_CAST_SHOW_VIEW)
|
calls = async_mock_signal(hass, home_assistant_cast.SIGNAL_HASS_CAST_SHOW_VIEW)
|
||||||
|
|
||||||
|
@ -55,7 +60,9 @@ async def test_service_show_view_dashboard(hass):
|
||||||
|
|
||||||
async def test_use_cloud_url(hass):
|
async def test_use_cloud_url(hass):
|
||||||
"""Test that we fall back to cloud url."""
|
"""Test that we fall back to cloud url."""
|
||||||
hass.config.api = Mock(base_url="http://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"internal_url": "http://example.local:8123"},
|
||||||
|
)
|
||||||
hass.config.components.add("cloud")
|
hass.config.components.add("cloud")
|
||||||
|
|
||||||
await home_assistant_cast.async_setup_ha_cast(hass, MockConfigEntry())
|
await home_assistant_cast.async_setup_ha_cast(hass, MockConfigEntry())
|
||||||
|
|
|
@ -6,11 +6,10 @@ import pytest
|
||||||
|
|
||||||
from homeassistant import data_entry_flow
|
from homeassistant import data_entry_flow
|
||||||
from homeassistant.components import dialogflow, intent_script
|
from homeassistant.components import dialogflow, intent_script
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.async_mock import Mock
|
|
||||||
|
|
||||||
SESSION_ID = "a9b84cec-46b6-484e-8f31-f65dba03ae6d"
|
SESSION_ID = "a9b84cec-46b6-484e-8f31-f65dba03ae6d"
|
||||||
INTENT_ID = "c6a74079-a8f0-46cd-b372-5a934d23591c"
|
INTENT_ID = "c6a74079-a8f0-46cd-b372-5a934d23591c"
|
||||||
INTENT_NAME = "tests"
|
INTENT_NAME = "tests"
|
||||||
|
@ -79,7 +78,10 @@ async def fixture(hass, aiohttp_client):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
hass.config.api = Mock(base_url="http://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"internal_url": "http://example.local:8123"},
|
||||||
|
)
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
"dialogflow", context={"source": "user"}
|
"dialogflow", context={"source": "user"}
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import pytest
|
||||||
from homeassistant import data_entry_flow
|
from homeassistant import data_entry_flow
|
||||||
from homeassistant.components import zone
|
from homeassistant.components import zone
|
||||||
from homeassistant.components.geofency import CONF_MOBILE_BEACONS, DOMAIN
|
from homeassistant.components.geofency import CONF_MOBILE_BEACONS, DOMAIN
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
HTTP_OK,
|
HTTP_OK,
|
||||||
HTTP_UNPROCESSABLE_ENTITY,
|
HTTP_UNPROCESSABLE_ENTITY,
|
||||||
|
@ -14,7 +15,7 @@ from homeassistant.setup import async_setup_component
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
|
|
||||||
# pylint: disable=redefined-outer-name
|
# pylint: disable=redefined-outer-name
|
||||||
from tests.async_mock import Mock, patch
|
from tests.async_mock import patch
|
||||||
|
|
||||||
HOME_LATITUDE = 37.239622
|
HOME_LATITUDE = 37.239622
|
||||||
HOME_LONGITUDE = -115.815811
|
HOME_LONGITUDE = -115.815811
|
||||||
|
@ -148,7 +149,9 @@ async def setup_zones(loop, hass):
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def webhook_id(hass, geofency_client):
|
async def webhook_id(hass, geofency_client):
|
||||||
"""Initialize the Geofency component and get the webhook_id."""
|
"""Initialize the Geofency component and get the webhook_id."""
|
||||||
hass.config.api = Mock(base_url="http://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"internal_url": "http://example.local:8123"},
|
||||||
|
)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": "user"}
|
DOMAIN, context={"source": "user"}
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,6 +8,7 @@ from homeassistant.components.google_assistant.const import ( # noqa: F401
|
||||||
EVENT_COMMAND_RECEIVED,
|
EVENT_COMMAND_RECEIVED,
|
||||||
NOT_EXPOSE_LOCAL,
|
NOT_EXPOSE_LOCAL,
|
||||||
)
|
)
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
from homeassistant.util import dt
|
from homeassistant.util import dt
|
||||||
|
|
||||||
|
@ -24,7 +25,11 @@ from tests.common import (
|
||||||
async def test_google_entity_sync_serialize_with_local_sdk(hass):
|
async def test_google_entity_sync_serialize_with_local_sdk(hass):
|
||||||
"""Test sync serialize attributes of a GoogleEntity."""
|
"""Test sync serialize attributes of a GoogleEntity."""
|
||||||
hass.states.async_set("light.ceiling_lights", "off")
|
hass.states.async_set("light.ceiling_lights", "off")
|
||||||
hass.config.api = Mock(port=1234, use_ssl=True, base_url="https://hostname:1234")
|
hass.config.api = Mock(port=1234, use_ssl=True)
|
||||||
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "https://hostname:1234"},
|
||||||
|
)
|
||||||
|
|
||||||
hass.http = Mock(server_port=1234)
|
hass.http = Mock(server_port=1234)
|
||||||
config = MockConfig(
|
config = MockConfig(
|
||||||
hass=hass,
|
hass=hass,
|
||||||
|
|
|
@ -5,6 +5,7 @@ from homeassistant import data_entry_flow
|
||||||
from homeassistant.components import gpslogger, zone
|
from homeassistant.components import gpslogger, zone
|
||||||
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
|
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
|
||||||
from homeassistant.components.gpslogger import DOMAIN, TRACKER_UPDATE
|
from homeassistant.components.gpslogger import DOMAIN, TRACKER_UPDATE
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
HTTP_OK,
|
HTTP_OK,
|
||||||
HTTP_UNPROCESSABLE_ENTITY,
|
HTTP_UNPROCESSABLE_ENTITY,
|
||||||
|
@ -14,7 +15,7 @@ from homeassistant.const import (
|
||||||
from homeassistant.helpers.dispatcher import DATA_DISPATCHER
|
from homeassistant.helpers.dispatcher import DATA_DISPATCHER
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.async_mock import Mock, patch
|
from tests.async_mock import patch
|
||||||
|
|
||||||
HOME_LATITUDE = 37.239622
|
HOME_LATITUDE = 37.239622
|
||||||
HOME_LONGITUDE = -115.815811
|
HOME_LONGITUDE = -115.815811
|
||||||
|
@ -62,7 +63,9 @@ async def setup_zones(loop, hass):
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def webhook_id(hass, gpslogger_client):
|
async def webhook_id(hass, gpslogger_client):
|
||||||
"""Initialize the GPSLogger component and get the webhook_id."""
|
"""Initialize the GPSLogger component and get the webhook_id."""
|
||||||
hass.config.api = Mock(base_url="http://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"internal_url": "http://example.local:8123"},
|
||||||
|
)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": "user"}
|
DOMAIN, context={"source": "user"}
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,11 +3,13 @@ from ipaddress import ip_network
|
||||||
import logging
|
import logging
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
import homeassistant.components.http as http
|
import homeassistant.components.http as http
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
from homeassistant.util.ssl import server_context_intermediate, server_context_modern
|
from homeassistant.util.ssl import server_context_intermediate, server_context_modern
|
||||||
|
|
||||||
from tests.async_mock import patch
|
from tests.async_mock import Mock, patch
|
||||||
|
|
||||||
|
|
||||||
class TestView(http.HomeAssistantView):
|
class TestView(http.HomeAssistantView):
|
||||||
|
@ -271,3 +273,127 @@ async def test_storing_config(hass, aiohttp_client, aiohttp_unused_port):
|
||||||
restored["trusted_proxies"][0] = ip_network(restored["trusted_proxies"][0])
|
restored["trusted_proxies"][0] = ip_network(restored["trusted_proxies"][0])
|
||||||
|
|
||||||
assert restored == http.HTTP_SCHEMA(config)
|
assert restored == http.HTTP_SCHEMA(config)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_use_of_base_url(hass):
|
||||||
|
"""Test detection base_url usage when called without integration context."""
|
||||||
|
await async_setup_component(hass, "http", {"http": {}})
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.http.extract_stack",
|
||||||
|
return_value=[
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/homeassistant/core.py",
|
||||||
|
lineno="21",
|
||||||
|
line="do_something()",
|
||||||
|
),
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/homeassistant/core.py",
|
||||||
|
lineno="42",
|
||||||
|
line="url = hass.config.api.base_url",
|
||||||
|
),
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/example/client.py",
|
||||||
|
lineno="21",
|
||||||
|
line="something()",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
), pytest.raises(RuntimeError):
|
||||||
|
hass.config.api.base_url
|
||||||
|
|
||||||
|
|
||||||
|
async def test_use_of_base_url_integration(hass, caplog):
|
||||||
|
"""Test detection base_url usage when called with integration context."""
|
||||||
|
await async_setup_component(hass, "http", {"http": {}})
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.http.extract_stack",
|
||||||
|
return_value=[
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/homeassistant/core.py",
|
||||||
|
lineno="21",
|
||||||
|
line="do_something()",
|
||||||
|
),
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/homeassistant/components/example/__init__.py",
|
||||||
|
lineno="42",
|
||||||
|
line="url = hass.config.api.base_url",
|
||||||
|
),
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/example/client.py",
|
||||||
|
lineno="21",
|
||||||
|
line="something()",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
):
|
||||||
|
assert hass.config.api.base_url == "http://127.0.0.1:8123"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
"Detected use of deprecated `base_url` property, use `homeassistant.helpers.network.async_get_url` method instead. Please report issue for example using this method at homeassistant/components/example/__init__.py, line 42: url = hass.config.api.base_url"
|
||||||
|
in caplog.text
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_use_of_base_url_integration_webhook(hass, caplog):
|
||||||
|
"""Test detection base_url usage when called with integration context."""
|
||||||
|
await async_setup_component(hass, "http", {"http": {}})
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.http.extract_stack",
|
||||||
|
return_value=[
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/homeassistant/core.py",
|
||||||
|
lineno="21",
|
||||||
|
line="do_something()",
|
||||||
|
),
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/homeassistant/components/example/__init__.py",
|
||||||
|
lineno="42",
|
||||||
|
line="url = hass.config.api.base_url",
|
||||||
|
),
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/homeassistant/components/webhook/__init__.py",
|
||||||
|
lineno="42",
|
||||||
|
line="return async_get_url(hass)",
|
||||||
|
),
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/example/client.py",
|
||||||
|
lineno="21",
|
||||||
|
line="something()",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
):
|
||||||
|
assert hass.config.api.base_url == "http://127.0.0.1:8123"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
"Detected use of deprecated `base_url` property, use `homeassistant.helpers.network.async_get_url` method instead. Please report issue for example using this method at homeassistant/components/example/__init__.py, line 42: url = hass.config.api.base_url"
|
||||||
|
in caplog.text
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_use_of_base_url_custom_component(hass, caplog):
|
||||||
|
"""Test detection base_url usage when called with custom component context."""
|
||||||
|
await async_setup_component(hass, "http", {"http": {}})
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.http.extract_stack",
|
||||||
|
return_value=[
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/homeassistant/core.py",
|
||||||
|
lineno="21",
|
||||||
|
line="do_something()",
|
||||||
|
),
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/.homeassistant/custom_components/example/__init__.py",
|
||||||
|
lineno="42",
|
||||||
|
line="url = hass.config.api.base_url",
|
||||||
|
),
|
||||||
|
Mock(
|
||||||
|
filename="/home/frenck/example/client.py",
|
||||||
|
lineno="21",
|
||||||
|
line="something()",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
):
|
||||||
|
assert hass.config.api.base_url == "http://127.0.0.1:8123"
|
||||||
|
|
||||||
|
assert (
|
||||||
|
"Detected use of deprecated `base_url` property, use `homeassistant.helpers.network.async_get_url` method instead. Please report issue to the custom component author for example using this method at custom_components/example/__init__.py, line 42: url = hass.config.api.base_url"
|
||||||
|
in caplog.text
|
||||||
|
)
|
||||||
|
|
|
@ -5,11 +5,12 @@ from homeassistant import data_entry_flow
|
||||||
from homeassistant.components import locative
|
from homeassistant.components import locative
|
||||||
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
|
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
|
||||||
from homeassistant.components.locative import DOMAIN, TRACKER_UPDATE
|
from homeassistant.components.locative import DOMAIN, TRACKER_UPDATE
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.const import HTTP_OK, HTTP_UNPROCESSABLE_ENTITY
|
from homeassistant.const import HTTP_OK, HTTP_UNPROCESSABLE_ENTITY
|
||||||
from homeassistant.helpers.dispatcher import DATA_DISPATCHER
|
from homeassistant.helpers.dispatcher import DATA_DISPATCHER
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.async_mock import Mock, patch
|
from tests.async_mock import patch
|
||||||
|
|
||||||
# pylint: disable=redefined-outer-name
|
# pylint: disable=redefined-outer-name
|
||||||
|
|
||||||
|
@ -33,7 +34,9 @@ async def locative_client(loop, hass, hass_client):
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def webhook_id(hass, locative_client):
|
async def webhook_id(hass, locative_client):
|
||||||
"""Initialize the Geofency component and get the webhook_id."""
|
"""Initialize the Geofency component and get the webhook_id."""
|
||||||
hass.config.api = Mock(base_url="http://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"internal_url": "http://example.local:8123"},
|
||||||
|
)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
"locative", context={"source": "user"}
|
"locative", context={"source": "user"}
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,12 +6,11 @@ import pytest
|
||||||
|
|
||||||
from homeassistant import data_entry_flow
|
from homeassistant import data_entry_flow
|
||||||
from homeassistant.components import mailgun, webhook
|
from homeassistant.components import mailgun, webhook
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.const import CONF_API_KEY, CONF_DOMAIN
|
from homeassistant.const import CONF_API_KEY, CONF_DOMAIN
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.async_mock import Mock
|
|
||||||
|
|
||||||
API_KEY = "abc123"
|
API_KEY = "abc123"
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,7 +30,9 @@ async def webhook_id_with_api_key(hass):
|
||||||
{mailgun.DOMAIN: {CONF_API_KEY: API_KEY, CONF_DOMAIN: "example.com"}},
|
{mailgun.DOMAIN: {CONF_API_KEY: API_KEY, CONF_DOMAIN: "example.com"}},
|
||||||
)
|
)
|
||||||
|
|
||||||
hass.config.api = Mock(base_url="http://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"internal_url": "http://example.local:8123"},
|
||||||
|
)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
"mailgun", context={"source": "user"}
|
"mailgun", context={"source": "user"}
|
||||||
)
|
)
|
||||||
|
@ -48,7 +49,9 @@ async def webhook_id_without_api_key(hass):
|
||||||
"""Initialize the Mailgun component and get the webhook_id w/o API key."""
|
"""Initialize the Mailgun component and get the webhook_id w/o API key."""
|
||||||
await async_setup_component(hass, mailgun.DOMAIN, {})
|
await async_setup_component(hass, mailgun.DOMAIN, {})
|
||||||
|
|
||||||
hass.config.api = Mock(base_url="http://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"internal_url": "http://example.local:8123"},
|
||||||
|
)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
"mailgun", context={"source": "user"}
|
"mailgun", context={"source": "user"}
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.const import CONF_WEBHOOK_ID
|
from homeassistant.const import CONF_WEBHOOK_ID
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.async_mock import Mock, patch
|
from tests.async_mock import patch
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
CONF_WEBHOOK_URL = "webhook_url"
|
CONF_WEBHOOK_URL = "webhook_url"
|
||||||
|
@ -47,9 +47,11 @@ def mock_not_supports_encryption():
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
def init_config_flow(hass):
|
async def init_config_flow(hass):
|
||||||
"""Init a configuration flow."""
|
"""Init a configuration flow."""
|
||||||
hass.config.api = Mock(base_url=BASE_URL)
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": BASE_URL},
|
||||||
|
)
|
||||||
flow = config_flow.OwnTracksFlow()
|
flow = config_flow.OwnTracksFlow()
|
||||||
flow.hass = hass
|
flow.hass = hass
|
||||||
return flow
|
return flow
|
||||||
|
@ -57,7 +59,7 @@ def init_config_flow(hass):
|
||||||
|
|
||||||
async def test_user(hass, webhook_id, secret):
|
async def test_user(hass, webhook_id, secret):
|
||||||
"""Test user step."""
|
"""Test user step."""
|
||||||
flow = init_config_flow(hass)
|
flow = await init_config_flow(hass)
|
||||||
|
|
||||||
result = await flow.async_step_user()
|
result = await flow.async_step_user()
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
@ -74,7 +76,7 @@ async def test_user(hass, webhook_id, secret):
|
||||||
|
|
||||||
async def test_import(hass, webhook_id, secret):
|
async def test_import(hass, webhook_id, secret):
|
||||||
"""Test import step."""
|
"""Test import step."""
|
||||||
flow = init_config_flow(hass)
|
flow = await init_config_flow(hass)
|
||||||
|
|
||||||
result = await flow.async_step_import({})
|
result = await flow.async_step_import({})
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
@ -99,7 +101,7 @@ async def test_import_setup(hass):
|
||||||
|
|
||||||
async def test_abort_if_already_setup(hass):
|
async def test_abort_if_already_setup(hass):
|
||||||
"""Test that we can't add more than one instance."""
|
"""Test that we can't add more than one instance."""
|
||||||
flow = init_config_flow(hass)
|
flow = await init_config_flow(hass)
|
||||||
|
|
||||||
MockConfigEntry(domain=DOMAIN, data={}).add_to_hass(hass)
|
MockConfigEntry(domain=DOMAIN, data={}).add_to_hass(hass)
|
||||||
assert hass.config_entries.async_entries(DOMAIN)
|
assert hass.config_entries.async_entries(DOMAIN)
|
||||||
|
@ -117,7 +119,7 @@ async def test_abort_if_already_setup(hass):
|
||||||
|
|
||||||
async def test_user_not_supports_encryption(hass, not_supports_encryption):
|
async def test_user_not_supports_encryption(hass, not_supports_encryption):
|
||||||
"""Test user step."""
|
"""Test user step."""
|
||||||
flow = init_config_flow(hass)
|
flow = await init_config_flow(hass)
|
||||||
|
|
||||||
result = await flow.async_step_user({})
|
result = await flow.async_step_user({})
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
|
|
@ -37,6 +37,7 @@ from homeassistant.components.smartthings.const import (
|
||||||
STORAGE_KEY,
|
STORAGE_KEY,
|
||||||
STORAGE_VERSION,
|
STORAGE_VERSION,
|
||||||
)
|
)
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.config_entries import CONN_CLASS_CLOUD_PUSH, SOURCE_USER, ConfigEntry
|
from homeassistant.config_entries import CONN_CLASS_CLOUD_PUSH, SOURCE_USER, ConfigEntry
|
||||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_WEBHOOK_ID
|
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_WEBHOOK_ID
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
@ -73,8 +74,10 @@ async def setup_platform(hass, platform: str, *, devices=None, scenes=None):
|
||||||
async def setup_component(hass, config_file, hass_storage):
|
async def setup_component(hass, config_file, hass_storage):
|
||||||
"""Load the SmartThing component."""
|
"""Load the SmartThing component."""
|
||||||
hass_storage[STORAGE_KEY] = {"data": config_file, "version": STORAGE_VERSION}
|
hass_storage[STORAGE_KEY] = {"data": config_file, "version": STORAGE_VERSION}
|
||||||
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "https://test.local"},
|
||||||
|
)
|
||||||
await async_setup_component(hass, "smartthings", {})
|
await async_setup_component(hass, "smartthings", {})
|
||||||
hass.config.api.base_url = "https://test.local"
|
|
||||||
|
|
||||||
|
|
||||||
def _create_location():
|
def _create_location():
|
||||||
|
@ -97,7 +100,7 @@ def locations_fixture(location):
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="app")
|
@pytest.fixture(name="app")
|
||||||
def app_fixture(hass, config_file):
|
async def app_fixture(hass, config_file):
|
||||||
"""Fixture for a single app."""
|
"""Fixture for a single app."""
|
||||||
app = Mock(AppEntity)
|
app = Mock(AppEntity)
|
||||||
app.app_name = APP_NAME_PREFIX + str(uuid4())
|
app.app_name = APP_NAME_PREFIX + str(uuid4())
|
||||||
|
@ -105,7 +108,7 @@ def app_fixture(hass, config_file):
|
||||||
app.app_type = "WEBHOOK_SMART_APP"
|
app.app_type = "WEBHOOK_SMART_APP"
|
||||||
app.classifications = [CLASSIFICATION_AUTOMATION]
|
app.classifications = [CLASSIFICATION_AUTOMATION]
|
||||||
app.display_name = "Home Assistant"
|
app.display_name = "Home Assistant"
|
||||||
app.description = f"{hass.config.location_name} at {hass.config.api.base_url}"
|
app.description = f"{hass.config.location_name} at https://test.local"
|
||||||
app.single_instance = True
|
app.single_instance = True
|
||||||
app.webhook_target_url = webhook.async_generate_url(
|
app.webhook_target_url = webhook.async_generate_url(
|
||||||
hass, hass.data[DOMAIN][CONF_WEBHOOK_ID]
|
hass, hass.data[DOMAIN][CONF_WEBHOOK_ID]
|
||||||
|
|
|
@ -15,6 +15,7 @@ from homeassistant.components.smartthings.const import (
|
||||||
CONF_OAUTH_CLIENT_SECRET,
|
CONF_OAUTH_CLIENT_SECRET,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
)
|
)
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_ACCESS_TOKEN,
|
CONF_ACCESS_TOKEN,
|
||||||
HTTP_FORBIDDEN,
|
HTTP_FORBIDDEN,
|
||||||
|
@ -417,9 +418,10 @@ async def test_entry_created_with_cloudhook(
|
||||||
|
|
||||||
async def test_invalid_webhook_aborts(hass):
|
async def test_invalid_webhook_aborts(hass):
|
||||||
"""Test flow aborts if webhook is invalid."""
|
"""Test flow aborts if webhook is invalid."""
|
||||||
hass.config.api.base_url = "http://0.0.0.0"
|
|
||||||
|
|
||||||
# Webhook confirmation shown
|
# Webhook confirmation shown
|
||||||
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "http://example.local:8123"},
|
||||||
|
)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": "user"}
|
DOMAIN, context={"source": "user"}
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,6 +16,7 @@ from homeassistant.components.smartthings.const import (
|
||||||
SIGNAL_SMARTTHINGS_UPDATE,
|
SIGNAL_SMARTTHINGS_UPDATE,
|
||||||
SUPPORTED_PLATFORMS,
|
SUPPORTED_PLATFORMS,
|
||||||
)
|
)
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.const import HTTP_FORBIDDEN, HTTP_INTERNAL_SERVER_ERROR
|
from homeassistant.const import HTTP_FORBIDDEN, HTTP_INTERNAL_SERVER_ERROR
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
@ -116,7 +117,9 @@ async def test_base_url_no_longer_https_does_not_load(
|
||||||
hass, config_entry, app, smartthings_mock
|
hass, config_entry, app, smartthings_mock
|
||||||
):
|
):
|
||||||
"""Test base_url no longer valid creates a new flow."""
|
"""Test base_url no longer valid creates a new flow."""
|
||||||
hass.config.api.base_url = "http://0.0.0.0"
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "http://example.local:8123"},
|
||||||
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
smartthings_mock.app.return_value = app
|
smartthings_mock.app.return_value = app
|
||||||
|
|
||||||
|
@ -218,7 +221,6 @@ async def test_config_entry_loads_unconnected_cloud(
|
||||||
"""Test entry loads during startup when cloud isn't connected."""
|
"""Test entry loads during startup when cloud isn't connected."""
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
hass.data[DOMAIN][CONF_CLOUDHOOK_URL] = "https://test.cloud"
|
hass.data[DOMAIN][CONF_CLOUDHOOK_URL] = "https://test.cloud"
|
||||||
hass.config.api.base_url = "http://0.0.0.0"
|
|
||||||
smartthings_mock.app.return_value = app
|
smartthings_mock.app.return_value = app
|
||||||
smartthings_mock.installed_app.return_value = installed_app
|
smartthings_mock.installed_app.return_value = installed_app
|
||||||
smartthings_mock.devices.return_value = [device]
|
smartthings_mock.devices.return_value = [device]
|
||||||
|
|
|
@ -5,6 +5,7 @@ from homeassistant import data_entry_flow
|
||||||
from homeassistant.components import traccar, zone
|
from homeassistant.components import traccar, zone
|
||||||
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
|
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
|
||||||
from homeassistant.components.traccar import DOMAIN, TRACKER_UPDATE
|
from homeassistant.components.traccar import DOMAIN, TRACKER_UPDATE
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
HTTP_OK,
|
HTTP_OK,
|
||||||
HTTP_UNPROCESSABLE_ENTITY,
|
HTTP_UNPROCESSABLE_ENTITY,
|
||||||
|
@ -14,7 +15,7 @@ from homeassistant.const import (
|
||||||
from homeassistant.helpers.dispatcher import DATA_DISPATCHER
|
from homeassistant.helpers.dispatcher import DATA_DISPATCHER
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.async_mock import Mock, patch
|
from tests.async_mock import patch
|
||||||
|
|
||||||
HOME_LATITUDE = 37.239622
|
HOME_LATITUDE = 37.239622
|
||||||
HOME_LONGITUDE = -115.815811
|
HOME_LONGITUDE = -115.815811
|
||||||
|
@ -23,7 +24,6 @@ HOME_LONGITUDE = -115.815811
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def mock_dev_track(mock_device_tracker_conf):
|
def mock_dev_track(mock_device_tracker_conf):
|
||||||
"""Mock device tracker config loading."""
|
"""Mock device tracker config loading."""
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="client")
|
@pytest.fixture(name="client")
|
||||||
|
@ -60,7 +60,9 @@ async def setup_zones(loop, hass):
|
||||||
@pytest.fixture(name="webhook_id")
|
@pytest.fixture(name="webhook_id")
|
||||||
async def webhook_id_fixture(hass, client):
|
async def webhook_id_fixture(hass, client):
|
||||||
"""Initialize the Traccar component and get the webhook_id."""
|
"""Initialize the Traccar component and get the webhook_id."""
|
||||||
hass.config.api = Mock(base_url="http://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "http://example.com"},
|
||||||
|
)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": "user"}
|
DOMAIN, context={"source": "user"}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
"""Test the webhook component."""
|
"""Test the webhook component."""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.async_mock import Mock
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_client(hass, hass_client):
|
def mock_client(hass, hass_client):
|
||||||
|
@ -37,7 +36,9 @@ async def test_unregistering_webhook(hass, mock_client):
|
||||||
|
|
||||||
async def test_generate_webhook_url(hass):
|
async def test_generate_webhook_url(hass):
|
||||||
"""Test we generate a webhook url correctly."""
|
"""Test we generate a webhook url correctly."""
|
||||||
hass.config.api = Mock(base_url="https://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "https://example.com"},
|
||||||
|
)
|
||||||
url = hass.components.webhook.async_generate_url("some_id")
|
url = hass.components.webhook.async_generate_url("some_id")
|
||||||
|
|
||||||
assert url == "https://example.com/api/webhook/some_id"
|
assert url == "https://example.com/api/webhook/some_id"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant import config_entries, data_entry_flow, setup
|
from homeassistant import config_entries, data_entry_flow, setup
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.helpers import config_entry_flow
|
from homeassistant.helpers import config_entry_flow
|
||||||
|
|
||||||
from tests.async_mock import Mock, patch
|
from tests.async_mock import Mock, patch
|
||||||
|
@ -232,7 +233,9 @@ async def test_webhook_config_flow_registers_webhook(hass, webhook_flow_conf):
|
||||||
flow = config_entries.HANDLERS["test_single"]()
|
flow = config_entries.HANDLERS["test_single"]()
|
||||||
flow.hass = hass
|
flow.hass = hass
|
||||||
|
|
||||||
hass.config.api = Mock(base_url="http://example.com")
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "https://example.com"},
|
||||||
|
)
|
||||||
result = await flow.async_step_user(user_input={})
|
result = await flow.async_step_user(user_input={})
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
|
|
@ -6,6 +6,7 @@ import time
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant import config_entries, data_entry_flow, setup
|
from homeassistant import config_entries, data_entry_flow, setup
|
||||||
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.helpers import config_entry_oauth2_flow
|
from homeassistant.helpers import config_entry_oauth2_flow
|
||||||
|
|
||||||
from tests.async_mock import patch
|
from tests.async_mock import patch
|
||||||
|
@ -124,7 +125,9 @@ async def test_abort_if_authorization_timeout(hass, flow_handler, local_impl):
|
||||||
|
|
||||||
async def test_step_discovery(hass, flow_handler, local_impl):
|
async def test_step_discovery(hass, flow_handler, local_impl):
|
||||||
"""Check flow triggers from discovery."""
|
"""Check flow triggers from discovery."""
|
||||||
hass.config.api.base_url = "https://example.com"
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "https://example.com"},
|
||||||
|
)
|
||||||
flow_handler.async_register_implementation(hass, local_impl)
|
flow_handler.async_register_implementation(hass, local_impl)
|
||||||
config_entry_oauth2_flow.async_register_implementation(
|
config_entry_oauth2_flow.async_register_implementation(
|
||||||
hass, TEST_DOMAIN, MockOAuth2Implementation()
|
hass, TEST_DOMAIN, MockOAuth2Implementation()
|
||||||
|
@ -140,7 +143,10 @@ async def test_step_discovery(hass, flow_handler, local_impl):
|
||||||
|
|
||||||
async def test_abort_discovered_multiple(hass, flow_handler, local_impl):
|
async def test_abort_discovered_multiple(hass, flow_handler, local_impl):
|
||||||
"""Test if aborts when discovered multiple times."""
|
"""Test if aborts when discovered multiple times."""
|
||||||
hass.config.api.base_url = "https://example.com"
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "https://example.com"},
|
||||||
|
)
|
||||||
|
|
||||||
flow_handler.async_register_implementation(hass, local_impl)
|
flow_handler.async_register_implementation(hass, local_impl)
|
||||||
config_entry_oauth2_flow.async_register_implementation(
|
config_entry_oauth2_flow.async_register_implementation(
|
||||||
hass, TEST_DOMAIN, MockOAuth2Implementation()
|
hass, TEST_DOMAIN, MockOAuth2Implementation()
|
||||||
|
@ -163,7 +169,9 @@ async def test_abort_discovered_multiple(hass, flow_handler, local_impl):
|
||||||
|
|
||||||
async def test_abort_discovered_existing_entries(hass, flow_handler, local_impl):
|
async def test_abort_discovered_existing_entries(hass, flow_handler, local_impl):
|
||||||
"""Test if abort discovery when entries exists."""
|
"""Test if abort discovery when entries exists."""
|
||||||
hass.config.api.base_url = "https://example.com"
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "https://example.com"},
|
||||||
|
)
|
||||||
flow_handler.async_register_implementation(hass, local_impl)
|
flow_handler.async_register_implementation(hass, local_impl)
|
||||||
config_entry_oauth2_flow.async_register_implementation(
|
config_entry_oauth2_flow.async_register_implementation(
|
||||||
hass, TEST_DOMAIN, MockOAuth2Implementation()
|
hass, TEST_DOMAIN, MockOAuth2Implementation()
|
||||||
|
@ -184,7 +192,10 @@ async def test_full_flow(
|
||||||
hass, flow_handler, local_impl, aiohttp_client, aioclient_mock
|
hass, flow_handler, local_impl, aiohttp_client, aioclient_mock
|
||||||
):
|
):
|
||||||
"""Check full flow."""
|
"""Check full flow."""
|
||||||
hass.config.api.base_url = "https://example.com"
|
await async_process_ha_core_config(
|
||||||
|
hass, {"external_url": "https://example.com"},
|
||||||
|
)
|
||||||
|
|
||||||
flow_handler.async_register_implementation(hass, local_impl)
|
flow_handler.async_register_implementation(hass, local_impl)
|
||||||
config_entry_oauth2_flow.async_register_implementation(
|
config_entry_oauth2_flow.async_register_implementation(
|
||||||
hass, TEST_DOMAIN, MockOAuth2Implementation()
|
hass, TEST_DOMAIN, MockOAuth2Implementation()
|
||||||
|
|
|
@ -119,7 +119,7 @@ async def test_get_url_internal_fallback(hass: HomeAssistant):
|
||||||
assert hass.config.internal_url is None
|
assert hass.config.internal_url is None
|
||||||
|
|
||||||
hass.config.api = Mock(
|
hass.config.api = Mock(
|
||||||
use_ssl=False, port=8123, base_url=None, local_ip="192.168.123.123"
|
use_ssl=False, port=8123, deprecated_base_url=None, local_ip="192.168.123.123"
|
||||||
)
|
)
|
||||||
assert _async_get_internal_url(hass) == "http://192.168.123.123:8123"
|
assert _async_get_internal_url(hass) == "http://192.168.123.123:8123"
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ async def test_get_url_internal_fallback(hass: HomeAssistant):
|
||||||
_async_get_internal_url(hass, require_ssl=True)
|
_async_get_internal_url(hass, require_ssl=True)
|
||||||
|
|
||||||
hass.config.api = Mock(
|
hass.config.api = Mock(
|
||||||
use_ssl=False, port=80, base_url=None, local_ip="192.168.123.123"
|
use_ssl=False, port=80, deprecated_base_url=None, local_ip="192.168.123.123"
|
||||||
)
|
)
|
||||||
assert _async_get_internal_url(hass) == "http://192.168.123.123"
|
assert _async_get_internal_url(hass) == "http://192.168.123.123"
|
||||||
assert (
|
assert (
|
||||||
|
@ -147,7 +147,7 @@ async def test_get_url_internal_fallback(hass: HomeAssistant):
|
||||||
with pytest.raises(NoURLAvailableError):
|
with pytest.raises(NoURLAvailableError):
|
||||||
_async_get_internal_url(hass, require_ssl=True)
|
_async_get_internal_url(hass, require_ssl=True)
|
||||||
|
|
||||||
hass.config.api = Mock(use_ssl=True, port=443, base_url=None)
|
hass.config.api = Mock(use_ssl=True, port=443, deprecated_base_url=None)
|
||||||
with pytest.raises(NoURLAvailableError):
|
with pytest.raises(NoURLAvailableError):
|
||||||
_async_get_internal_url(hass)
|
_async_get_internal_url(hass)
|
||||||
|
|
||||||
|
@ -161,7 +161,9 @@ async def test_get_url_internal_fallback(hass: HomeAssistant):
|
||||||
_async_get_internal_url(hass, require_ssl=True)
|
_async_get_internal_url(hass, require_ssl=True)
|
||||||
|
|
||||||
# Do no accept any local loopback address as fallback
|
# Do no accept any local loopback address as fallback
|
||||||
hass.config.api = Mock(use_ssl=False, port=80, base_url=None, local_ip="127.0.0.1")
|
hass.config.api = Mock(
|
||||||
|
use_ssl=False, port=80, deprecated_base_url=None, local_ip="127.0.0.1"
|
||||||
|
)
|
||||||
with pytest.raises(NoURLAvailableError):
|
with pytest.raises(NoURLAvailableError):
|
||||||
_async_get_internal_url(hass)
|
_async_get_internal_url(hass)
|
||||||
|
|
||||||
|
@ -367,7 +369,7 @@ async def test_get_url(hass: HomeAssistant):
|
||||||
async_get_url(hass)
|
async_get_url(hass)
|
||||||
|
|
||||||
hass.config.api = Mock(
|
hass.config.api = Mock(
|
||||||
use_ssl=False, port=8123, base_url=None, local_ip="192.168.123.123"
|
use_ssl=False, port=8123, deprecated_base_url=None, local_ip="192.168.123.123"
|
||||||
)
|
)
|
||||||
assert async_get_url(hass) == "http://192.168.123.123:8123"
|
assert async_get_url(hass) == "http://192.168.123.123:8123"
|
||||||
assert async_get_url(hass, prefer_external=True) == "http://192.168.123.123:8123"
|
assert async_get_url(hass, prefer_external=True) == "http://192.168.123.123:8123"
|
||||||
|
@ -409,7 +411,7 @@ async def test_get_url(hass: HomeAssistant):
|
||||||
async def test_get_deprecated_base_url_internal(hass: HomeAssistant):
|
async def test_get_deprecated_base_url_internal(hass: HomeAssistant):
|
||||||
"""Test getting an internal instance URL from the deprecated base_url."""
|
"""Test getting an internal instance URL from the deprecated base_url."""
|
||||||
# Test with SSL local URL
|
# Test with SSL local URL
|
||||||
hass.config.api = Mock(base_url="https://example.local")
|
hass.config.api = Mock(deprecated_base_url="https://example.local")
|
||||||
assert (
|
assert (
|
||||||
_async_get_deprecated_base_url(hass, internal=True) == "https://example.local"
|
_async_get_deprecated_base_url(hass, internal=True) == "https://example.local"
|
||||||
)
|
)
|
||||||
|
@ -427,7 +429,7 @@ async def test_get_deprecated_base_url_internal(hass: HomeAssistant):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test with no SSL, local IP URL
|
# Test with no SSL, local IP URL
|
||||||
hass.config.api = Mock(base_url="http://10.10.10.10:8123")
|
hass.config.api = Mock(deprecated_base_url="http://10.10.10.10:8123")
|
||||||
assert (
|
assert (
|
||||||
_async_get_deprecated_base_url(hass, internal=True) == "http://10.10.10.10:8123"
|
_async_get_deprecated_base_url(hass, internal=True) == "http://10.10.10.10:8123"
|
||||||
)
|
)
|
||||||
|
@ -442,7 +444,7 @@ async def test_get_deprecated_base_url_internal(hass: HomeAssistant):
|
||||||
_async_get_deprecated_base_url(hass, internal=True, require_standard_port=True)
|
_async_get_deprecated_base_url(hass, internal=True, require_standard_port=True)
|
||||||
|
|
||||||
# Test with SSL, local IP URL
|
# Test with SSL, local IP URL
|
||||||
hass.config.api = Mock(base_url="https://10.10.10.10")
|
hass.config.api = Mock(deprecated_base_url="https://10.10.10.10")
|
||||||
assert _async_get_deprecated_base_url(hass, internal=True) == "https://10.10.10.10"
|
assert _async_get_deprecated_base_url(hass, internal=True) == "https://10.10.10.10"
|
||||||
assert (
|
assert (
|
||||||
_async_get_deprecated_base_url(hass, internal=True, require_ssl=True)
|
_async_get_deprecated_base_url(hass, internal=True, require_ssl=True)
|
||||||
|
@ -454,7 +456,7 @@ async def test_get_deprecated_base_url_internal(hass: HomeAssistant):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test external URL
|
# Test external URL
|
||||||
hass.config.api = Mock(base_url="https://example.com")
|
hass.config.api = Mock(deprecated_base_url="https://example.com")
|
||||||
with pytest.raises(NoURLAvailableError):
|
with pytest.raises(NoURLAvailableError):
|
||||||
_async_get_deprecated_base_url(hass, internal=True)
|
_async_get_deprecated_base_url(hass, internal=True)
|
||||||
|
|
||||||
|
@ -468,7 +470,7 @@ async def test_get_deprecated_base_url_internal(hass: HomeAssistant):
|
||||||
_async_get_deprecated_base_url(hass, internal=True, allow_ip=False)
|
_async_get_deprecated_base_url(hass, internal=True, allow_ip=False)
|
||||||
|
|
||||||
# Test with loopback
|
# Test with loopback
|
||||||
hass.config.api = Mock(base_url="https://127.0.0.42")
|
hass.config.api = Mock(deprecated_base_url="https://127.0.0.42")
|
||||||
with pytest.raises(NoURLAvailableError):
|
with pytest.raises(NoURLAvailableError):
|
||||||
assert _async_get_deprecated_base_url(hass, internal=True)
|
assert _async_get_deprecated_base_url(hass, internal=True)
|
||||||
|
|
||||||
|
@ -485,7 +487,7 @@ async def test_get_deprecated_base_url_internal(hass: HomeAssistant):
|
||||||
async def test_get_deprecated_base_url_external(hass: HomeAssistant):
|
async def test_get_deprecated_base_url_external(hass: HomeAssistant):
|
||||||
"""Test getting an external instance URL from the deprecated base_url."""
|
"""Test getting an external instance URL from the deprecated base_url."""
|
||||||
# Test with SSL and external domain on standard port
|
# Test with SSL and external domain on standard port
|
||||||
hass.config.api = Mock(base_url="https://example.com:443/")
|
hass.config.api = Mock(deprecated_base_url="https://example.com:443/")
|
||||||
assert _async_get_deprecated_base_url(hass) == "https://example.com"
|
assert _async_get_deprecated_base_url(hass) == "https://example.com"
|
||||||
assert (
|
assert (
|
||||||
_async_get_deprecated_base_url(hass, require_ssl=True) == "https://example.com"
|
_async_get_deprecated_base_url(hass, require_ssl=True) == "https://example.com"
|
||||||
|
@ -496,7 +498,7 @@ async def test_get_deprecated_base_url_external(hass: HomeAssistant):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test without SSL and external domain on non-standard port
|
# Test without SSL and external domain on non-standard port
|
||||||
hass.config.api = Mock(base_url="http://example.com:8123/")
|
hass.config.api = Mock(deprecated_base_url="http://example.com:8123/")
|
||||||
assert _async_get_deprecated_base_url(hass) == "http://example.com:8123"
|
assert _async_get_deprecated_base_url(hass) == "http://example.com:8123"
|
||||||
|
|
||||||
with pytest.raises(NoURLAvailableError):
|
with pytest.raises(NoURLAvailableError):
|
||||||
|
@ -506,7 +508,7 @@ async def test_get_deprecated_base_url_external(hass: HomeAssistant):
|
||||||
_async_get_deprecated_base_url(hass, require_standard_port=True)
|
_async_get_deprecated_base_url(hass, require_standard_port=True)
|
||||||
|
|
||||||
# Test SSL on external IP
|
# Test SSL on external IP
|
||||||
hass.config.api = Mock(base_url="https://1.1.1.1")
|
hass.config.api = Mock(deprecated_base_url="https://1.1.1.1")
|
||||||
assert _async_get_deprecated_base_url(hass) == "https://1.1.1.1"
|
assert _async_get_deprecated_base_url(hass) == "https://1.1.1.1"
|
||||||
assert _async_get_deprecated_base_url(hass, require_ssl=True) == "https://1.1.1.1"
|
assert _async_get_deprecated_base_url(hass, require_ssl=True) == "https://1.1.1.1"
|
||||||
assert (
|
assert (
|
||||||
|
@ -518,7 +520,7 @@ async def test_get_deprecated_base_url_external(hass: HomeAssistant):
|
||||||
_async_get_deprecated_base_url(hass, allow_ip=False)
|
_async_get_deprecated_base_url(hass, allow_ip=False)
|
||||||
|
|
||||||
# Test with private IP
|
# Test with private IP
|
||||||
hass.config.api = Mock(base_url="https://10.10.10.10")
|
hass.config.api = Mock(deprecated_base_url="https://10.10.10.10")
|
||||||
with pytest.raises(NoURLAvailableError):
|
with pytest.raises(NoURLAvailableError):
|
||||||
assert _async_get_deprecated_base_url(hass)
|
assert _async_get_deprecated_base_url(hass)
|
||||||
|
|
||||||
|
@ -532,7 +534,7 @@ async def test_get_deprecated_base_url_external(hass: HomeAssistant):
|
||||||
_async_get_deprecated_base_url(hass, require_standard_port=True)
|
_async_get_deprecated_base_url(hass, require_standard_port=True)
|
||||||
|
|
||||||
# Test with local domain
|
# Test with local domain
|
||||||
hass.config.api = Mock(base_url="https://example.local")
|
hass.config.api = Mock(deprecated_base_url="https://example.local")
|
||||||
with pytest.raises(NoURLAvailableError):
|
with pytest.raises(NoURLAvailableError):
|
||||||
assert _async_get_deprecated_base_url(hass)
|
assert _async_get_deprecated_base_url(hass)
|
||||||
|
|
||||||
|
@ -546,7 +548,7 @@ async def test_get_deprecated_base_url_external(hass: HomeAssistant):
|
||||||
_async_get_deprecated_base_url(hass, require_standard_port=True)
|
_async_get_deprecated_base_url(hass, require_standard_port=True)
|
||||||
|
|
||||||
# Test with loopback
|
# Test with loopback
|
||||||
hass.config.api = Mock(base_url="https://127.0.0.42")
|
hass.config.api = Mock(deprecated_base_url="https://127.0.0.42")
|
||||||
with pytest.raises(NoURLAvailableError):
|
with pytest.raises(NoURLAvailableError):
|
||||||
assert _async_get_deprecated_base_url(hass)
|
assert _async_get_deprecated_base_url(hass)
|
||||||
|
|
||||||
|
@ -563,7 +565,7 @@ async def test_get_deprecated_base_url_external(hass: HomeAssistant):
|
||||||
async def test_get_internal_url_with_base_url_fallback(hass: HomeAssistant):
|
async def test_get_internal_url_with_base_url_fallback(hass: HomeAssistant):
|
||||||
"""Test getting an internal instance URL with the deprecated base_url fallback."""
|
"""Test getting an internal instance URL with the deprecated base_url fallback."""
|
||||||
hass.config.api = Mock(
|
hass.config.api = Mock(
|
||||||
use_ssl=False, port=8123, base_url=None, local_ip="192.168.123.123"
|
use_ssl=False, port=8123, deprecated_base_url=None, local_ip="192.168.123.123"
|
||||||
)
|
)
|
||||||
assert hass.config.internal_url is None
|
assert hass.config.internal_url is None
|
||||||
assert _async_get_internal_url(hass) == "http://192.168.123.123:8123"
|
assert _async_get_internal_url(hass) == "http://192.168.123.123:8123"
|
||||||
|
@ -578,7 +580,9 @@ async def test_get_internal_url_with_base_url_fallback(hass: HomeAssistant):
|
||||||
_async_get_internal_url(hass, require_ssl=True)
|
_async_get_internal_url(hass, require_ssl=True)
|
||||||
|
|
||||||
# Add base_url
|
# Add base_url
|
||||||
hass.config.api = Mock(use_ssl=False, port=8123, base_url="https://example.local")
|
hass.config.api = Mock(
|
||||||
|
use_ssl=False, port=8123, deprecated_base_url="https://example.local"
|
||||||
|
)
|
||||||
assert _async_get_internal_url(hass) == "https://example.local"
|
assert _async_get_internal_url(hass) == "https://example.local"
|
||||||
assert _async_get_internal_url(hass, allow_ip=False) == "https://example.local"
|
assert _async_get_internal_url(hass, allow_ip=False) == "https://example.local"
|
||||||
assert (
|
assert (
|
||||||
|
@ -626,14 +630,14 @@ async def test_get_internal_url_with_base_url_fallback(hass: HomeAssistant):
|
||||||
|
|
||||||
async def test_get_external_url_with_base_url_fallback(hass: HomeAssistant):
|
async def test_get_external_url_with_base_url_fallback(hass: HomeAssistant):
|
||||||
"""Test getting an external instance URL with the deprecated base_url fallback."""
|
"""Test getting an external instance URL with the deprecated base_url fallback."""
|
||||||
hass.config.api = Mock(use_ssl=False, port=8123, base_url=None)
|
hass.config.api = Mock(use_ssl=False, port=8123, deprecated_base_url=None)
|
||||||
assert hass.config.internal_url is None
|
assert hass.config.internal_url is None
|
||||||
|
|
||||||
with pytest.raises(NoURLAvailableError):
|
with pytest.raises(NoURLAvailableError):
|
||||||
_async_get_external_url(hass)
|
_async_get_external_url(hass)
|
||||||
|
|
||||||
# Test with SSL and external domain on standard port
|
# Test with SSL and external domain on standard port
|
||||||
hass.config.api = Mock(base_url="https://example.com:443/")
|
hass.config.api = Mock(deprecated_base_url="https://example.com:443/")
|
||||||
assert _async_get_external_url(hass) == "https://example.com"
|
assert _async_get_external_url(hass) == "https://example.com"
|
||||||
assert _async_get_external_url(hass, allow_ip=False) == "https://example.com"
|
assert _async_get_external_url(hass, allow_ip=False) == "https://example.com"
|
||||||
assert _async_get_external_url(hass, require_ssl=True) == "https://example.com"
|
assert _async_get_external_url(hass, require_ssl=True) == "https://example.com"
|
||||||
|
|
|
@ -1310,12 +1310,12 @@ async def test_migration_base_url(hass, hass_storage):
|
||||||
assert mock_listen.mock_calls[0][1][0] == EVENT_HOMEASSISTANT_START
|
assert mock_listen.mock_calls[0][1][0] == EVENT_HOMEASSISTANT_START
|
||||||
|
|
||||||
# External
|
# External
|
||||||
hass.config.api = Mock(base_url="https://loaded-example.com")
|
hass.config.api = Mock(deprecated_base_url="https://loaded-example.com")
|
||||||
await mock_listen.mock_calls[0][1][1](None)
|
await mock_listen.mock_calls[0][1][1](None)
|
||||||
assert config.external_url == "https://loaded-example.com"
|
assert config.external_url == "https://loaded-example.com"
|
||||||
|
|
||||||
# Internal
|
# Internal
|
||||||
for internal in ("http://hass.local", "http://192.168.1.100:8123"):
|
for internal in ("http://hass.local", "http://192.168.1.100:8123"):
|
||||||
hass.config.api = Mock(base_url=internal)
|
hass.config.api = Mock(deprecated_base_url=internal)
|
||||||
await mock_listen.mock_calls[0][1][1](None)
|
await mock_listen.mock_calls[0][1][1](None)
|
||||||
assert config.internal_url == internal
|
assert config.internal_url == internal
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue