Skip to content

Commit

Permalink
Add better testing to vacuum platform (home-assistant#112523)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
Lash-L and MartinHjelmare authored May 8, 2024
1 parent f9413fc commit a77add1
Show file tree
Hide file tree
Showing 3 changed files with 308 additions and 1 deletion.
83 changes: 83 additions & 0 deletions tests/components/vacuum/__init__.py
Original file line number Diff line number Diff line change
@@ -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]
)
23 changes: 23 additions & 0 deletions tests/components/vacuum/conftest.py
Original file line number Diff line number Diff line change
@@ -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
203 changes: 202 additions & 1 deletion tests/components/vacuum/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand Down

0 comments on commit a77add1

Please sign in to comment.