1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 21:06:19 +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

@@ -9,13 +9,11 @@ from uuid import uuid4
import pytest
import voluptuous as vol
import yaml
from homeassistant import config as hass_config, config_entries, data_entry_flow
from homeassistant import config_entries, data_entry_flow
from homeassistant.components import mqtt
from homeassistant.components.hassio import HassioServiceInfo
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
@@ -267,39 +265,13 @@ async def test_user_connection_fails(
assert len(mock_finish_setup.mock_calls) == 0
async def test_manual_config_starts_discovery_flow(
hass: HomeAssistant,
mock_try_connection: MqttMockPahoClient,
mock_finish_setup: MagicMock,
) -> None:
"""Test manual config initiates a discovery flow."""
# No flows in progress
assert hass.config_entries.flow.async_progress() == []
# MQTT config present in yaml config
assert await async_setup_component(hass, "mqtt", {"mqtt": {}})
await hass.async_block_till_done()
assert len(mock_finish_setup.mock_calls) == 0
# There should now be a discovery flow
flows = hass.config_entries.flow.async_progress()
assert len(flows) == 1
assert flows[0]["context"]["source"] == "integration_discovery"
assert flows[0]["handler"] == "mqtt"
assert flows[0]["step_id"] == "broker"
@pytest.mark.parametrize("hass_config", [{"mqtt": {"sensor": {"state_topic": "test"}}}])
async def test_manual_config_set(
hass: HomeAssistant,
mock_try_connection: MqttMockPahoClient,
mock_finish_setup: MagicMock,
) -> None:
"""Test manual config does not create an entry, and entry can be setup late."""
# MQTT config present in yaml config
assert await async_setup_component(hass, "mqtt", {"mqtt": {"broker": "bla"}})
await hass.async_block_till_done()
# do not try to reload
hass.data["mqtt"].reload_needed = False
assert len(mock_finish_setup.mock_calls) == 0
mock_try_connection.return_value = True
@@ -1162,6 +1134,9 @@ async def test_options_bad_will_message_fails(
}
@pytest.mark.parametrize(
"hass_config", [{"mqtt": {"sensor": [{"state_topic": "some-topic"}]}}]
)
async def test_try_connection_with_advanced_parameters(
hass: HomeAssistant,
mock_try_connection_success: MqttMockPahoClient,
@@ -1170,23 +1145,6 @@ async def test_try_connection_with_advanced_parameters(
mock_process_uploaded_file: MagicMock,
) -> None:
"""Test config flow with advanced parameters from config."""
with open(tmp_path / "client.crt", "wb") as certfile:
certfile.write(MOCK_CLIENT_CERT)
with open(tmp_path / "client.key", "wb") as keyfile:
keyfile.write(MOCK_CLIENT_KEY)
config = {
"certificate": "auto",
"tls_insecure": True,
"client_cert": str(tmp_path / "client.crt"),
"client_key": str(tmp_path / "client.key"),
}
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
config_entry = MockConfigEntry(domain=mqtt.DOMAIN)
config_entry.add_to_hass(hass)
config_entry.data = {
@@ -1195,6 +1153,10 @@ async def test_try_connection_with_advanced_parameters(
mqtt.CONF_USERNAME: "user",
mqtt.CONF_PASSWORD: "pass",
mqtt.CONF_TRANSPORT: "websockets",
mqtt.CONF_CERTIFICATE: "auto",
mqtt.CONF_TLS_INSECURE: True,
mqtt.CONF_CLIENT_CERT: MOCK_CLIENT_CERT.decode(encoding="utf-8)"),
mqtt.CONF_CLIENT_KEY: MOCK_CLIENT_KEY.decode(encoding="utf-8"),
mqtt.CONF_WS_PATH: "/path/",
mqtt.CONF_WS_HEADERS: {"h1": "v1", "h2": "v2"},
mqtt.CONF_KEEPALIVE: 30,
@@ -1212,95 +1174,81 @@ async def test_try_connection_with_advanced_parameters(
mqtt.ATTR_RETAIN: False,
},
}
# Test default/suggested values from config
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["step_id"] == "broker"
defaults = {
mqtt.CONF_BROKER: "test-broker",
mqtt.CONF_PORT: 1234,
"set_client_cert": True,
"set_ca_cert": "auto",
}
suggested = {
mqtt.CONF_USERNAME: "user",
mqtt.CONF_PASSWORD: "pass",
mqtt.CONF_TLS_INSECURE: True,
mqtt.CONF_PROTOCOL: "3.1.1",
mqtt.CONF_TRANSPORT: "websockets",
mqtt.CONF_WS_PATH: "/path/",
mqtt.CONF_WS_HEADERS: '{"h1":"v1","h2":"v2"}',
}
for k, v in defaults.items():
assert get_default(result["data_schema"].schema, k) == v
for k, v in suggested.items():
assert get_suggested(result["data_schema"].schema, k) == v
with patch.object(hass_config, "YAML_CONFIG_FILE", new_yaml_config_file):
await async_setup_component(hass, mqtt.DOMAIN, {mqtt.DOMAIN: config})
await hass.async_block_till_done()
# Test default/suggested values from config
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["step_id"] == "broker"
defaults = {
mqtt.CONF_BROKER: "test-broker",
mqtt.CONF_PORT: 1234,
"set_client_cert": True,
# test we can change username and password
# as it was configured as auto in configuration.yaml is is migrated now
mock_try_connection_success.reset_mock()
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
mqtt.CONF_BROKER: "another-broker",
mqtt.CONF_PORT: 2345,
mqtt.CONF_USERNAME: "us3r",
mqtt.CONF_PASSWORD: "p4ss",
"set_ca_cert": "auto",
}
suggested = {
mqtt.CONF_USERNAME: "user",
mqtt.CONF_PASSWORD: "pass",
"set_client_cert": True,
mqtt.CONF_TLS_INSECURE: True,
mqtt.CONF_PROTOCOL: "3.1.1",
mqtt.CONF_TRANSPORT: "websockets",
mqtt.CONF_WS_PATH: "/path/",
mqtt.CONF_WS_HEADERS: '{"h1":"v1","h2":"v2"}',
}
for k, v in defaults.items():
assert get_default(result["data_schema"].schema, k) == v
for k, v in suggested.items():
assert get_suggested(result["data_schema"].schema, k) == v
mqtt.CONF_WS_PATH: "/new/path",
mqtt.CONF_WS_HEADERS: '{"h3": "v3"}',
},
)
assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["errors"] == {}
assert result["step_id"] == "options"
await hass.async_block_till_done()
# test the client cert and key were migrated to the entry
assert config_entry.data[mqtt.CONF_CLIENT_CERT] == MOCK_CLIENT_CERT.decode(
"utf-8"
)
assert config_entry.data[mqtt.CONF_CLIENT_KEY] == MOCK_CLIENT_KEY.decode(
"utf-8"
)
assert config_entry.data[mqtt.CONF_CERTIFICATE] == "auto"
# check if the username and password was set from config flow and not from configuration.yaml
assert mock_try_connection_success.username_pw_set.mock_calls[0][1] == (
"us3r",
"p4ss",
)
# check if tls_insecure_set is called
assert mock_try_connection_success.tls_insecure_set.mock_calls[0][1] == (True,)
# test we can change username and password
# as it was configured as auto in configuration.yaml is is migrated now
mock_try_connection_success.reset_mock()
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
mqtt.CONF_BROKER: "another-broker",
mqtt.CONF_PORT: 2345,
mqtt.CONF_USERNAME: "us3r",
mqtt.CONF_PASSWORD: "p4ss",
"set_ca_cert": "auto",
"set_client_cert": True,
mqtt.CONF_TLS_INSECURE: True,
mqtt.CONF_TRANSPORT: "websockets",
mqtt.CONF_WS_PATH: "/new/path",
mqtt.CONF_WS_HEADERS: '{"h3": "v3"}',
},
)
assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["errors"] == {}
assert result["step_id"] == "options"
await hass.async_block_till_done()
# check if the ca certificate settings were not set during connection test
assert mock_try_connection_success.tls_set.mock_calls[0].kwargs[
"certfile"
] == mqtt.util.get_file_path(mqtt.CONF_CLIENT_CERT)
assert mock_try_connection_success.tls_set.mock_calls[0].kwargs[
"keyfile"
] == mqtt.util.get_file_path(mqtt.CONF_CLIENT_KEY)
# check if the username and password was set from config flow and not from configuration.yaml
assert mock_try_connection_success.username_pw_set.mock_calls[0][1] == (
"us3r",
"p4ss",
)
# check if tls_insecure_set is called
assert mock_try_connection_success.tls_insecure_set.mock_calls[0][1] == (True,)
# check if the ca certificate settings were not set during connection test
assert mock_try_connection_success.tls_set.mock_calls[0].kwargs[
"certfile"
] == mqtt.util.get_file_path(mqtt.CONF_CLIENT_CERT)
assert mock_try_connection_success.tls_set.mock_calls[0].kwargs[
"keyfile"
] == mqtt.util.get_file_path(mqtt.CONF_CLIENT_KEY)
# check if websockets options are set
assert mock_try_connection_success.ws_set_options.mock_calls[0][1] == (
"/new/path",
{"h3": "v3"},
)
# Accept default option
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={},
)
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
await hass.async_block_till_done()
# check if websockets options are set
assert mock_try_connection_success.ws_set_options.mock_calls[0][1] == (
"/new/path",
{"h3": "v3"},
)
# Accept default option
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={},
)
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
await hass.async_block_till_done()
async def test_setup_with_advanced_settings(