Detect use of deprecated base_url (#35353)
* Detect use of deprecated base_url * Update get_url helper * Update core migration * Migrate all testspull/35381/head
parent
1be41b9de8
commit
e56dd8ed50
|
@ -3,6 +3,7 @@ from ipaddress import ip_network
|
|||
import logging
|
||||
import os
|
||||
import ssl
|
||||
from traceback import extract_stack
|
||||
from typing import Optional, cast
|
||||
|
||||
from aiohttp import web
|
||||
|
@ -119,14 +120,66 @@ class ApiConfig:
|
|||
|
||||
host = host.rstrip("/")
|
||||
if host.startswith(("http://", "https://")):
|
||||
self.base_url = host
|
||||
self.deprecated_base_url = host
|
||||
elif use_ssl:
|
||||
self.base_url = f"https://{host}"
|
||||
self.deprecated_base_url = f"https://{host}"
|
||||
else:
|
||||
self.base_url = f"http://{host}"
|
||||
self.deprecated_base_url = f"http://{host}"
|
||||
|
||||
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):
|
||||
|
|
|
@ -1463,7 +1463,7 @@ class Config:
|
|||
if self.hass.config.api is None:
|
||||
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
|
||||
if str(base_url.host).endswith(".local") or (
|
||||
|
|
|
@ -195,10 +195,10 @@ def _async_get_deprecated_base_url(
|
|||
require_standard_port: bool = False,
|
||||
) -> str:
|
||||
"""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
|
||||
|
||||
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
|
||||
if (
|
||||
(allow_ip or not is_ip_address(str(base_url.host)))
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
"""Test 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
|
||||
|
||||
|
||||
async def test_service_show_view(hass):
|
||||
"""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())
|
||||
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):
|
||||
"""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())
|
||||
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):
|
||||
"""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")
|
||||
|
||||
await home_assistant_cast.async_setup_ha_cast(hass, MockConfigEntry())
|
||||
|
|
|
@ -6,11 +6,10 @@ import pytest
|
|||
|
||||
from homeassistant import data_entry_flow
|
||||
from homeassistant.components import dialogflow, intent_script
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.async_mock import Mock
|
||||
|
||||
SESSION_ID = "a9b84cec-46b6-484e-8f31-f65dba03ae6d"
|
||||
INTENT_ID = "c6a74079-a8f0-46cd-b372-5a934d23591c"
|
||||
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(
|
||||
"dialogflow", context={"source": "user"}
|
||||
)
|
||||
|
|
|
@ -4,6 +4,7 @@ import pytest
|
|||
from homeassistant import data_entry_flow
|
||||
from homeassistant.components import zone
|
||||
from homeassistant.components.geofency import CONF_MOBILE_BEACONS, DOMAIN
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.const import (
|
||||
HTTP_OK,
|
||||
HTTP_UNPROCESSABLE_ENTITY,
|
||||
|
@ -14,7 +15,7 @@ from homeassistant.setup import async_setup_component
|
|||
from homeassistant.util import slugify
|
||||
|
||||
# pylint: disable=redefined-outer-name
|
||||
from tests.async_mock import Mock, patch
|
||||
from tests.async_mock import patch
|
||||
|
||||
HOME_LATITUDE = 37.239622
|
||||
HOME_LONGITUDE = -115.815811
|
||||
|
@ -148,7 +149,9 @@ async def setup_zones(loop, hass):
|
|||
@pytest.fixture
|
||||
async def webhook_id(hass, geofency_client):
|
||||
"""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(
|
||||
DOMAIN, context={"source": "user"}
|
||||
)
|
||||
|
|
|
@ -8,6 +8,7 @@ from homeassistant.components.google_assistant.const import ( # noqa: F401
|
|||
EVENT_COMMAND_RECEIVED,
|
||||
NOT_EXPOSE_LOCAL,
|
||||
)
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt
|
||||
|
||||
|
@ -24,7 +25,11 @@ from tests.common import (
|
|||
async def test_google_entity_sync_serialize_with_local_sdk(hass):
|
||||
"""Test sync serialize attributes of a GoogleEntity."""
|
||||
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)
|
||||
config = MockConfig(
|
||||
hass=hass,
|
||||
|
|
|
@ -5,6 +5,7 @@ from homeassistant import data_entry_flow
|
|||
from homeassistant.components import gpslogger, zone
|
||||
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
|
||||
from homeassistant.components.gpslogger import DOMAIN, TRACKER_UPDATE
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.const import (
|
||||
HTTP_OK,
|
||||
HTTP_UNPROCESSABLE_ENTITY,
|
||||
|
@ -14,7 +15,7 @@ from homeassistant.const import (
|
|||
from homeassistant.helpers.dispatcher import DATA_DISPATCHER
|
||||
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_LONGITUDE = -115.815811
|
||||
|
@ -62,7 +63,9 @@ async def setup_zones(loop, hass):
|
|||
@pytest.fixture
|
||||
async def webhook_id(hass, gpslogger_client):
|
||||
"""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(
|
||||
DOMAIN, context={"source": "user"}
|
||||
)
|
||||
|
|
|
@ -3,11 +3,13 @@ from ipaddress import ip_network
|
|||
import logging
|
||||
import unittest
|
||||
|
||||
import pytest
|
||||
|
||||
import homeassistant.components.http as http
|
||||
from homeassistant.setup import async_setup_component
|
||||
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):
|
||||
|
@ -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])
|
||||
|
||||
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.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
|
||||
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.helpers.dispatcher import DATA_DISPATCHER
|
||||
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
|
||||
|
||||
|
@ -33,7 +34,9 @@ async def locative_client(loop, hass, hass_client):
|
|||
@pytest.fixture
|
||||
async def webhook_id(hass, locative_client):
|
||||
"""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(
|
||||
"locative", context={"source": "user"}
|
||||
)
|
||||
|
|
|
@ -6,12 +6,11 @@ import pytest
|
|||
|
||||
from homeassistant import data_entry_flow
|
||||
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.core import callback
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.async_mock import Mock
|
||||
|
||||
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"}},
|
||||
)
|
||||
|
||||
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(
|
||||
"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."""
|
||||
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(
|
||||
"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.setup import async_setup_component
|
||||
|
||||
from tests.async_mock import Mock, patch
|
||||
from tests.async_mock import patch
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
CONF_WEBHOOK_URL = "webhook_url"
|
||||
|
@ -47,9 +47,11 @@ def mock_not_supports_encryption():
|
|||
yield
|
||||
|
||||
|
||||
def init_config_flow(hass):
|
||||
async def init_config_flow(hass):
|
||||
"""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.hass = hass
|
||||
return flow
|
||||
|
@ -57,7 +59,7 @@ def init_config_flow(hass):
|
|||
|
||||
async def test_user(hass, webhook_id, secret):
|
||||
"""Test user step."""
|
||||
flow = init_config_flow(hass)
|
||||
flow = await init_config_flow(hass)
|
||||
|
||||
result = await flow.async_step_user()
|
||||
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):
|
||||
"""Test import step."""
|
||||
flow = init_config_flow(hass)
|
||||
flow = await init_config_flow(hass)
|
||||
|
||||
result = await flow.async_step_import({})
|
||||
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):
|
||||
"""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)
|
||||
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):
|
||||
"""Test user step."""
|
||||
flow = init_config_flow(hass)
|
||||
flow = await init_config_flow(hass)
|
||||
|
||||
result = await flow.async_step_user({})
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
|
|
|
@ -37,6 +37,7 @@ from homeassistant.components.smartthings.const import (
|
|||
STORAGE_KEY,
|
||||
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.const import CONF_ACCESS_TOKEN, CONF_WEBHOOK_ID
|
||||
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):
|
||||
"""Load the SmartThing component."""
|
||||
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", {})
|
||||
hass.config.api.base_url = "https://test.local"
|
||||
|
||||
|
||||
def _create_location():
|
||||
|
@ -97,7 +100,7 @@ def locations_fixture(location):
|
|||
|
||||
|
||||
@pytest.fixture(name="app")
|
||||
def app_fixture(hass, config_file):
|
||||
async def app_fixture(hass, config_file):
|
||||
"""Fixture for a single app."""
|
||||
app = Mock(AppEntity)
|
||||
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.classifications = [CLASSIFICATION_AUTOMATION]
|
||||
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.webhook_target_url = webhook.async_generate_url(
|
||||
hass, hass.data[DOMAIN][CONF_WEBHOOK_ID]
|
||||
|
|
|
@ -15,6 +15,7 @@ from homeassistant.components.smartthings.const import (
|
|||
CONF_OAUTH_CLIENT_SECRET,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.const import (
|
||||
CONF_ACCESS_TOKEN,
|
||||
HTTP_FORBIDDEN,
|
||||
|
@ -417,9 +418,10 @@ async def test_entry_created_with_cloudhook(
|
|||
|
||||
async def test_invalid_webhook_aborts(hass):
|
||||
"""Test flow aborts if webhook is invalid."""
|
||||
hass.config.api.base_url = "http://0.0.0.0"
|
||||
|
||||
# Webhook confirmation shown
|
||||
await async_process_ha_core_config(
|
||||
hass, {"external_url": "http://example.local:8123"},
|
||||
)
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "user"}
|
||||
)
|
||||
|
|
|
@ -16,6 +16,7 @@ from homeassistant.components.smartthings.const import (
|
|||
SIGNAL_SMARTTHINGS_UPDATE,
|
||||
SUPPORTED_PLATFORMS,
|
||||
)
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.const import HTTP_FORBIDDEN, HTTP_INTERNAL_SERVER_ERROR
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
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
|
||||
):
|
||||
"""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)
|
||||
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."""
|
||||
config_entry.add_to_hass(hass)
|
||||
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.installed_app.return_value = installed_app
|
||||
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.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
|
||||
from homeassistant.components.traccar import DOMAIN, TRACKER_UPDATE
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.const import (
|
||||
HTTP_OK,
|
||||
HTTP_UNPROCESSABLE_ENTITY,
|
||||
|
@ -14,7 +15,7 @@ from homeassistant.const import (
|
|||
from homeassistant.helpers.dispatcher import DATA_DISPATCHER
|
||||
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_LONGITUDE = -115.815811
|
||||
|
@ -23,7 +24,6 @@ HOME_LONGITUDE = -115.815811
|
|||
@pytest.fixture(autouse=True)
|
||||
def mock_dev_track(mock_device_tracker_conf):
|
||||
"""Mock device tracker config loading."""
|
||||
pass
|
||||
|
||||
|
||||
@pytest.fixture(name="client")
|
||||
|
@ -60,7 +60,9 @@ async def setup_zones(loop, hass):
|
|||
@pytest.fixture(name="webhook_id")
|
||||
async def webhook_id_fixture(hass, client):
|
||||
"""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(
|
||||
DOMAIN, context={"source": "user"}
|
||||
)
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
"""Test the webhook component."""
|
||||
import pytest
|
||||
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.async_mock import Mock
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
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):
|
||||
"""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")
|
||||
|
||||
assert url == "https://example.com/api/webhook/some_id"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import pytest
|
||||
|
||||
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 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.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={})
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
|
|
|
@ -6,6 +6,7 @@ import time
|
|||
import pytest
|
||||
|
||||
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 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):
|
||||
"""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)
|
||||
config_entry_oauth2_flow.async_register_implementation(
|
||||
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):
|
||||
"""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)
|
||||
config_entry_oauth2_flow.async_register_implementation(
|
||||
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):
|
||||
"""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)
|
||||
config_entry_oauth2_flow.async_register_implementation(
|
||||
hass, TEST_DOMAIN, MockOAuth2Implementation()
|
||||
|
@ -184,7 +192,10 @@ async def test_full_flow(
|
|||
hass, flow_handler, local_impl, aiohttp_client, aioclient_mock
|
||||
):
|
||||
"""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)
|
||||
config_entry_oauth2_flow.async_register_implementation(
|
||||
hass, TEST_DOMAIN, MockOAuth2Implementation()
|
||||
|
|
|
@ -119,7 +119,7 @@ async def test_get_url_internal_fallback(hass: HomeAssistant):
|
|||
assert hass.config.internal_url is None
|
||||
|
||||
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"
|
||||
|
||||
|
@ -133,7 +133,7 @@ async def test_get_url_internal_fallback(hass: HomeAssistant):
|
|||
_async_get_internal_url(hass, require_ssl=True)
|
||||
|
||||
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 (
|
||||
|
@ -147,7 +147,7 @@ async def test_get_url_internal_fallback(hass: HomeAssistant):
|
|||
with pytest.raises(NoURLAvailableError):
|
||||
_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):
|
||||
_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)
|
||||
|
||||
# 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):
|
||||
_async_get_internal_url(hass)
|
||||
|
||||
|
@ -367,7 +369,7 @@ async def test_get_url(hass: HomeAssistant):
|
|||
async_get_url(hass)
|
||||
|
||||
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, 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):
|
||||
"""Test getting an internal instance URL from the deprecated base_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 (
|
||||
_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
|
||||
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 (
|
||||
_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)
|
||||
|
||||
# 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, require_ssl=True)
|
||||
|
@ -454,7 +456,7 @@ async def test_get_deprecated_base_url_internal(hass: HomeAssistant):
|
|||
)
|
||||
|
||||
# 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):
|
||||
_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)
|
||||
|
||||
# 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):
|
||||
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):
|
||||
"""Test getting an external instance URL from the deprecated base_url."""
|
||||
# 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, 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
|
||||
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"
|
||||
|
||||
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)
|
||||
|
||||
# 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, require_ssl=True) == "https://1.1.1.1"
|
||||
assert (
|
||||
|
@ -518,7 +520,7 @@ async def test_get_deprecated_base_url_external(hass: HomeAssistant):
|
|||
_async_get_deprecated_base_url(hass, allow_ip=False)
|
||||
|
||||
# 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):
|
||||
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)
|
||||
|
||||
# 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):
|
||||
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)
|
||||
|
||||
# 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):
|
||||
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):
|
||||
"""Test getting an internal instance URL with the deprecated base_url fallback."""
|
||||
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 _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)
|
||||
|
||||
# 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, allow_ip=False) == "https://example.local"
|
||||
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):
|
||||
"""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
|
||||
|
||||
with pytest.raises(NoURLAvailableError):
|
||||
_async_get_external_url(hass)
|
||||
|
||||
# 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, allow_ip=False) == "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
|
||||
|
||||
# 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)
|
||||
assert config.external_url == "https://loaded-example.com"
|
||||
|
||||
# Internal
|
||||
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)
|
||||
assert config.internal_url == internal
|
||||
|
|
Loading…
Reference in New Issue