1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 12:59:34 +00:00

Remove dependency on async_setup from mqtt integration (#87987)

* Remove async_setup from mqtt integration

* Final update common tests

* Related tests init

* Related tests diagnostics

* Related tests config_flow

* Cleanup and correct test

* Keep websockets_api commands in async_setup
This commit is contained in:
Jan Bouwhuis
2023-03-28 09:37:07 +02:00
committed by GitHub
parent 5e03272821
commit 14ffda9758
7 changed files with 153 additions and 428 deletions

View File

@@ -5,18 +5,15 @@ import copy
from datetime import datetime, timedelta
from functools import partial
import json
from pathlib import Path
import ssl
from typing import Any, TypedDict
from unittest.mock import ANY, MagicMock, call, mock_open, patch
import pytest
import voluptuous as vol
import yaml
from homeassistant import config as module_hass_config
from homeassistant.components import mqtt
from homeassistant.components.mqtt import CONFIG_SCHEMA, debug_info
from homeassistant.components.mqtt import debug_info
from homeassistant.components.mqtt.client import EnsureJobAfterCooldown
from homeassistant.components.mqtt.mixins import MQTT_ENTITY_DEVICE_INFO_SCHEMA
from homeassistant.components.mqtt.models import MessageCallbackType, ReceiveMessage
@@ -40,10 +37,7 @@ from homeassistant.helpers.typing import ConfigType
from homeassistant.setup import async_setup_component
from homeassistant.util.dt import utcnow
from .test_common import (
help_test_entry_reload_with_new_config,
help_test_validate_platform_config,
)
from .test_common import help_test_validate_platform_config
from tests.common import (
MockConfigEntry,
@@ -1529,18 +1523,17 @@ async def test_subscribed_at_highest_qos(
async def test_reload_entry_with_restored_subscriptions(
hass: HomeAssistant,
tmp_path: Path,
mqtt_client_mock: MqttMockPahoClient,
record_calls: MessageCallbackType,
calls: list[ReceiveMessage],
) -> None:
"""Test reloading the config entry with with subscriptions restored."""
# Setup the MQTT entry
entry = MockConfigEntry(domain=mqtt.DOMAIN, data={mqtt.CONF_BROKER: "test-broker"})
entry.add_to_hass(hass)
mqtt_client_mock.connect.return_value = 0
assert await mqtt.async_setup_entry(hass, entry)
await hass.async_block_till_done()
with patch("homeassistant.config.load_yaml_config_file", return_value={}):
await entry.async_setup(hass)
await mqtt.async_subscribe(hass, "test-topic", record_calls)
await mqtt.async_subscribe(hass, "wild/+/card", record_calls)
@@ -1557,10 +1550,10 @@ async def test_reload_entry_with_restored_subscriptions(
calls.clear()
# Reload the entry
config_yaml_new = {}
await help_test_entry_reload_with_new_config(hass, tmp_path, config_yaml_new)
await hass.async_block_till_done()
with patch("homeassistant.config.load_yaml_config_file", return_value={}):
assert await hass.config_entries.async_reload(entry.entry_id)
assert entry.state is ConfigEntryState.LOADED
await hass.async_block_till_done()
async_fire_mqtt_message(hass, "test-topic", "test-payload2")
async_fire_mqtt_message(hass, "wild/any/card", "wild-card-payload2")
@@ -1574,10 +1567,10 @@ async def test_reload_entry_with_restored_subscriptions(
calls.clear()
# Reload the entry again
config_yaml_new = {}
await help_test_entry_reload_with_new_config(hass, tmp_path, config_yaml_new)
await hass.async_block_till_done()
with patch("homeassistant.config.load_yaml_config_file", return_value={}):
assert await hass.config_entries.async_reload(entry.entry_id)
assert entry.state is ConfigEntryState.LOADED
await hass.async_block_till_done()
async_fire_mqtt_message(hass, "test-topic", "test-payload3")
async_fire_mqtt_message(hass, "wild/any/card", "wild-card-payload3")
@@ -1804,55 +1797,6 @@ async def test_handle_message_callback(
assert callbacks[0].payload == "test-payload"
async def test_setup_override_configuration(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture, tmp_path: Path
) -> None:
"""Test override setup from configuration entry."""
calls_username_password_set = []
def mock_usename_password_set(username: str, password: str) -> None:
calls_username_password_set.append((username, password))
# Mock password setup from config
config = {
"username": "someuser",
"password": "someyamlconfiguredpassword",
"protocol": "3.1",
}
new_yaml_config_file = tmp_path / "configuration.yaml"
new_yaml_config = yaml.dump({mqtt.DOMAIN: config})
new_yaml_config_file.write_text(new_yaml_config)
assert new_yaml_config_file.read_text() == new_yaml_config
with patch.object(module_hass_config, "YAML_CONFIG_FILE", new_yaml_config_file):
# Mock config entry
entry = MockConfigEntry(
domain=mqtt.DOMAIN,
data={mqtt.CONF_BROKER: "test-broker", "password": "somepassword"},
)
entry.add_to_hass(hass)
with patch("paho.mqtt.client.Client") as mock_client:
mock_client().username_pw_set = mock_usename_password_set
mock_client.on_connect(return_value=0)
await async_setup_component(hass, mqtt.DOMAIN, {mqtt.DOMAIN: config})
await entry.async_setup(hass)
await hass.async_block_till_done()
assert (
"Deprecated configuration settings found in configuration.yaml. "
"These settings from your configuration entry will override:"
in caplog.text
)
# Check if the protocol was set to 3.1 from configuration.yaml
assert mock_client.call_args[1]["protocol"] == 3
# Check if the password override worked
assert calls_username_password_set[0][0] == "someuser"
assert calls_username_password_set[0][1] == "somepassword"
@patch("homeassistant.components.mqtt.PLATFORMS", [])
async def test_setup_manual_mqtt_with_platform_key(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
@@ -2312,39 +2256,10 @@ async def test_mqtt_subscribes_topics_on_connect(
mqtt_client_mock.subscribe.assert_any_call("still/pending", 1)
async def test_setup_entry_with_config_override(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test if the MQTT component loads with no config and config entry can be setup."""
data = (
'{ "device":{"identifiers":["0AFFD2"]},'
' "state_topic": "foobar/sensor",'
' "unique_id": "unique" }'
)
# mqtt present in yaml config
assert await async_setup_component(hass, mqtt.DOMAIN, {})
await hass.async_block_till_done()
# User sets up a config entry
entry = MockConfigEntry(domain=mqtt.DOMAIN, data={mqtt.CONF_BROKER: "test-broker"})
entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
# Discover a device to verify the entry was setup correctly
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data)
await hass.async_block_till_done()
device_entry = device_registry.async_get_device({("mqtt", "0AFFD2")})
assert device_entry is not None
async def test_update_incomplete_entry(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
mqtt_client_mock: MqttMockPahoClient,
caplog: pytest.LogCaptureFixture,
) -> None:
@@ -2356,24 +2271,17 @@ async def test_update_incomplete_entry(
)
# Config entry data is incomplete
entry = MockConfigEntry(domain=mqtt.DOMAIN, data={"port": 1234})
entry.add_to_hass(hass)
# Mqtt present in yaml config
config = {"broker": "yaml_broker"}
await async_setup_component(hass, mqtt.DOMAIN, {mqtt.DOMAIN: config})
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
entry.data = {"broker": "test-broker", "port": 1234}
await mqtt_mock_entry_no_yaml_config()
await hass.async_block_till_done()
# Config entry data should now be updated
assert dict(entry.data) == {
"broker": "test-broker",
"port": 1234,
"discovery_prefix": "homeassistant",
"broker": "yaml_broker",
}
# Warnings about broker deprecated, but not about other keys with default values
assert (
"The 'broker' option is deprecated, please remove it from your configuration"
in caplog.text
)
# Discover a device to verify the entry was setup correctly
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data)
@@ -3219,7 +3127,7 @@ async def test_subscribe_connection_status(
# This warning and test is to be removed from HA core 2023.6
async def test_one_deprecation_warning_per_platform(
hass: HomeAssistant,
mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test a deprecation warning is is logged once per platform."""
@@ -3230,8 +3138,6 @@ async def test_one_deprecation_warning_per_platform(
config2 = copy.deepcopy(config)
config2["name"] = "test2"
await async_setup_component(hass, platform, {platform: [config1, config2]})
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
count = 0
for record in caplog.records:
if record.levelname == "ERROR" and (
@@ -3242,13 +3148,6 @@ async def test_one_deprecation_warning_per_platform(
assert count == 1
async def test_config_schema_validation(hass: HomeAssistant) -> None:
"""Test invalid platform options in the config schema do not pass the config validation."""
config = {"mqtt": {"sensor": [{"some_illegal_topic": "mystate/topic/path"}]}}
with pytest.raises(vol.MultipleInvalid):
CONFIG_SCHEMA(config)
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.LIGHT])
async def test_unload_config_entry(
hass: HomeAssistant,
@@ -3277,24 +3176,6 @@ async def test_unload_config_entry(
assert "No ACK from MQTT server" not in caplog.text
@patch("homeassistant.components.mqtt.PLATFORMS", [])
async def test_setup_with_disabled_entry(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test setting up the platform with a disabled config entry."""
# Try to setup the platform with a disabled config entry
config_entry = MockConfigEntry(
domain=mqtt.DOMAIN, data={}, disabled_by=ConfigEntryDisabler.USER
)
config_entry.add_to_hass(hass)
config: ConfigType = {mqtt.DOMAIN: {}}
await async_setup_component(hass, mqtt.DOMAIN, config)
await hass.async_block_till_done()
assert "MQTT will be not available until the config entry is enabled" in caplog.text
@patch("homeassistant.components.mqtt.PLATFORMS", [])
async def test_publish_or_subscribe_without_valid_config_entry(
hass: HomeAssistant, record_calls: MessageCallbackType