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:
Franck Nijhof 2020-05-08 17:52:32 +02:00 committed by GitHub
parent 1be41b9de8
commit e56dd8ed50
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 308 additions and 73 deletions

View file

@ -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):

View file

@ -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 (

View file

@ -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)))

View file

@ -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())

View file

@ -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"}
) )

View file

@ -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"}
) )

View file

@ -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,

View file

@ -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"}
) )

View file

@ -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
)

View file

@ -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"}
) )

View file

@ -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"}
) )

View file

@ -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

View file

@ -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]

View file

@ -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"}
) )

View file

@ -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]

View file

@ -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"}
) )

View file

@ -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"

View file

@ -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

View file

@ -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()

View file

@ -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"

View file

@ -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