Add type hints for MQTT discovery tests (#87425)

* Add type hints for MQTT discovery tests

* Remove more unused caplog instances

* rebase commit

* Small corrections

* Add event tye hint and correct string assignment

* Another Event type hint

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Correct test_complex_discovery_topic_prefix

* Import individual items from homeassistant.core

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
This commit is contained in:
Jan Bouwhuis 2023-02-08 20:56:27 +01:00 committed by GitHub
parent b0b1d8143f
commit b93c135c8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -22,7 +22,11 @@ from homeassistant.const import (
STATE_UNKNOWN, STATE_UNKNOWN,
Platform, Platform,
) )
import homeassistant.core as ha from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.data_entry_flow import FlowResult
import homeassistant.helpers.device_registry as dr
import homeassistant.helpers.entity_registry as er
from homeassistant.helpers.service_info.mqtt import MqttServiceInfo
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from .test_common import help_test_unload_config_entry from .test_common import help_test_unload_config_entry
@ -35,16 +39,21 @@ from tests.common import (
mock_entity_platform, mock_entity_platform,
mock_registry, mock_registry,
) )
from tests.typing import (
MqttMockHAClientGenerator,
MqttMockPahoClient,
WebSocketGenerator,
)
@pytest.fixture @pytest.fixture
def device_reg(hass): def device_reg(hass: HomeAssistant) -> dr.DeviceRegistry:
"""Return an empty, loaded, registry.""" """Return an empty, loaded, registry."""
return mock_device_registry(hass) return mock_device_registry(hass)
@pytest.fixture @pytest.fixture
def entity_reg(hass): def entity_reg(hass: HomeAssistant) -> er.EntityRegistry:
"""Return an empty, loaded, registry.""" """Return an empty, loaded, registry."""
return mock_registry(hass) return mock_registry(hass)
@ -53,7 +62,10 @@ def entity_reg(hass):
"mqtt_config_entry_data", "mqtt_config_entry_data",
[{mqtt.CONF_BROKER: "mock-broker", mqtt.CONF_DISCOVERY: False}], [{mqtt.CONF_BROKER: "mock-broker", mqtt.CONF_DISCOVERY: False}],
) )
async def test_subscribing_config_topic(hass, mqtt_mock_entry_no_yaml_config): async def test_subscribing_config_topic(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test setting up discovery.""" """Test setting up discovery."""
mqtt_mock = await mqtt_mock_entry_no_yaml_config() mqtt_mock = await mqtt_mock_entry_no_yaml_config()
entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0] entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
@ -78,7 +90,13 @@ async def test_subscribing_config_topic(hass, mqtt_mock_entry_no_yaml_config):
("homeassistant/binary_sensor/rörkrökare/config", True), ("homeassistant/binary_sensor/rörkrökare/config", True),
], ],
) )
async def test_invalid_topic(hass, mqtt_mock_entry_no_yaml_config, caplog, topic, log): async def test_invalid_topic(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
topic: str,
log: bool,
) -> None:
"""Test sending to invalid topic.""" """Test sending to invalid topic."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
with patch( with patch(
@ -99,7 +117,11 @@ async def test_invalid_topic(hass, mqtt_mock_entry_no_yaml_config, caplog, topic
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
async def test_invalid_json(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_invalid_json(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test sending in invalid JSON.""" """Test sending in invalid JSON."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
with patch( with patch(
@ -115,7 +137,11 @@ async def test_invalid_json(hass, mqtt_mock_entry_no_yaml_config, caplog):
assert not mock_dispatcher_send.called assert not mock_dispatcher_send.called
async def test_only_valid_components(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_only_valid_components(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test for a valid component.""" """Test for a valid component."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
with patch( with patch(
@ -137,7 +163,10 @@ async def test_only_valid_components(hass, mqtt_mock_entry_no_yaml_config, caplo
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
async def test_correct_config_discovery(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_correct_config_discovery(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test sending in correct JSON.""" """Test sending in correct JSON."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
async_fire_mqtt_message( async_fire_mqtt_message(
@ -155,13 +184,16 @@ async def test_correct_config_discovery(hass, mqtt_mock_entry_no_yaml_config, ca
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.FAN]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.FAN])
async def test_discover_fan(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_discover_fan(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test discovering an MQTT fan.""" """Test discovering an MQTT fan."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
async_fire_mqtt_message( async_fire_mqtt_message(
hass, hass,
"homeassistant/fan/bla/config", "homeassistant/fan/bla/config",
('{ "name": "Beer",' ' "command_topic": "test_topic" }'), '{ "name": "Beer", "command_topic": "test_topic" }',
) )
await hass.async_block_till_done() await hass.async_block_till_done()
@ -173,7 +205,11 @@ async def test_discover_fan(hass, mqtt_mock_entry_no_yaml_config, caplog):
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.CLIMATE]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.CLIMATE])
async def test_discover_climate(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_discover_climate(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test discovering an MQTT climate component.""" """Test discovering an MQTT climate component."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
data = ( data = (
@ -194,8 +230,9 @@ async def test_discover_climate(hass, mqtt_mock_entry_no_yaml_config, caplog):
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.ALARM_CONTROL_PANEL]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.ALARM_CONTROL_PANEL])
async def test_discover_alarm_control_panel( async def test_discover_alarm_control_panel(
hass, mqtt_mock_entry_no_yaml_config, caplog hass: HomeAssistant,
): mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test discovering an MQTT alarm control panel component.""" """Test discovering an MQTT alarm control panel component."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
data = ( data = (
@ -362,8 +399,14 @@ async def test_discover_alarm_control_panel(
], ],
) )
async def test_discovery_with_object_id( async def test_discovery_with_object_id(
hass, mqtt_mock_entry_no_yaml_config, caplog, topic, config, entity_id, name, domain hass: HomeAssistant,
): mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
topic: str,
config: str,
entity_id: str,
name: str,
domain: str,
) -> None:
"""Test discovering an MQTT entity with object_id.""" """Test discovering an MQTT entity with object_id."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
async_fire_mqtt_message(hass, topic, config) async_fire_mqtt_message(hass, topic, config)
@ -377,7 +420,10 @@ async def test_discovery_with_object_id(
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
async def test_discovery_incl_nodeid(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_discovery_incl_nodeid(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test sending in correct JSON with optional node_id included.""" """Test sending in correct JSON with optional node_id included."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
async_fire_mqtt_message( async_fire_mqtt_message(
@ -397,7 +443,11 @@ async def test_discovery_incl_nodeid(hass, mqtt_mock_entry_no_yaml_config, caplo
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
async def test_non_duplicate_discovery(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_non_duplicate_discovery(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test for a non duplicate component.""" """Test for a non duplicate component."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
async_fire_mqtt_message( async_fire_mqtt_message(
@ -422,7 +472,10 @@ async def test_non_duplicate_discovery(hass, mqtt_mock_entry_no_yaml_config, cap
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
async def test_removal(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_removal(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test removal of component through empty discovery message.""" """Test removal of component through empty discovery message."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
async_fire_mqtt_message( async_fire_mqtt_message(
@ -441,7 +494,10 @@ async def test_removal(hass, mqtt_mock_entry_no_yaml_config, caplog):
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
async def test_rediscover(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_rediscover(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test rediscover of removed component.""" """Test rediscover of removed component."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
async_fire_mqtt_message( async_fire_mqtt_message(
@ -469,7 +525,10 @@ async def test_rediscover(hass, mqtt_mock_entry_no_yaml_config, caplog):
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
async def test_rapid_rediscover(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_rapid_rediscover(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test immediate rediscover of removed component.""" """Test immediate rediscover of removed component."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
events = async_capture_events(hass, EVENT_STATE_CHANGED) events = async_capture_events(hass, EVENT_STATE_CHANGED)
@ -519,17 +578,20 @@ async def test_rapid_rediscover(hass, mqtt_mock_entry_no_yaml_config, caplog):
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
async def test_rapid_rediscover_unique(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_rapid_rediscover_unique(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test immediate rediscover of removed component.""" """Test immediate rediscover of removed component."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
events = [] events = []
@ha.callback @callback
def callback(event): def test_callback(event: Event) -> None:
"""Verify event got called.""" """Verify event got called."""
events.append(event) events.append(event)
hass.bus.async_listen(EVENT_STATE_CHANGED, callback) hass.bus.async_listen(EVENT_STATE_CHANGED, test_callback)
async_fire_mqtt_message( async_fire_mqtt_message(
hass, hass,
@ -579,17 +641,20 @@ async def test_rapid_rediscover_unique(hass, mqtt_mock_entry_no_yaml_config, cap
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
async def test_rapid_reconfigure(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_rapid_reconfigure(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test immediate reconfigure of added component.""" """Test immediate reconfigure of added component."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
events = [] events = []
@ha.callback @callback
def callback(event): def test_callback(event: Event) -> None:
"""Verify event got called.""" """Verify event got called."""
events.append(event) events.append(event)
hass.bus.async_listen(EVENT_STATE_CHANGED, callback) hass.bus.async_listen(EVENT_STATE_CHANGED, test_callback)
# Discovery immediately followed by reconfig # Discovery immediately followed by reconfig
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", "") async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", "")
@ -632,7 +697,11 @@ async def test_rapid_reconfigure(hass, mqtt_mock_entry_no_yaml_config, caplog):
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
async def test_duplicate_removal(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_duplicate_removal(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test for a non duplicate component.""" """Test for a non duplicate component."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
async_fire_mqtt_message( async_fire_mqtt_message(
@ -652,8 +721,12 @@ async def test_duplicate_removal(hass, mqtt_mock_entry_no_yaml_config, caplog):
async def test_cleanup_device( async def test_cleanup_device(
hass, hass_ws_client, device_reg, entity_reg, mqtt_mock_entry_no_yaml_config hass: HomeAssistant,
): hass_ws_client: WebSocketGenerator,
device_reg: dr.DeviceRegistry,
entity_reg: er.EntityRegistry,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test discvered device is cleaned up when entry removed from device.""" """Test discvered device is cleaned up when entry removed from device."""
mqtt_mock = await mqtt_mock_entry_no_yaml_config() mqtt_mock = await mqtt_mock_entry_no_yaml_config()
assert await async_setup_component(hass, "config", {}) assert await async_setup_component(hass, "config", {})
@ -711,8 +784,11 @@ async def test_cleanup_device(
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR])
async def test_cleanup_device_mqtt( async def test_cleanup_device_mqtt(
hass, device_reg, entity_reg, mqtt_mock_entry_no_yaml_config hass: HomeAssistant,
): device_reg: dr.DeviceRegistry,
entity_reg: er.EntityRegistry,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test discvered device is cleaned up when removed through MQTT.""" """Test discvered device is cleaned up when removed through MQTT."""
mqtt_mock = await mqtt_mock_entry_no_yaml_config() mqtt_mock = await mqtt_mock_entry_no_yaml_config()
data = ( data = (
@ -754,8 +830,12 @@ async def test_cleanup_device_mqtt(
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR])
async def test_cleanup_device_multiple_config_entries( async def test_cleanup_device_multiple_config_entries(
hass, hass_ws_client, device_reg, entity_reg, mqtt_mock_entry_no_yaml_config hass: HomeAssistant,
): hass_ws_client: WebSocketGenerator,
device_reg: dr.DeviceRegistry,
entity_reg: er.EntityRegistry,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test discovered device is cleaned up when entry removed from device.""" """Test discovered device is cleaned up when entry removed from device."""
assert await async_setup_component(hass, "config", {}) assert await async_setup_component(hass, "config", {})
await hass.async_block_till_done() await hass.async_block_till_done()
@ -764,10 +844,11 @@ async def test_cleanup_device_multiple_config_entries(
config_entry = MockConfigEntry(domain="test", data={}) config_entry = MockConfigEntry(domain="test", data={})
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
device_entry = device_reg.async_get_or_create( device_entry: dr.DeviceEntry | None = device_reg.async_get_or_create(
config_entry_id=config_entry.entry_id, config_entry_id=config_entry.entry_id,
connections={("mac", "12:34:56:AB:CD:EF")}, connections={("mac", "12:34:56:AB:CD:EF")},
) )
assert device_entry is not None
mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0] mqtt_config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
@ -851,13 +932,16 @@ async def test_cleanup_device_multiple_config_entries(
async def test_cleanup_device_multiple_config_entries_mqtt( async def test_cleanup_device_multiple_config_entries_mqtt(
hass, device_reg, entity_reg, mqtt_mock_entry_no_yaml_config hass: HomeAssistant,
): device_reg: dr.DeviceRegistry,
entity_reg: er.EntityRegistry,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test discovered device is cleaned up when removed through MQTT.""" """Test discovered device is cleaned up when removed through MQTT."""
mqtt_mock = await mqtt_mock_entry_no_yaml_config() mqtt_mock = await mqtt_mock_entry_no_yaml_config()
config_entry = MockConfigEntry(domain="test", data={}) config_entry = MockConfigEntry(domain="test", data={})
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
device_entry = device_reg.async_get_or_create( device_entry: dr.DeviceEntry | None = device_reg.async_get_or_create(
config_entry_id=config_entry.entry_id, config_entry_id=config_entry.entry_id,
connections={("mac", "12:34:56:AB:CD:EF")}, connections={("mac", "12:34:56:AB:CD:EF")},
) )
@ -929,7 +1013,10 @@ async def test_cleanup_device_multiple_config_entries_mqtt(
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SWITCH]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SWITCH])
async def test_discovery_expansion(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_discovery_expansion(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test expansion of abbreviated discovery payload.""" """Test expansion of abbreviated discovery payload."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
data = ( data = (
@ -965,7 +1052,7 @@ async def test_discovery_expansion(hass, mqtt_mock_entry_no_yaml_config, caplog)
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("switch.DiscoveryExpansionTest1") state = hass.states.get("switch.DiscoveryExpansionTest1")
assert state.state == STATE_UNAVAILABLE assert state and state.state == STATE_UNAVAILABLE
async_fire_mqtt_message(hass, "avail_item2/some/base/topic", "available") async_fire_mqtt_message(hass, "avail_item2/some/base/topic", "available")
await hass.async_block_till_done() await hass.async_block_till_done()
@ -979,17 +1066,20 @@ async def test_discovery_expansion(hass, mqtt_mock_entry_no_yaml_config, caplog)
async_fire_mqtt_message(hass, "test_topic/some/base/topic", "ON") async_fire_mqtt_message(hass, "test_topic/some/base/topic", "ON")
state = hass.states.get("switch.DiscoveryExpansionTest1") state = hass.states.get("switch.DiscoveryExpansionTest1")
assert state.state == STATE_ON assert state and state.state == STATE_ON
async_fire_mqtt_message(hass, "some/base/topic/avail_item1", "not_available") async_fire_mqtt_message(hass, "some/base/topic/avail_item1", "not_available")
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("switch.DiscoveryExpansionTest1") state = hass.states.get("switch.DiscoveryExpansionTest1")
assert state.state == STATE_UNAVAILABLE assert state and state.state == STATE_UNAVAILABLE
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SWITCH]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SWITCH])
async def test_discovery_expansion_2(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_discovery_expansion_2(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test expansion of abbreviated discovery payload.""" """Test expansion of abbreviated discovery payload."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
data = ( data = (
@ -1018,7 +1108,7 @@ async def test_discovery_expansion_2(hass, mqtt_mock_entry_no_yaml_config, caplo
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("switch.DiscoveryExpansionTest1") state = hass.states.get("switch.DiscoveryExpansionTest1")
assert state.state == STATE_UNAVAILABLE assert state and state.state == STATE_UNAVAILABLE
async_fire_mqtt_message(hass, "some/base/topic/avail_item1", "available") async_fire_mqtt_message(hass, "some/base/topic/avail_item1", "available")
await hass.async_block_till_done() await hass.async_block_till_done()
@ -1032,7 +1122,11 @@ async def test_discovery_expansion_2(hass, mqtt_mock_entry_no_yaml_config, caplo
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SWITCH]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SWITCH])
@pytest.mark.no_fail_on_log_exception @pytest.mark.no_fail_on_log_exception
async def test_discovery_expansion_3(hass, mqtt_mock_entry_no_yaml_config, caplog): async def test_discovery_expansion_3(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test expansion of broken discovery payload.""" """Test expansion of broken discovery payload."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
data = ( data = (
@ -1065,8 +1159,9 @@ async def test_discovery_expansion_3(hass, mqtt_mock_entry_no_yaml_config, caplo
async def test_discovery_expansion_without_encoding_and_value_template_1( async def test_discovery_expansion_without_encoding_and_value_template_1(
hass, mqtt_mock_entry_no_yaml_config, caplog hass: HomeAssistant,
): mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test expansion of raw availability payload with a template as list.""" """Test expansion of raw availability payload with a template as list."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
data = ( data = (
@ -1097,7 +1192,7 @@ async def test_discovery_expansion_without_encoding_and_value_template_1(
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("switch.DiscoveryExpansionTest1") state = hass.states.get("switch.DiscoveryExpansionTest1")
assert state.state == STATE_UNAVAILABLE assert state and state.state == STATE_UNAVAILABLE
async_fire_mqtt_message(hass, "some/base/topic/avail_item1", b"\x01") async_fire_mqtt_message(hass, "some/base/topic/avail_item1", b"\x01")
await hass.async_block_till_done() await hass.async_block_till_done()
@ -1111,13 +1206,14 @@ async def test_discovery_expansion_without_encoding_and_value_template_1(
async_fire_mqtt_message(hass, "some/base/topic/avail_item1", b"\x00") async_fire_mqtt_message(hass, "some/base/topic/avail_item1", b"\x00")
state = hass.states.get("switch.DiscoveryExpansionTest1") state = hass.states.get("switch.DiscoveryExpansionTest1")
assert state.state == STATE_UNAVAILABLE assert state and state.state == STATE_UNAVAILABLE
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SWITCH]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SWITCH])
async def test_discovery_expansion_without_encoding_and_value_template_2( async def test_discovery_expansion_without_encoding_and_value_template_2(
hass, mqtt_mock_entry_no_yaml_config, caplog hass: HomeAssistant,
): mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test expansion of raw availability payload with a template directly.""" """Test expansion of raw availability payload with a template directly."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
data = ( data = (
@ -1146,7 +1242,7 @@ async def test_discovery_expansion_without_encoding_and_value_template_2(
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("switch.DiscoveryExpansionTest1") state = hass.states.get("switch.DiscoveryExpansionTest1")
assert state.state == STATE_UNAVAILABLE assert state and state.state == STATE_UNAVAILABLE
async_fire_mqtt_message(hass, "some/base/topic/avail_item1", b"\x01") async_fire_mqtt_message(hass, "some/base/topic/avail_item1", b"\x01")
await hass.async_block_till_done() await hass.async_block_till_done()
@ -1160,7 +1256,7 @@ async def test_discovery_expansion_without_encoding_and_value_template_2(
async_fire_mqtt_message(hass, "some/base/topic/avail_item1", b"\x00") async_fire_mqtt_message(hass, "some/base/topic/avail_item1", b"\x00")
state = hass.states.get("switch.DiscoveryExpansionTest1") state = hass.states.get("switch.DiscoveryExpansionTest1")
assert state.state == STATE_UNAVAILABLE assert state and state.state == STATE_UNAVAILABLE
ABBREVIATIONS_WHITE_LIST = [ ABBREVIATIONS_WHITE_LIST = [
@ -1201,8 +1297,9 @@ ABBREVIATIONS_WHITE_LIST = [
async def test_missing_discover_abbreviations( async def test_missing_discover_abbreviations(
hass, mqtt_mock_entry_no_yaml_config, caplog hass: HomeAssistant,
): mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Check MQTT platforms for missing abbreviations.""" """Check MQTT platforms for missing abbreviations."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
missing = [] missing = []
@ -1210,7 +1307,7 @@ async def test_missing_discover_abbreviations(
for fil in Path(mqtt.__file__).parent.rglob("*.py"): for fil in Path(mqtt.__file__).parent.rglob("*.py"):
if fil.name == "trigger.py": if fil.name == "trigger.py":
continue continue
with open(fil) as file: with open(fil, encoding="utf-8") as file:
matches = re.findall(regex, file.read()) matches = re.findall(regex, file.read())
for match in matches: for match in matches:
if ( if (
@ -1229,11 +1326,12 @@ async def test_missing_discover_abbreviations(
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SWITCH]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SWITCH])
async def test_no_implicit_state_topic_switch( async def test_no_implicit_state_topic_switch(
hass, mqtt_mock_entry_no_yaml_config, caplog hass: HomeAssistant,
): mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Test no implicit state topic for switch.""" """Test no implicit state topic for switch."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
data = '{ "name": "Test1",' ' "command_topic": "cmnd"' "}" data = '{ "name": "Test1", "command_topic": "cmnd" }'
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data) async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data)
await hass.async_block_till_done() await hass.async_block_till_done()
@ -1248,7 +1346,7 @@ async def test_no_implicit_state_topic_switch(
async_fire_mqtt_message(hass, "homeassistant/switch/bla/state", "ON") async_fire_mqtt_message(hass, "homeassistant/switch/bla/state", "ON")
state = hass.states.get("switch.Test1") state = hass.states.get("switch.Test1")
assert state.state == STATE_UNKNOWN assert state and state.state == STATE_UNKNOWN
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.BINARY_SENSOR])
@ -1257,22 +1355,15 @@ async def test_no_implicit_state_topic_switch(
[ [
{ {
mqtt.CONF_BROKER: "mock-broker", mqtt.CONF_BROKER: "mock-broker",
mqtt.CONF_DISCOVERY_PREFIX: "my_home/homeassistant/register",
} }
], ],
) )
async def test_complex_discovery_topic_prefix( async def test_complex_discovery_topic_prefix(
hass, mqtt_mock_entry_with_yaml_config, caplog hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
): ) -> None:
"""Tests handling of discovery topic prefix with multiple slashes.""" """Tests handling of discovery topic prefix with multiple slashes."""
assert await async_setup_component( await mqtt_mock_entry_no_yaml_config()
hass,
mqtt.DOMAIN,
{
mqtt.DOMAIN: {
mqtt.CONF_DISCOVERY_PREFIX: "my_home/homeassistant/register",
}
},
)
async_fire_mqtt_message( async_fire_mqtt_message(
hass, hass,
@ -1292,8 +1383,10 @@ async def test_complex_discovery_topic_prefix(
@patch("homeassistant.components.mqtt.PLATFORMS", []) @patch("homeassistant.components.mqtt.PLATFORMS", [])
async def test_mqtt_integration_discovery_subscribe_unsubscribe( async def test_mqtt_integration_discovery_subscribe_unsubscribe(
hass, mqtt_client_mock, mqtt_mock_entry_no_yaml_config hass: HomeAssistant,
): mqtt_client_mock: MqttMockPahoClient,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Check MQTT integration discovery subscribe and unsubscribe.""" """Check MQTT integration discovery subscribe and unsubscribe."""
mqtt_mock = await mqtt_mock_entry_no_yaml_config() mqtt_mock = await mqtt_mock_entry_no_yaml_config()
mock_entity_platform(hass, "config_flow.comp", None) mock_entity_platform(hass, "config_flow.comp", None)
@ -1314,7 +1407,7 @@ async def test_mqtt_integration_discovery_subscribe_unsubscribe(
class TestFlow(config_entries.ConfigFlow): class TestFlow(config_entries.ConfigFlow):
"""Test flow.""" """Test flow."""
async def async_step_mqtt(self, discovery_info): async def async_step_mqtt(self, discovery_info: MqttServiceInfo) -> FlowResult:
"""Test mqtt step.""" """Test mqtt step."""
return self.async_abort(reason="already_configured") return self.async_abort(reason="already_configured")
@ -1334,8 +1427,10 @@ async def test_mqtt_integration_discovery_subscribe_unsubscribe(
@patch("homeassistant.components.mqtt.PLATFORMS", []) @patch("homeassistant.components.mqtt.PLATFORMS", [])
async def test_mqtt_discovery_unsubscribe_once( async def test_mqtt_discovery_unsubscribe_once(
hass, mqtt_client_mock, mqtt_mock_entry_no_yaml_config hass: HomeAssistant,
): mqtt_client_mock: MqttMockPahoClient,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
) -> None:
"""Check MQTT integration discovery unsubscribe once.""" """Check MQTT integration discovery unsubscribe once."""
mqtt_mock = await mqtt_mock_entry_no_yaml_config() mqtt_mock = await mqtt_mock_entry_no_yaml_config()
mock_entity_platform(hass, "config_flow.comp", None) mock_entity_platform(hass, "config_flow.comp", None)
@ -1356,7 +1451,7 @@ async def test_mqtt_discovery_unsubscribe_once(
class TestFlow(config_entries.ConfigFlow): class TestFlow(config_entries.ConfigFlow):
"""Test flow.""" """Test flow."""
async def async_step_mqtt(self, discovery_info): async def async_step_mqtt(self, discovery_info: MqttServiceInfo) -> FlowResult:
"""Test mqtt step.""" """Test mqtt step."""
return self.async_abort(reason="already_configured") return self.async_abort(reason="already_configured")
@ -1370,8 +1465,11 @@ async def test_mqtt_discovery_unsubscribe_once(
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR])
async def test_clear_config_topic_disabled_entity( async def test_clear_config_topic_disabled_entity(
hass, mqtt_mock_entry_no_yaml_config, device_reg, caplog hass: HomeAssistant,
): mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
device_reg: dr.DeviceRegistry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test the discovery topic is removed when a disabled entity is removed.""" """Test the discovery topic is removed when a disabled entity is removed."""
mqtt_mock = await mqtt_mock_entry_no_yaml_config() mqtt_mock = await mqtt_mock_entry_no_yaml_config()
# discover an entity that is not enabled by default # discover an entity that is not enabled by default
@ -1441,8 +1539,11 @@ async def test_clear_config_topic_disabled_entity(
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR])
async def test_clean_up_registry_monitoring( async def test_clean_up_registry_monitoring(
hass, mqtt_mock_entry_no_yaml_config, device_reg, tmp_path hass: HomeAssistant,
): mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
device_reg: dr.DeviceRegistry,
tmp_path: Path,
) -> None:
"""Test registry monitoring hook is removed after a reload.""" """Test registry monitoring hook is removed after a reload."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
hooks: dict = hass.data["mqtt"].discovery_registry_hooks hooks: dict = hass.data["mqtt"].discovery_registry_hooks
@ -1491,8 +1592,10 @@ async def test_clean_up_registry_monitoring(
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR])
async def test_unique_id_collission_has_priority( async def test_unique_id_collission_has_priority(
hass, mqtt_mock_entry_no_yaml_config, entity_reg hass: HomeAssistant,
): mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
entity_reg: er.EntityRegistry,
) -> None:
"""Test the unique_id collision detection has priority over registry disabled items.""" """Test the unique_id collision detection has priority over registry disabled items."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
config = { config = {
@ -1538,7 +1641,7 @@ async def test_unique_id_collission_has_priority(
@pytest.mark.xfail(raises=MultipleInvalid) @pytest.mark.xfail(raises=MultipleInvalid)
@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR]) @patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR])
async def test_update_with_bad_config_not_breaks_discovery( async def test_update_with_bad_config_not_breaks_discovery(
hass: ha.HomeAssistant, mqtt_mock_entry_no_yaml_config, entity_reg hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None: ) -> None:
"""Test a bad update does not break discovery.""" """Test a bad update does not break discovery."""
await mqtt_mock_entry_no_yaml_config() await mqtt_mock_entry_no_yaml_config()
@ -1586,4 +1689,5 @@ async def test_update_with_bad_config_not_breaks_discovery(
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get("sensor.sbfspot_12345").state == "new_value" state = hass.states.get("sensor.sbfspot_12345")
assert state and state.state == "new_value"