Add better testing to vacuum platform (#112523)

* Add better testing to vacuum platform

* remove state strings

* some of the MR comments

* move MockVacuum

* remove manifest extra

* fix linting

* fix other linting

* Fix create entity calls

* Format

* remove create_entity

* change to match notify

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
pull/117127/head
Luke Lashley 2024-05-08 18:33:23 -04:00 committed by GitHub
parent f9413fcc9c
commit a77add1b77
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 308 additions and 1 deletions

View File

@ -1 +1,84 @@
"""The tests for vacuum platforms."""
from typing import Any
from homeassistant.components.vacuum import (
DOMAIN,
STATE_CLEANING,
STATE_DOCKED,
STATE_IDLE,
STATE_PAUSED,
STATE_RETURNING,
StateVacuumEntity,
VacuumEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from tests.common import MockEntity
class MockVacuum(MockEntity, StateVacuumEntity):
"""Mock vacuum class."""
_attr_supported_features = (
VacuumEntityFeature.PAUSE
| VacuumEntityFeature.STOP
| VacuumEntityFeature.RETURN_HOME
| VacuumEntityFeature.FAN_SPEED
| VacuumEntityFeature.BATTERY
| VacuumEntityFeature.CLEAN_SPOT
| VacuumEntityFeature.MAP
| VacuumEntityFeature.STATE
| VacuumEntityFeature.START
)
_attr_battery_level = 99
_attr_fan_speed_list = ["slow", "fast"]
def __init__(self, **values: Any) -> None:
"""Initialize a mock vacuum entity."""
super().__init__(**values)
self._attr_state = STATE_DOCKED
self._attr_fan_speed = "slow"
def stop(self, **kwargs: Any) -> None:
"""Stop cleaning."""
self._attr_state = STATE_IDLE
def return_to_base(self, **kwargs: Any) -> None:
"""Return to base."""
self._attr_state = STATE_RETURNING
def clean_spot(self, **kwargs: Any) -> None:
"""Clean a spot."""
self._attr_state = STATE_CLEANING
def set_fan_speed(self, fan_speed: str, **kwargs: Any) -> None:
"""Set the fan speed."""
self._attr_fan_speed = fan_speed
def start(self) -> None:
"""Start cleaning."""
self._attr_state = STATE_CLEANING
def pause(self) -> None:
"""Pause cleaning."""
self._attr_state = STATE_PAUSED
async def help_async_setup_entry_init(
hass: HomeAssistant, config_entry: ConfigEntry
) -> bool:
"""Set up test config entry."""
await hass.config_entries.async_forward_entry_setup(config_entry, DOMAIN)
return True
async def help_async_unload_entry(
hass: HomeAssistant, config_entry: ConfigEntry
) -> bool:
"""Unload test config emntry."""
return await hass.config_entries.async_unload_platforms(
config_entry, [Platform.VACUUM]
)

View File

@ -0,0 +1,23 @@
"""Fixtures for Vacuum platform tests."""
from collections.abc import Generator
import pytest
from homeassistant.config_entries import ConfigFlow
from homeassistant.core import HomeAssistant
from tests.common import mock_config_flow, mock_platform
class MockFlow(ConfigFlow):
"""Test flow."""
@pytest.fixture
def config_flow_fixture(hass: HomeAssistant) -> Generator[None, None, None]:
"""Mock config flow."""
mock_platform(hass, "test.config_flow")
with mock_config_flow("test", MockFlow):
yield

View File

@ -2,9 +2,210 @@
from __future__ import annotations
from homeassistant.components.vacuum import StateVacuumEntity, VacuumEntityFeature
from typing import Any
import pytest
from homeassistant.components.vacuum import (
DOMAIN,
SERVICE_CLEAN_SPOT,
SERVICE_LOCATE,
SERVICE_PAUSE,
SERVICE_RETURN_TO_BASE,
SERVICE_SEND_COMMAND,
SERVICE_SET_FAN_SPEED,
SERVICE_START,
SERVICE_STOP,
STATE_CLEANING,
STATE_IDLE,
STATE_PAUSED,
STATE_RETURNING,
StateVacuumEntity,
VacuumEntityFeature,
)
from homeassistant.core import HomeAssistant
from . import MockVacuum, help_async_setup_entry_init, help_async_unload_entry
from tests.common import (
MockConfigEntry,
MockModule,
mock_integration,
setup_test_component_platform,
)
@pytest.mark.parametrize(
("service", "expected_state"),
[
(SERVICE_CLEAN_SPOT, STATE_CLEANING),
(SERVICE_PAUSE, STATE_PAUSED),
(SERVICE_RETURN_TO_BASE, STATE_RETURNING),
(SERVICE_START, STATE_CLEANING),
(SERVICE_STOP, STATE_IDLE),
],
)
async def test_state_services(
hass: HomeAssistant, config_flow_fixture: None, service: str, expected_state: str
) -> None:
"""Test get vacuum service that affect state."""
mock_vacuum = MockVacuum(
name="Testing",
entity_id="vacuum.testing",
)
config_entry = MockConfigEntry(domain="test")
config_entry.add_to_hass(hass)
mock_integration(
hass,
MockModule(
"test",
async_setup_entry=help_async_setup_entry_init,
async_unload_entry=help_async_unload_entry,
),
)
setup_test_component_platform(hass, DOMAIN, [mock_vacuum], from_config_entry=True)
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.services.async_call(
DOMAIN,
service,
{"entity_id": mock_vacuum.entity_id},
blocking=True,
)
vacuum_state = hass.states.get(mock_vacuum.entity_id)
assert vacuum_state.state == expected_state
async def test_fan_speed(hass: HomeAssistant, config_flow_fixture: None) -> None:
"""Test set vacuum fan speed."""
mock_vacuum = MockVacuum(
name="Testing",
entity_id="vacuum.testing",
)
config_entry = MockConfigEntry(domain="test")
config_entry.add_to_hass(hass)
mock_integration(
hass,
MockModule(
"test",
async_setup_entry=help_async_setup_entry_init,
async_unload_entry=help_async_unload_entry,
),
)
setup_test_component_platform(hass, DOMAIN, [mock_vacuum], from_config_entry=True)
assert await hass.config_entries.async_setup(config_entry.entry_id)
config_entry = MockConfigEntry(domain="test", data={})
config_entry.add_to_hass(hass)
await hass.services.async_call(
DOMAIN,
SERVICE_SET_FAN_SPEED,
{"entity_id": mock_vacuum.entity_id, "fan_speed": "high"},
blocking=True,
)
assert mock_vacuum.fan_speed == "high"
async def test_locate(hass: HomeAssistant, config_flow_fixture: None) -> None:
"""Test vacuum locate."""
calls = []
class MockVacuumWithLocation(MockVacuum):
def __init__(self, calls: list[str], **kwargs) -> None:
super().__init__()
self._attr_supported_features = (
self.supported_features | VacuumEntityFeature.LOCATE
)
self._calls = calls
def locate(self, **kwargs: Any) -> None:
self._calls.append("locate")
mock_vacuum = MockVacuumWithLocation(
name="Testing", entity_id="vacuum.testing", calls=calls
)
config_entry = MockConfigEntry(domain="test")
config_entry.add_to_hass(hass)
mock_integration(
hass,
MockModule(
"test",
async_setup_entry=help_async_setup_entry_init,
async_unload_entry=help_async_unload_entry,
),
)
setup_test_component_platform(hass, DOMAIN, [mock_vacuum], from_config_entry=True)
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.services.async_call(
DOMAIN,
SERVICE_LOCATE,
{"entity_id": mock_vacuum.entity_id},
blocking=True,
)
assert "locate" in calls
async def test_send_command(hass: HomeAssistant, config_flow_fixture: None) -> None:
"""Test Vacuum send command."""
strings = []
class MockVacuumWithSendCommand(MockVacuum):
def __init__(self, strings: list[str], **kwargs) -> None:
super().__init__()
self._attr_supported_features = (
self.supported_features | VacuumEntityFeature.SEND_COMMAND
)
self._strings = strings
def send_command(
self,
command: str,
params: dict[str, Any] | list[Any] | None = None,
**kwargs: Any,
) -> None:
if command == "add_str":
self._strings.append(params["str"])
mock_vacuum = MockVacuumWithSendCommand(
name="Testing", entity_id="vacuum.testing", strings=strings
)
config_entry = MockConfigEntry(domain="test")
config_entry.add_to_hass(hass)
mock_integration(
hass,
MockModule(
"test",
async_setup_entry=help_async_setup_entry_init,
async_unload_entry=help_async_unload_entry,
),
)
setup_test_component_platform(hass, DOMAIN, [mock_vacuum], from_config_entry=True)
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.services.async_call(
DOMAIN,
SERVICE_SEND_COMMAND,
{
"entity_id": mock_vacuum.entity_id,
"command": "add_str",
"params": {"str": "test"},
},
blocking=True,
)
assert "test" in strings
async def test_supported_features_compat(hass: HomeAssistant) -> None:
"""Test StateVacuumEntity using deprecated feature constants features."""