diff --git a/tests/components/mqtt/test_lock.py b/tests/components/mqtt/test_lock.py index 0c8b6680c55..f13de403535 100644 --- a/tests/components/mqtt/test_lock.py +++ b/tests/components/mqtt/test_lock.py @@ -25,9 +25,9 @@ from homeassistant.const import ( Platform, ) from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component from .test_common import ( + help_custom_config, help_test_availability_when_connection_lost, help_test_availability_without_topic, help_test_custom_availability_payload, @@ -63,6 +63,22 @@ DEFAULT_CONFIG = { mqtt.DOMAIN: {lock.DOMAIN: {"name": "test", "command_topic": "test-topic"}} } +CONFIG_WITH_STATES = { + mqtt.DOMAIN: { + lock.DOMAIN: { + "name": "test", + "state_topic": "state-topic", + "command_topic": "command-topic", + "payload_lock": "LOCK", + "payload_unlock": "UNLOCK", + "state_locked": "closed", + "state_locking": "closing", + "state_unlocked": "open", + "state_unlocking": "opening", + } + } +} + @pytest.fixture(autouse=True) def lock_platform_only(): @@ -72,42 +88,22 @@ def lock_platform_only(): @pytest.mark.parametrize( - ("payload", "lock_state"), + ("hass_config", "payload", "lock_state"), [ - ("LOCKED", STATE_LOCKED), - ("LOCKING", STATE_LOCKING), - ("UNLOCKED", STATE_UNLOCKED), - ("UNLOCKING", STATE_UNLOCKING), + (CONFIG_WITH_STATES, "closed", STATE_LOCKED), + (CONFIG_WITH_STATES, "closing", STATE_LOCKING), + (CONFIG_WITH_STATES, "open", STATE_UNLOCKED), + (CONFIG_WITH_STATES, "opening", STATE_UNLOCKING), ], ) async def test_controlling_state_via_topic( hass: HomeAssistant, - mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator, - payload, - lock_state, + mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator, + payload: str, + lock_state: str, ) -> None: """Test the controlling state via topic.""" - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - lock.DOMAIN: { - "name": "test", - "state_topic": "state-topic", - "command_topic": "command-topic", - "payload_lock": "LOCK", - "payload_unlock": "UNLOCK", - "state_locked": "LOCKED", - "state_locking": "LOCKING", - "state_unlocked": "UNLOCKED", - "state_unlocking": "UNLOCKING", - } - } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + await mqtt_mock_entry_no_yaml_config() state = hass.states.get("lock.test") assert state.state is STATE_UNLOCKED @@ -115,48 +111,29 @@ async def test_controlling_state_via_topic( assert not state.attributes.get(ATTR_SUPPORTED_FEATURES) async_fire_mqtt_message(hass, "state-topic", payload) + await hass.async_block_till_done() state = hass.states.get("lock.test") assert state.state is lock_state @pytest.mark.parametrize( - ("payload", "lock_state"), + ("hass_config", "payload", "lock_state"), [ - ("closed", STATE_LOCKED), - ("closing", STATE_LOCKING), - ("open", STATE_UNLOCKED), - ("opening", STATE_UNLOCKING), + (CONFIG_WITH_STATES, "closed", STATE_LOCKED), + (CONFIG_WITH_STATES, "closing", STATE_LOCKING), + (CONFIG_WITH_STATES, "open", STATE_UNLOCKED), + (CONFIG_WITH_STATES, "opening", STATE_UNLOCKING), ], ) async def test_controlling_non_default_state_via_topic( hass: HomeAssistant, - mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator, - payload, - lock_state, + mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator, + payload: str, + lock_state: str, ) -> None: """Test the controlling state via topic.""" - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - lock.DOMAIN: { - "name": "test", - "state_topic": "state-topic", - "command_topic": "command-topic", - "payload_lock": "LOCK", - "payload_unlock": "UNLOCK", - "state_locked": "closed", - "state_locking": "closing", - "state_unlocked": "open", - "state_unlocking": "opening", - } - } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + await mqtt_mock_entry_no_yaml_config() state = hass.states.get("lock.test") assert state.state is STATE_UNLOCKED @@ -169,43 +146,54 @@ async def test_controlling_non_default_state_via_topic( @pytest.mark.parametrize( - ("payload", "lock_state"), + ("hass_config", "payload", "lock_state"), [ - ('{"val":"LOCKED"}', STATE_LOCKED), - ('{"val":"LOCKING"}', STATE_LOCKING), - ('{"val":"UNLOCKED"}', STATE_UNLOCKED), - ('{"val":"UNLOCKING"}', STATE_UNLOCKING), + ( + help_custom_config( + lock.DOMAIN, + CONFIG_WITH_STATES, + ({"value_template": "{{ value_json.val }}"},), + ), + '{"val":"closed"}', + STATE_LOCKED, + ), + ( + help_custom_config( + lock.DOMAIN, + CONFIG_WITH_STATES, + ({"value_template": "{{ value_json.val }}"},), + ), + '{"val":"closing"}', + STATE_LOCKING, + ), + ( + help_custom_config( + lock.DOMAIN, + CONFIG_WITH_STATES, + ({"value_template": "{{ value_json.val }}"},), + ), + '{"val":"opening"}', + STATE_UNLOCKING, + ), + ( + help_custom_config( + lock.DOMAIN, + CONFIG_WITH_STATES, + ({"value_template": "{{ value_json.val }}"},), + ), + '{"val":"open"}', + STATE_UNLOCKED, + ), ], ) async def test_controlling_state_via_topic_and_json_message( hass: HomeAssistant, - mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator, - payload, - lock_state, + mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator, + payload: str, + lock_state: str, ) -> None: """Test the controlling state via topic and JSON message.""" - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - lock.DOMAIN: { - "name": "test", - "state_topic": "state-topic", - "command_topic": "command-topic", - "payload_lock": "LOCK", - "payload_unlock": "UNLOCK", - "state_locked": "LOCKED", - "state_locking": "LOCKING", - "state_unlocked": "UNLOCKED", - "state_unlocking": "UNLOCKING", - "value_template": "{{ value_json.val }}", - } - } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + await mqtt_mock_entry_no_yaml_config() state = hass.states.get("lock.test") assert state.state is STATE_UNLOCKED @@ -217,43 +205,54 @@ async def test_controlling_state_via_topic_and_json_message( @pytest.mark.parametrize( - ("payload", "lock_state"), + ("hass_config", "payload", "lock_state"), [ - ('{"val":"closed"}', STATE_LOCKED), - ('{"val":"closing"}', STATE_LOCKING), - ('{"val":"open"}', STATE_UNLOCKED), - ('{"val":"opening"}', STATE_UNLOCKING), + ( + help_custom_config( + lock.DOMAIN, + CONFIG_WITH_STATES, + ({"value_template": "{{ value_json.val }}"},), + ), + '{"val":"closed"}', + STATE_LOCKED, + ), + ( + help_custom_config( + lock.DOMAIN, + CONFIG_WITH_STATES, + ({"value_template": "{{ value_json.val }}"},), + ), + '{"val":"closing"}', + STATE_LOCKING, + ), + ( + help_custom_config( + lock.DOMAIN, + CONFIG_WITH_STATES, + ({"value_template": "{{ value_json.val }}"},), + ), + '{"val":"open"}', + STATE_UNLOCKED, + ), + ( + help_custom_config( + lock.DOMAIN, + CONFIG_WITH_STATES, + ({"value_template": "{{ value_json.val }}"},), + ), + '{"val":"opening"}', + STATE_UNLOCKING, + ), ], ) async def test_controlling_non_default_state_via_topic_and_json_message( hass: HomeAssistant, - mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator, - payload, - lock_state, + mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator, + payload: str, + lock_state: str, ) -> None: """Test the controlling state via topic and JSON message.""" - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - lock.DOMAIN: { - "name": "test", - "state_topic": "state-topic", - "command_topic": "command-topic", - "payload_lock": "LOCK", - "payload_unlock": "UNLOCK", - "state_locked": "closed", - "state_locking": "closing", - "state_unlocked": "open", - "state_unlocking": "opening", - "value_template": "{{ value_json.val }}", - } - } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + await mqtt_mock_entry_no_yaml_config() state = hass.states.get("lock.test") assert state.state is STATE_UNLOCKED @@ -264,13 +263,9 @@ async def test_controlling_non_default_state_via_topic_and_json_message( assert state.state is lock_state -async def test_sending_mqtt_commands_and_optimistic( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator -) -> None: - """Test optimistic mode without state topic.""" - assert await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { lock.DOMAIN: { @@ -282,10 +277,14 @@ async def test_sending_mqtt_commands_and_optimistic( "state_unlocked": "UNLOCKED", } } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + } + ], +) +async def test_sending_mqtt_commands_and_optimistic( + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator +) -> None: + """Test optimistic mode without state topic.""" + mqtt_mock = await mqtt_mock_entry_no_yaml_config() state = hass.states.get("lock.test") assert state.state is STATE_UNLOCKED @@ -312,13 +311,9 @@ async def test_sending_mqtt_commands_and_optimistic( assert state.attributes.get(ATTR_ASSUMED_STATE) -async def test_sending_mqtt_commands_with_template( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator -) -> None: - """Test sending commands with template.""" - assert await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { lock.DOMAIN: { @@ -333,10 +328,14 @@ async def test_sending_mqtt_commands_with_template( "state_unlocked": "UNLOCKED", } } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + } + ], +) +async def test_sending_mqtt_commands_with_template( + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator +) -> None: + """Test sending commands with template.""" + mqtt_mock = await mqtt_mock_entry_no_yaml_config() state = hass.states.get("lock.test") assert state.state is STATE_UNLOCKED @@ -373,30 +372,30 @@ async def test_sending_mqtt_commands_with_template( assert state.attributes.get(ATTR_ASSUMED_STATE) +@pytest.mark.parametrize( + "hass_config", + [ + { + mqtt.DOMAIN: { + lock.DOMAIN: { + "name": "test", + "state_topic": "state-topic", + "command_topic": "command-topic", + "payload_lock": "LOCK", + "payload_unlock": "UNLOCK", + "state_locked": "LOCKED", + "state_unlocked": "UNLOCKED", + "optimistic": True, + } + } + } + ], +) async def test_sending_mqtt_commands_and_explicit_optimistic( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator ) -> None: """Test optimistic mode without state topic.""" - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - lock.DOMAIN: { - "name": "test", - "state_topic": "state-topic", - "command_topic": "command-topic", - "payload_lock": "LOCK", - "payload_unlock": "UNLOCK", - "state_locked": "LOCKED", - "state_unlocked": "UNLOCKED", - "optimistic": True, - } - } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + mqtt_mock = await mqtt_mock_entry_no_yaml_config() state = hass.states.get("lock.test") assert state.state is STATE_UNLOCKED @@ -423,29 +422,29 @@ async def test_sending_mqtt_commands_and_explicit_optimistic( assert state.attributes.get(ATTR_ASSUMED_STATE) +@pytest.mark.parametrize( + "hass_config", + [ + { + mqtt.DOMAIN: { + lock.DOMAIN: { + "name": "test", + "command_topic": "command-topic", + "payload_lock": "LOCK", + "payload_unlock": "UNLOCK", + "payload_open": "OPEN", + "state_locked": "LOCKED", + "state_unlocked": "UNLOCKED", + } + } + } + ], +) async def test_sending_mqtt_commands_support_open_and_optimistic( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator ) -> None: """Test open function of the lock without state topic.""" - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - lock.DOMAIN: { - "name": "test", - "command_topic": "command-topic", - "payload_lock": "LOCK", - "payload_unlock": "UNLOCK", - "payload_open": "OPEN", - "state_locked": "LOCKED", - "state_unlocked": "UNLOCKED", - } - } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + mqtt_mock = await mqtt_mock_entry_no_yaml_config() state = hass.states.get("lock.test") assert state.state is STATE_UNLOCKED @@ -483,13 +482,9 @@ async def test_sending_mqtt_commands_support_open_and_optimistic( assert state.attributes.get(ATTR_ASSUMED_STATE) -async def test_sending_mqtt_commands_support_open_and_explicit_optimistic( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator -) -> None: - """Test open function of the lock without state topic.""" - assert await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { lock.DOMAIN: { @@ -504,10 +499,14 @@ async def test_sending_mqtt_commands_support_open_and_explicit_optimistic( "optimistic": True, } } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + } + ], +) +async def test_sending_mqtt_commands_support_open_and_explicit_optimistic( + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator +) -> None: + """Test open function of the lock without state topic.""" + mqtt_mock = await mqtt_mock_entry_no_yaml_config() state = hass.states.get("lock.test") assert state.state is STATE_UNLOCKED @@ -545,13 +544,9 @@ async def test_sending_mqtt_commands_support_open_and_explicit_optimistic( assert state.attributes.get(ATTR_ASSUMED_STATE) -async def test_sending_mqtt_commands_pessimistic( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator -) -> None: - """Test function of the lock with state topics.""" - assert await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { lock.DOMAIN: { @@ -568,10 +563,14 @@ async def test_sending_mqtt_commands_pessimistic( "state_jammed": "JAMMED", } } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + } + ], +) +async def test_sending_mqtt_commands_pessimistic( + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator +) -> None: + """Test function of the lock with state topics.""" + mqtt_mock = await mqtt_mock_entry_no_yaml_config() state = hass.states.get("lock.test") assert state.state is STATE_UNLOCKED diff --git a/tests/components/mqtt/test_mixins.py b/tests/components/mqtt/test_mixins.py index c9bcd07f26c..18d59f98675 100644 --- a/tests/components/mqtt/test_mixins.py +++ b/tests/components/mqtt/test_mixins.py @@ -2,28 +2,19 @@ from unittest.mock import patch +import pytest + from homeassistant.components import mqtt, sensor from homeassistant.const import EVENT_STATE_CHANGED, Platform from homeassistant.core import HomeAssistant, callback -from homeassistant.setup import async_setup_component from tests.common import async_fire_mqtt_message from tests.typing import MqttMockHAClientGenerator -@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR]) -async def test_availability_with_shared_state_topic( - hass: HomeAssistant, - mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator, -) -> None: - """Test the state is not changed twice. - - When an entity with a shared state_topic and availability_topic becomes available - The state should only change once. - """ - assert await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { sensor.DOMAIN: { @@ -36,10 +27,20 @@ async def test_availability_with_shared_state_topic( "availability_template": "{{ value != '0' }}", } } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + } + ], +) +@patch("homeassistant.components.mqtt.PLATFORMS", [Platform.SENSOR]) +async def test_availability_with_shared_state_topic( + hass: HomeAssistant, + mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator, +) -> None: + """Test the state is not changed twice. + + When an entity with a shared state_topic and availability_topic becomes available + The state should only change once. + """ + await mqtt_mock_entry_no_yaml_config() events = [] diff --git a/tests/components/mqtt/test_number.py b/tests/components/mqtt/test_number.py index eb2a6402284..bd28d75ac9a 100644 --- a/tests/components/mqtt/test_number.py +++ b/tests/components/mqtt/test_number.py @@ -30,7 +30,6 @@ from homeassistant.const import ( UnitOfTemperature, ) from homeassistant.core import HomeAssistant, State -from homeassistant.setup import async_setup_component from .test_common import ( help_test_availability_when_connection_lost, @@ -76,31 +75,30 @@ def number_platform_only(): yield -async def test_run_number_setup( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator -) -> None: - """Test that it fetches the given payload.""" - topic = "test/number" - await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { number.DOMAIN: { - "state_topic": topic, - "command_topic": topic, + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", "name": "Test Number", "device_class": "temperature", - "unit_of_measurement": UnitOfTemperature.FAHRENHEIT, + "unit_of_measurement": UnitOfTemperature.FAHRENHEIT.value, "payload_reset": "reset!", } } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + } + ], +) +async def test_run_number_setup( + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator +) -> None: + """Test that it fetches the given payload.""" + await mqtt_mock_entry_no_yaml_config() - async_fire_mqtt_message(hass, topic, "10") + async_fire_mqtt_message(hass, "test/state_number", "10") await hass.async_block_till_done() @@ -109,7 +107,7 @@ async def test_run_number_setup( assert state.attributes.get(ATTR_DEVICE_CLASS) == NumberDeviceClass.TEMPERATURE assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "°C" - async_fire_mqtt_message(hass, topic, "20.5") + async_fire_mqtt_message(hass, "test/state_number", "20.5") await hass.async_block_till_done() @@ -118,7 +116,7 @@ async def test_run_number_setup( assert state.attributes.get(ATTR_DEVICE_CLASS) == NumberDeviceClass.TEMPERATURE assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "°C" - async_fire_mqtt_message(hass, topic, "reset!") + async_fire_mqtt_message(hass, "test/state_number", "reset!") await hass.async_block_till_done() @@ -128,27 +126,27 @@ async def test_run_number_setup( assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "°C" -async def test_value_template( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator -) -> None: - """Test that it fetches the given payload with a template.""" - topic = "test/number" - await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { number.DOMAIN: { - "state_topic": topic, - "command_topic": topic, + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", "name": "Test Number", "value_template": "{{ value_json.val }}", } } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + } + ], +) +async def test_value_template( + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator +) -> None: + """Test that it fetches the given payload with a template.""" + topic = "test/state_number" + await mqtt_mock_entry_no_yaml_config() async_fire_mqtt_message(hass, topic, '{"val":10}') @@ -172,11 +170,25 @@ async def test_value_template( assert state.state == "unknown" +@pytest.mark.parametrize( + "hass_config", + [ + { + mqtt.DOMAIN: { + number.DOMAIN: { + "command_topic": "test/number", + "device_class": "temperature", + "unit_of_measurement": UnitOfTemperature.FAHRENHEIT.value, + "name": "Test Number", + } + } + } + ], +) async def test_restore_native_value( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator ) -> None: """Test that the stored native_value is restored.""" - topic = "test/number" RESTORE_DATA = { "native_max_value": None, # Ignored by MQTT number @@ -189,30 +201,28 @@ async def test_restore_native_value( mock_restore_cache_with_extra_data( hass, ((State("number.test_number", "abc"), RESTORE_DATA),) ) - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - number.DOMAIN: { - "command_topic": topic, - "device_class": "temperature", - "unit_of_measurement": UnitOfTemperature.FAHRENHEIT, - "name": "Test Number", - } - } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + await mqtt_mock_entry_no_yaml_config() state = hass.states.get("number.test_number") assert state.state == "37.8" assert state.attributes.get(ATTR_ASSUMED_STATE) +@pytest.mark.parametrize( + "hass_config", + [ + { + mqtt.DOMAIN: { + number.DOMAIN: { + "command_topic": "test/number", + "name": "Test Number", + } + } + } + ], +) async def test_run_number_service_optimistic( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator ) -> None: """Test that set_value service works in optimistic mode.""" topic = "test/number" @@ -228,20 +238,8 @@ async def test_run_number_service_optimistic( mock_restore_cache_with_extra_data( hass, ((State("number.test_number", "abc"), RESTORE_DATA),) ) - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - number.DOMAIN: { - "command_topic": topic, - "name": "Test Number", - } - } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + + mqtt_mock = await mqtt_mock_entry_no_yaml_config() state = hass.states.get("number.test_number") assert state.state == "3" @@ -287,8 +285,22 @@ async def test_run_number_service_optimistic( assert state.state == "42.1" +@pytest.mark.parametrize( + "hass_config", + [ + { + mqtt.DOMAIN: { + number.DOMAIN: { + "command_topic": "test/number", + "name": "Test Number", + "command_template": '{"number": {{ value }} }', + } + } + } + ], +) async def test_run_number_service_optimistic_with_command_template( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator ) -> None: """Test that set_value service works in optimistic mode and with a command_template.""" topic = "test/number" @@ -304,21 +316,7 @@ async def test_run_number_service_optimistic_with_command_template( mock_restore_cache_with_extra_data( hass, ((State("number.test_number", "abc"), RESTORE_DATA),) ) - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - number.DOMAIN: { - "command_topic": topic, - "name": "Test Number", - "command_template": '{"number": {{ value }} }', - } - } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + mqtt_mock = await mqtt_mock_entry_no_yaml_config() state = hass.states.get("number.test_number") assert state.state == "3" @@ -366,28 +364,28 @@ async def test_run_number_service_optimistic_with_command_template( assert state.state == "42.1" +@pytest.mark.parametrize( + "hass_config", + [ + { + mqtt.DOMAIN: { + number.DOMAIN: { + "command_topic": "test/number/set", + "state_topic": "test/number", + "name": "Test Number", + } + } + } + ], +) async def test_run_number_service( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator ) -> None: """Test that set_value service works in non optimistic mode.""" cmd_topic = "test/number/set" state_topic = "test/number" - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - number.DOMAIN: { - "command_topic": cmd_topic, - "state_topic": state_topic, - "name": "Test Number", - } - } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + mqtt_mock = await mqtt_mock_entry_no_yaml_config() async_fire_mqtt_message(hass, state_topic, "32") state = hass.states.get("number.test_number") @@ -404,29 +402,29 @@ async def test_run_number_service( assert state.state == "32" +@pytest.mark.parametrize( + "hass_config", + [ + { + mqtt.DOMAIN: { + number.DOMAIN: { + "command_topic": "test/number/set", + "state_topic": "test/number", + "name": "Test Number", + "command_template": '{"number": {{ value }} }', + } + } + } + ], +) async def test_run_number_service_with_command_template( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator ) -> None: """Test that set_value service works in non optimistic mode and with a command_template.""" cmd_topic = "test/number/set" state_topic = "test/number" - assert await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - number.DOMAIN: { - "command_topic": cmd_topic, - "state_topic": state_topic, - "name": "Test Number", - "command_template": '{"number": {{ value }} }', - } - } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + mqtt_mock = await mqtt_mock_entry_no_yaml_config() async_fire_mqtt_message(hass, state_topic, "32") state = hass.states.get("number.test_number") @@ -732,29 +730,28 @@ async def test_entity_debug_info_message( ) -async def test_min_max_step_attributes( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator -) -> None: - """Test min/max/step attributes.""" - topic = "test/number" - await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { number.DOMAIN: { - "state_topic": topic, - "command_topic": topic, + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", "name": "Test Number", "min": 5, "max": 110, "step": 20, } } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + } + ], +) +async def test_min_max_step_attributes( + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator +) -> None: + """Test min/max/step attributes.""" + await mqtt_mock_entry_no_yaml_config() state = hass.states.get("number.test_number") assert state.attributes.get(ATTR_MIN) == 5 @@ -762,129 +759,180 @@ async def test_min_max_step_attributes( assert state.attributes.get(ATTR_STEP) == 20 -async def test_invalid_min_max_attributes( - hass: HomeAssistant, caplog: pytest.LogCaptureFixture -) -> None: - """Test invalid min/max attributes.""" - topic = "test/number" - assert not await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { number.DOMAIN: { - "state_topic": topic, - "command_topic": topic, + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", "name": "Test Number", "min": 35, "max": 10, } } - }, - ) - + } + ], +) +async def test_invalid_min_max_attributes( + hass: HomeAssistant, + mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator, + caplog: pytest.LogCaptureFixture, +) -> None: + """Test invalid min/max attributes.""" + with pytest.raises(AssertionError): + await mqtt_mock_entry_no_yaml_config() assert f"'{CONF_MAX}' must be > '{CONF_MIN}'" in caplog.text -async def test_default_mode( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator -) -> None: - """Test default mode.""" - topic = "test/number" - await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { number.DOMAIN: { - "state_topic": topic, - "command_topic": topic, + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", "name": "Test Number", } } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + } + ], +) +async def test_default_mode( + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator +) -> None: + """Test default mode.""" + await mqtt_mock_entry_no_yaml_config() state = hass.states.get("number.test_number") assert state.attributes.get(ATTR_MODE) == "auto" -@pytest.mark.parametrize("mode", ("auto", "box", "slider")) +@pytest.mark.parametrize( + ("hass_config", "mode"), + [ + ( + { + mqtt.DOMAIN: { + number.DOMAIN: { + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", + "name": "Test Number", + "mode": "auto", + } + } + }, + "auto", + ), + ( + { + mqtt.DOMAIN: { + number.DOMAIN: { + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", + "name": "Test Number", + "mode": "box", + } + } + }, + "box", + ), + ( + { + mqtt.DOMAIN: { + number.DOMAIN: { + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", + "name": "Test Number", + "mode": "slider", + } + } + }, + "slider", + ), + ], +) async def test_mode( hass: HomeAssistant, - mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator, + mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator, mode, ) -> None: """Test mode.""" - topic = "test/number" - await async_setup_component( - hass, - mqtt.DOMAIN, - { - mqtt.DOMAIN: { - number.DOMAIN: { - "state_topic": topic, - "command_topic": topic, - "name": "Test Number", - "mode": mode, - } - } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + await mqtt_mock_entry_no_yaml_config() state = hass.states.get("number.test_number") assert state.attributes.get(ATTR_MODE) == mode -@pytest.mark.parametrize(("mode", "valid"), [("bleh", False), ("auto", True)]) -async def test_invalid_mode(hass: HomeAssistant, mode, valid) -> None: - """Test invalid mode.""" - topic = "test/number" - assert ( - await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + ("hass_config", "valid"), + [ + ( { mqtt.DOMAIN: { number.DOMAIN: { - "state_topic": topic, - "command_topic": topic, + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", "name": "Test Number", - "mode": mode, + "mode": "bleh", } } }, - ) - is valid - ) - - -async def test_mqtt_payload_not_a_number_warning( + False, + ), + ( + { + mqtt.DOMAIN: { + number.DOMAIN: { + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", + "name": "Test Number", + "mode": "auto", + } + } + }, + True, + ), + ], +) +async def test_invalid_mode( hass: HomeAssistant, - caplog: pytest.LogCaptureFixture, - mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator, + mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator, + valid: bool, ) -> None: - """Test warning for MQTT payload which is not a number.""" - topic = "test/number" - assert await async_setup_component( - hass, - mqtt.DOMAIN, + """Test invalid mode.""" + if valid: + await mqtt_mock_entry_no_yaml_config() + return + with pytest.raises(AssertionError): + await mqtt_mock_entry_no_yaml_config() + + +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { number.DOMAIN: { - "state_topic": topic, - "command_topic": topic, + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", "name": "Test Number", } } - }, - ) - await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + } + ], +) +async def test_mqtt_payload_not_a_number_warning( + hass: HomeAssistant, + caplog: pytest.LogCaptureFixture, + mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator, +) -> None: + """Test warning for MQTT payload which is not a number.""" + topic = "test/state_number" + + await mqtt_mock_entry_no_yaml_config() async_fire_mqtt_message(hass, topic, "not_a_number") @@ -893,30 +941,32 @@ async def test_mqtt_payload_not_a_number_warning( assert "Payload 'not_a_number' is not a Number" in caplog.text -async def test_mqtt_payload_out_of_range_error( - hass: HomeAssistant, - caplog: pytest.LogCaptureFixture, - mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator, -) -> None: - """Test error when MQTT payload is out of min/max range.""" - topic = "test/number" - await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { number.DOMAIN: { - "state_topic": topic, - "command_topic": topic, + "state_topic": "test/state_number", + "command_topic": "test/cmd_number", "name": "Test Number", "min": 5, "max": 110, } } - }, - ) + } + ], +) +async def test_mqtt_payload_out_of_range_error( + hass: HomeAssistant, + caplog: pytest.LogCaptureFixture, + mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator, +) -> None: + """Test error when MQTT payload is out of min/max range.""" + topic = "test/state_number" + await hass.async_block_till_done() - await mqtt_mock_entry_with_yaml_config() + await mqtt_mock_entry_no_yaml_config() async_fire_mqtt_message(hass, topic, "115.5") diff --git a/tests/components/mqtt/test_scene.py b/tests/components/mqtt/test_scene.py index 3da5fd4f36a..56350c90c0d 100644 --- a/tests/components/mqtt/test_scene.py +++ b/tests/components/mqtt/test_scene.py @@ -7,7 +7,6 @@ import pytest from homeassistant.components import mqtt, scene from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_ON, STATE_UNKNOWN, Platform from homeassistant.core import HomeAssistant, State -from homeassistant.setup import async_setup_component from .test_common import ( help_test_availability_when_connection_lost, @@ -44,16 +43,9 @@ def scene_platform_only(): yield -async def test_sending_mqtt_commands( - hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator -) -> None: - """Test the sending MQTT commands.""" - fake_state = State("scene.test", STATE_UNKNOWN) - mock_restore_cache(hass, (fake_state,)) - - assert await async_setup_component( - hass, - mqtt.DOMAIN, +@pytest.mark.parametrize( + "hass_config", + [ { mqtt.DOMAIN: { scene.DOMAIN: { @@ -62,10 +54,17 @@ async def test_sending_mqtt_commands( "payload_on": "beer on", }, } - }, - ) - await hass.async_block_till_done() - mqtt_mock = await mqtt_mock_entry_with_yaml_config() + } + ], +) +async def test_sending_mqtt_commands( + hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator +) -> None: + """Test the sending MQTT commands.""" + fake_state = State("scene.test", STATE_UNKNOWN) + mock_restore_cache(hass, (fake_state,)) + + mqtt_mock = await mqtt_mock_entry_no_yaml_config() state = hass.states.get("scene.test") assert state.state == STATE_UNKNOWN