Prepare MQTT platform tests part4 (#90107)

* Tests humidifier

* Tests legacy_vacuum
pull/90189/head
Jan Bouwhuis 2023-03-23 19:14:44 +01:00 committed by GitHub
parent 44add1dc11
commit 2c1b59be0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 398 additions and 414 deletions

View File

@ -14,7 +14,6 @@ from homeassistant.components.humidifier import (
SERVICE_SET_HUMIDITY,
SERVICE_SET_MODE,
)
from homeassistant.components.mqtt import CONFIG_SCHEMA
from homeassistant.components.mqtt.humidifier import (
CONF_MODE_COMMAND_TOPIC,
CONF_MODE_STATE_TOPIC,
@ -34,7 +33,6 @@ from homeassistant.const import (
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from .test_common import (
help_test_availability_when_connection_lost,
@ -130,30 +128,26 @@ async def async_set_humidity(
await hass.services.async_call(DOMAIN, SERVICE_SET_HUMIDITY, data, blocking=True)
@pytest.mark.parametrize(
"hass_config", [{mqtt.DOMAIN: {humidifier.DOMAIN: {"name": "test"}}}]
)
async def test_fail_setup_if_no_command_topic(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test if command fails with command topic."""
assert not await async_setup_component(
hass,
mqtt.DOMAIN,
{mqtt.DOMAIN: {humidifier.DOMAIN: {"name": "test"}}},
)
with pytest.raises(AssertionError):
await mqtt_mock_entry_no_yaml_config()
assert (
"Invalid config for [mqtt]: required key not provided @ data['mqtt']['humidifier'][0]['command_topic']. Got None"
in caplog.text
)
async def test_controlling_state_via_topic(
hass: HomeAssistant,
mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test the controlling state via topic."""
assert await async_setup_component(
hass,
mqtt.DOMAIN,
@pytest.mark.parametrize(
"hass_config",
[
{
mqtt.DOMAIN: {
humidifier.DOMAIN: {
@ -178,10 +172,16 @@ async def test_controlling_state_via_topic(
"payload_reset_mode": "rEset_mode",
}
}
},
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
}
],
)
async def test_controlling_state_via_topic(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test the controlling state via topic."""
await mqtt_mock_entry_no_yaml_config()
state = hass.states.get("humidifier.test")
assert state.state == STATE_UNKNOWN
@ -252,15 +252,9 @@ async def test_controlling_state_via_topic(
assert state.state == STATE_UNKNOWN
async def test_controlling_state_via_topic_and_json_message(
hass: HomeAssistant,
mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test the controlling state via topic and JSON message."""
assert await async_setup_component(
hass,
mqtt.DOMAIN,
@pytest.mark.parametrize(
"hass_config",
[
{
mqtt.DOMAIN: {
humidifier.DOMAIN: {
@ -281,10 +275,17 @@ async def test_controlling_state_via_topic_and_json_message(
"mode_state_template": "{{ value_json.val }}",
}
}
},
)
}
],
)
async def test_controlling_state_via_topic_and_json_message(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test the controlling state via topic and JSON message."""
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
state = hass.states.get("humidifier.test")
assert state.state == STATE_UNKNOWN
@ -343,15 +344,9 @@ async def test_controlling_state_via_topic_and_json_message(
assert state.state == STATE_UNKNOWN
async def test_controlling_state_via_topic_and_json_message_shared_topic(
hass: HomeAssistant,
mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test the controlling state via topic and JSON message using a shared topic."""
assert await async_setup_component(
hass,
mqtt.DOMAIN,
@pytest.mark.parametrize(
"hass_config",
[
{
mqtt.DOMAIN: {
humidifier.DOMAIN: {
@ -372,10 +367,16 @@ async def test_controlling_state_via_topic_and_json_message_shared_topic(
"mode_state_template": "{{ value_json.mode }}",
}
}
},
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
}
],
)
async def test_controlling_state_via_topic_and_json_message_shared_topic(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test the controlling state via topic and JSON message using a shared topic."""
await mqtt_mock_entry_no_yaml_config()
state = hass.states.get("humidifier.test")
assert state.state == STATE_UNKNOWN
@ -422,15 +423,9 @@ async def test_controlling_state_via_topic_and_json_message_shared_topic(
caplog.clear()
async def test_sending_mqtt_commands_and_optimistic(
hass: HomeAssistant,
mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test optimistic mode without state topic."""
assert await async_setup_component(
hass,
mqtt.DOMAIN,
@pytest.mark.parametrize(
"hass_config",
[
{
mqtt.DOMAIN: {
humidifier.DOMAIN: {
@ -447,10 +442,16 @@ async def test_sending_mqtt_commands_and_optimistic(
],
}
}
},
)
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,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test optimistic mode without state topic."""
mqtt_mock = await mqtt_mock_entry_no_yaml_config()
state = hass.states.get("humidifier.test")
assert state.state == STATE_UNKNOWN
@ -521,15 +522,9 @@ async def test_sending_mqtt_commands_and_optimistic(
assert state.attributes.get(ATTR_ASSUMED_STATE)
async def test_sending_mqtt_command_templates_(
hass: HomeAssistant,
mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Testing command templates with optimistic mode without state topic."""
assert await async_setup_component(
hass,
mqtt.DOMAIN,
@pytest.mark.parametrize(
"hass_config",
[
{
mqtt.DOMAIN: {
humidifier.DOMAIN: {
@ -547,10 +542,16 @@ async def test_sending_mqtt_command_templates_(
],
}
}
},
)
await hass.async_block_till_done()
mqtt_mock = await mqtt_mock_entry_with_yaml_config()
}
],
)
async def test_sending_mqtt_command_templates_(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Testing command templates with optimistic mode without state topic."""
mqtt_mock = await mqtt_mock_entry_no_yaml_config()
state = hass.states.get("humidifier.test")
assert state.state == STATE_UNKNOWN
@ -621,15 +622,9 @@ async def test_sending_mqtt_command_templates_(
assert state.attributes.get(ATTR_ASSUMED_STATE)
async def test_sending_mqtt_commands_and_explicit_optimistic(
hass: HomeAssistant,
mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test optimistic mode with state topic and turn on attributes."""
assert await async_setup_component(
hass,
mqtt.DOMAIN,
@pytest.mark.parametrize(
"hass_config",
[
{
mqtt.DOMAIN: {
humidifier.DOMAIN: {
@ -648,10 +643,16 @@ async def test_sending_mqtt_commands_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_and_explicit_optimistic(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test optimistic mode with state topic and turn on attributes."""
mqtt_mock = await mqtt_mock_entry_no_yaml_config()
state = hass.states.get("humidifier.test")
assert state.state == STATE_UNKNOWN
@ -774,15 +775,9 @@ async def test_encoding_subscribable_topics(
)
async def test_attributes(
hass: HomeAssistant,
mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test attributes."""
assert await async_setup_component(
hass,
mqtt.DOMAIN,
@pytest.mark.parametrize(
"hass_config",
[
{
mqtt.DOMAIN: {
humidifier.DOMAIN: {
@ -796,10 +791,16 @@ async def test_attributes(
],
}
}
},
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
}
],
)
async def test_attributes(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test attributes."""
await mqtt_mock_entry_no_yaml_config()
state = hass.states.get("humidifier.test")
assert state.state == STATE_UNKNOWN
@ -826,105 +827,142 @@ async def test_attributes(
@pytest.mark.parametrize(
("config", "valid"),
("hass_config", "valid"),
[
(
{
"name": "test_valid_1",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test_valid_1",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
}
}
},
True,
),
(
{
"name": "test_valid_2",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"device_class": "humidifier",
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test_valid_2",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"device_class": "humidifier",
}
}
},
True,
),
(
{
"name": "test_valid_3",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"device_class": "dehumidifier",
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test_valid_3",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"device_class": "dehumidifier",
}
}
},
True,
),
(
{
"name": "test_invalid_device_class",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"device_class": "notsupporedSpeci@l",
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test_invalid_device_class",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"device_class": "notsupporedSpeci@l",
}
}
},
False,
),
(
{
"name": "test_mode_command_without_modes",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"mode_command_topic": "mode-command-topic",
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test_mode_command_without_modes",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"mode_command_topic": "mode-command-topic",
}
}
},
False,
),
(
{
"name": "test_invalid_humidity_min_max_1",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"min_humidity": 0,
"max_humidity": 101,
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test_invalid_humidity_min_max_1",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"min_humidity": 0,
"max_humidity": 101,
}
}
},
False,
),
(
{
"name": "test_invalid_humidity_min_max_2",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"max_humidity": 20,
"min_humidity": 40,
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test_invalid_humidity_min_max_2",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"max_humidity": 20,
"min_humidity": 40,
}
}
},
False,
),
(
{
"name": "test_invalid_mode_is_reset",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"mode_command_topic": "mode-command-topic",
"modes": ["eco", "None"],
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test_invalid_mode_is_reset",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"mode_command_topic": "mode-command-topic",
"modes": ["eco", "None"],
}
}
},
False,
),
],
)
async def test_validity_configurations(hass: HomeAssistant, config, valid) -> None:
async def test_validity_configurations(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
valid: bool,
) -> None:
"""Test validity of configurations."""
assert (
await async_setup_component(
hass,
mqtt.DOMAIN,
{mqtt.DOMAIN: {humidifier.DOMAIN: config}},
)
is valid
)
if valid:
await mqtt_mock_entry_no_yaml_config()
return
with pytest.raises(AssertionError):
await mqtt_mock_entry_no_yaml_config()
@pytest.mark.parametrize(
("name", "config", "success", "features"),
("name", "hass_config", "success", "features"),
[
(
"test1",
{
"name": "test1",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test1",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
}
}
},
True,
0,
@ -932,21 +970,29 @@ async def test_validity_configurations(hass: HomeAssistant, config, valid) -> No
(
"test2",
{
"name": "test2",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"mode_command_topic": "mode-command-topic",
"modes": ["eco", "auto"],
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test2",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"mode_command_topic": "mode-command-topic",
"modes": ["eco", "auto"],
}
}
},
True,
humidifier.SUPPORT_MODES,
humidifier.HumidifierEntityFeature.MODES,
),
(
"test3",
{
"name": "test3",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test3",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
}
}
},
True,
0,
@ -954,20 +1000,28 @@ async def test_validity_configurations(hass: HomeAssistant, config, valid) -> No
(
"test4",
{
"name": "test4",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"mode_command_topic": "mode-command-topic",
"modes": ["eco", "auto"],
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test4",
"command_topic": "command-topic",
"target_humidity_command_topic": "humidity-command-topic",
"mode_command_topic": "mode-command-topic",
"modes": ["eco", "auto"],
}
}
},
True,
humidifier.SUPPORT_MODES,
humidifier.HumidifierEntityFeature.MODES,
),
(
"test5",
{
"name": "test5",
"command_topic": "command-topic",
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test5",
"command_topic": "command-topic",
}
}
},
False,
None,
@ -975,8 +1029,12 @@ async def test_validity_configurations(hass: HomeAssistant, config, valid) -> No
(
"test6",
{
"name": "test6",
"target_humidity_command_topic": "humidity-command-topic",
mqtt.DOMAIN: {
humidifier.DOMAIN: {
"name": "test6",
"target_humidity_command_topic": "humidity-command-topic",
}
}
},
False,
None,
@ -985,27 +1043,20 @@ async def test_validity_configurations(hass: HomeAssistant, config, valid) -> No
)
async def test_supported_features(
hass: HomeAssistant,
mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator,
name,
config,
success,
features,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
name: str,
success: bool,
features: humidifier.HumidifierEntityFeature | None,
) -> None:
"""Test supported features."""
assert (
await async_setup_component(
hass,
mqtt.DOMAIN,
{mqtt.DOMAIN: {humidifier.DOMAIN: config}},
)
is success
)
if success:
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
state = hass.states.get(f"humidifier.{name}")
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == features
return
with pytest.raises(AssertionError):
await mqtt_mock_entry_no_yaml_config()
@pytest.mark.parametrize("hass_config", [DEFAULT_CONFIG])
@ -1388,17 +1439,6 @@ async def test_setup_manual_entity_from_yaml(
assert hass.states.get(f"{platform}.test")
async def test_config_schema_validation(hass: HomeAssistant) -> None:
"""Test invalid platform options in the config schema do not pass the config validation."""
platform = humidifier.DOMAIN
config = copy.deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][platform])
config["name"] = "test"
CONFIG_SCHEMA({mqtt.DOMAIN: {platform: config}})
CONFIG_SCHEMA({mqtt.DOMAIN: {platform: [config]}})
with pytest.raises(MultipleInvalid):
CONFIG_SCHEMA({mqtt.DOMAIN: {platform: [{"bla": "bla"}]}})
async def test_unload_config_entry(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,

View File

@ -32,9 +32,10 @@ from homeassistant.components.vacuum import (
)
from homeassistant.const import CONF_NAME, STATE_OFF, STATE_ON, Platform
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from homeassistant.helpers.typing import ConfigType
from .test_common import (
help_custom_config,
help_test_availability_when_connection_lost,
help_test_availability_without_topic,
help_test_custom_availability_payload,
@ -92,6 +93,28 @@ DEFAULT_CONFIG = {
DEFAULT_CONFIG_2 = {mqtt.DOMAIN: {vacuum.DOMAIN: {"name": "test"}}}
DEFAULT_CONFIG_ALL_SERVICES = help_custom_config(
vacuum.DOMAIN,
DEFAULT_CONFIG,
(
{
mqttvacuum.CONF_SUPPORTED_FEATURES: services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
},
),
)
def filter_options(default_config: ConfigType, options: set[str]) -> ConfigType:
"""Generate a config from a default config with omitted options."""
options_base: ConfigType = default_config[mqtt.DOMAIN][vacuum.DOMAIN]
config = deepcopy(default_config)
config[mqtt.DOMAIN][vacuum.DOMAIN] = {
key: value for key, value in options_base.items() if key not in options
}
return config
@pytest.fixture(autouse=True)
def vacuum_platform_only():
@ -100,13 +123,12 @@ def vacuum_platform_only():
yield
@pytest.mark.parametrize("hass_config", [DEFAULT_CONFIG])
async def test_default_supported_features(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test that the correct supported features."""
assert await async_setup_component(hass, mqtt.DOMAIN, DEFAULT_CONFIG)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
entity = hass.states.get("vacuum.mqtttest")
entity_features = entity.attributes.get(mqttvacuum.CONF_SUPPORTED_FEATURES, 0)
assert sorted(services_to_strings(entity_features, SERVICE_TO_STRING)) == sorted(
@ -122,20 +144,15 @@ async def test_default_supported_features(
)
@pytest.mark.parametrize(
"hass_config",
[DEFAULT_CONFIG_ALL_SERVICES],
)
async def test_all_commands(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test simple commands to the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
mqtt_mock = await mqtt_mock_entry_with_yaml_config()
mqtt_mock = await mqtt_mock_entry_no_yaml_config()
await common.async_turn_on(hass, "vacuum.mqtttest")
mqtt_mock.async_publish.assert_called_once_with(
@ -206,21 +223,27 @@ async def test_all_commands(
}
@pytest.mark.parametrize(
"hass_config",
[
help_custom_config(
vacuum.DOMAIN,
DEFAULT_CONFIG,
(
{
mqttvacuum.CONF_SUPPORTED_FEATURES: services_to_strings(
mqttvacuum.STRING_TO_SERVICE["status"], SERVICE_TO_STRING
)
},
),
)
],
)
async def test_commands_without_supported_features(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test commands which are not supported by the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
services = mqttvacuum.STRING_TO_SERVICE["status"]
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
services, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
mqtt_mock = await mqtt_mock_entry_with_yaml_config()
mqtt_mock = await mqtt_mock_entry_no_yaml_config()
await common.async_turn_on(hass, "vacuum.mqtttest")
mqtt_mock.async_publish.assert_not_called()
@ -259,21 +282,27 @@ async def test_commands_without_supported_features(
mqtt_mock.async_publish.reset_mock()
@pytest.mark.parametrize(
"hass_config",
[
help_custom_config(
vacuum.DOMAIN,
DEFAULT_CONFIG,
(
{
mqttvacuum.CONF_SUPPORTED_FEATURES: services_to_strings(
mqttvacuum.STRING_TO_SERVICE["turn_on"], SERVICE_TO_STRING
)
},
),
)
],
)
async def test_attributes_without_supported_features(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test attributes which are not supported by the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
services = mqttvacuum.STRING_TO_SERVICE["turn_on"]
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
services, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
message = """{
"battery_level": 54,
@ -291,20 +320,15 @@ async def test_attributes_without_supported_features(
assert state.attributes.get(ATTR_FAN_SPEED_LIST) is None
@pytest.mark.parametrize(
"hass_config",
[DEFAULT_CONFIG_ALL_SERVICES],
)
async def test_status(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test status updates from the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
message = """{
"battery_level": 54,
@ -336,20 +360,15 @@ async def test_status(
assert state.attributes.get(ATTR_FAN_SPEED) == "min"
@pytest.mark.parametrize(
"hass_config",
[DEFAULT_CONFIG_ALL_SERVICES],
)
async def test_status_battery(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test status updates from the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
message = """{
"battery_level": 54
@ -359,20 +378,16 @@ async def test_status_battery(
assert state.attributes.get(ATTR_BATTERY_ICON) == "mdi:battery-50"
@pytest.mark.parametrize(
"hass_config",
[DEFAULT_CONFIG_ALL_SERVICES],
)
async def test_status_cleaning(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test status updates from the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
message = """{
"cleaning": true
@ -382,20 +397,15 @@ async def test_status_cleaning(
assert state.state == STATE_ON
@pytest.mark.parametrize(
"hass_config",
[DEFAULT_CONFIG_ALL_SERVICES],
)
async def test_status_docked(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test status updates from the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
message = """{
"docked": true
@ -405,20 +415,15 @@ async def test_status_docked(
assert state.state == STATE_OFF
@pytest.mark.parametrize(
"hass_config",
[DEFAULT_CONFIG_ALL_SERVICES],
)
async def test_status_charging(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test status updates from the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
message = """{
"charging": true
@ -428,20 +433,12 @@ async def test_status_charging(
assert state.attributes.get(ATTR_BATTERY_ICON) == "mdi:battery-outline"
@pytest.mark.parametrize("hass_config", [DEFAULT_CONFIG_ALL_SERVICES])
async def test_status_fan_speed(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test status updates from the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
message = """{
"fan_speed": "max"
@ -451,62 +448,52 @@ async def test_status_fan_speed(
assert state.attributes.get(ATTR_FAN_SPEED) == "max"
@pytest.mark.parametrize("hass_config", [DEFAULT_CONFIG_ALL_SERVICES])
async def test_status_fan_speed_list(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test status updates from the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
state = hass.states.get("vacuum.mqtttest")
assert state.attributes.get(ATTR_FAN_SPEED_LIST) == ["min", "medium", "high", "max"]
@pytest.mark.parametrize(
"hass_config",
[
help_custom_config(
vacuum.DOMAIN,
DEFAULT_CONFIG,
(
{
mqttvacuum.CONF_SUPPORTED_FEATURES: services_to_strings(
ALL_SERVICES - VacuumEntityFeature.FAN_SPEED, SERVICE_TO_STRING
)
},
),
)
],
)
async def test_status_no_fan_speed_list(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test status updates from the vacuum.
If the vacuum doesn't support fan speed, fan speed list should be None.
"""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
services = ALL_SERVICES - VacuumEntityFeature.FAN_SPEED
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
services, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
state = hass.states.get("vacuum.mqtttest")
assert state.attributes.get(ATTR_FAN_SPEED_LIST) is None
@pytest.mark.parametrize("hass_config", [DEFAULT_CONFIG_ALL_SERVICES])
async def test_status_error(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test status updates from the vacuum."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
await mqtt_mock_entry_no_yaml_config()
message = """{
"error": "Error1"
@ -523,26 +510,26 @@ async def test_status_error(
assert state.attributes.get(ATTR_STATUS) == "Stopped"
@pytest.mark.parametrize(
"hass_config",
[
help_custom_config(
vacuum.DOMAIN,
DEFAULT_CONFIG,
(
{
mqttvacuum.CONF_BATTERY_LEVEL_TOPIC: "retroroomba/battery_level",
mqttvacuum.CONF_BATTERY_LEVEL_TEMPLATE: "{{ value }}",
},
),
)
],
)
async def test_battery_template(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test that you can use non-default templates for battery_level."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config.update(
{
mqttvacuum.CONF_SUPPORTED_FEATURES: services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
),
mqttvacuum.CONF_BATTERY_LEVEL_TOPIC: "retroroomba/battery_level",
mqttvacuum.CONF_BATTERY_LEVEL_TEMPLATE: "{{ value }}",
}
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
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, "retroroomba/battery_level", "54")
state = hass.states.get("vacuum.mqtttest")
@ -550,20 +537,12 @@ async def test_battery_template(
assert state.attributes.get(ATTR_BATTERY_ICON) == "mdi:battery-50"
@pytest.mark.parametrize("hass_config", [DEFAULT_CONFIG_ALL_SERVICES])
async def test_status_invalid_json(
hass: HomeAssistant, mqtt_mock_entry_with_yaml_config: MqttMockHAClientGenerator
hass: HomeAssistant, mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator
) -> None:
"""Test to make sure nothing breaks if the vacuum sends bad JSON."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config[mqttvacuum.CONF_SUPPORTED_FEATURES] = services_to_strings(
ALL_SERVICES, SERVICE_TO_STRING
)
assert await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
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, "vacuum/state", '{"asdfasas false}')
state = hass.states.get("vacuum.mqtttest")
@ -571,63 +550,28 @@ async def test_status_invalid_json(
assert state.attributes.get(ATTR_STATUS) == "Stopped"
async def test_missing_battery_template(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(
"hass_config",
[
filter_options(DEFAULT_CONFIG, {mqttvacuum.CONF_BATTERY_LEVEL_TEMPLATE}),
filter_options(DEFAULT_CONFIG, {mqttvacuum.CONF_CHARGING_TEMPLATE}),
filter_options(DEFAULT_CONFIG, {mqttvacuum.CONF_CLEANING_TEMPLATE}),
filter_options(DEFAULT_CONFIG, {mqttvacuum.CONF_DOCKED_TEMPLATE}),
filter_options(DEFAULT_CONFIG, {mqttvacuum.CONF_ERROR_TEMPLATE}),
filter_options(DEFAULT_CONFIG, {mqttvacuum.CONF_FAN_SPEED_TEMPLATE}),
],
)
async def test_missing_templates(
hass: HomeAssistant,
mqtt_mock_entry_no_yaml_config: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test to make sure missing template is not allowed."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config.pop(mqttvacuum.CONF_BATTERY_LEVEL_TEMPLATE)
assert not await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
async def test_missing_charging_template(hass: HomeAssistant) -> None:
"""Test to make sure missing template is not allowed."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config.pop(mqttvacuum.CONF_CHARGING_TEMPLATE)
assert not await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
async def test_missing_cleaning_template(hass: HomeAssistant) -> None:
"""Test to make sure missing template is not allowed."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config.pop(mqttvacuum.CONF_CLEANING_TEMPLATE)
assert not await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
async def test_missing_docked_template(hass: HomeAssistant) -> None:
"""Test to make sure missing template is not allowed."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config.pop(mqttvacuum.CONF_DOCKED_TEMPLATE)
assert not await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
async def test_missing_error_template(hass: HomeAssistant) -> None:
"""Test to make sure missing template is not allowed."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config.pop(mqttvacuum.CONF_ERROR_TEMPLATE)
assert not await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
)
async def test_missing_fan_speed_template(hass: HomeAssistant) -> None:
"""Test to make sure missing template is not allowed."""
config = deepcopy(DEFAULT_CONFIG[mqtt.DOMAIN][vacuum.DOMAIN])
config.pop(mqttvacuum.CONF_FAN_SPEED_TEMPLATE)
assert not await async_setup_component(
hass, mqtt.DOMAIN, {mqtt.DOMAIN: {vacuum.DOMAIN: config}}
with pytest.raises(AssertionError):
await mqtt_mock_entry_no_yaml_config()
assert (
"Invalid config for [mqtt]: some but not all values in the same group of inclusion"
in caplog.text
)