mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Add tests for Rituals init, sensor and switch (#52406)
This commit is contained in:
parent
ec3bfcea46
commit
d4b506e5e4
@ -865,12 +865,8 @@ omit =
|
|||||||
homeassistant/components/ring/camera.py
|
homeassistant/components/ring/camera.py
|
||||||
homeassistant/components/ripple/sensor.py
|
homeassistant/components/ripple/sensor.py
|
||||||
homeassistant/components/rituals_perfume_genie/binary_sensor.py
|
homeassistant/components/rituals_perfume_genie/binary_sensor.py
|
||||||
homeassistant/components/rituals_perfume_genie/entity.py
|
|
||||||
homeassistant/components/rituals_perfume_genie/number.py
|
homeassistant/components/rituals_perfume_genie/number.py
|
||||||
homeassistant/components/rituals_perfume_genie/select.py
|
homeassistant/components/rituals_perfume_genie/select.py
|
||||||
homeassistant/components/rituals_perfume_genie/sensor.py
|
|
||||||
homeassistant/components/rituals_perfume_genie/switch.py
|
|
||||||
homeassistant/components/rituals_perfume_genie/__init__.py
|
|
||||||
homeassistant/components/rocketchat/notify.py
|
homeassistant/components/rocketchat/notify.py
|
||||||
homeassistant/components/roomba/__init__.py
|
homeassistant/components/roomba/__init__.py
|
||||||
homeassistant/components/roomba/binary_sensor.py
|
homeassistant/components/roomba/binary_sensor.py
|
||||||
|
94
tests/components/rituals_perfume_genie/common.py
Normal file
94
tests/components/rituals_perfume_genie/common.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
"""Common methods used across tests for Rituals Perfume Genie."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from unittest.mock import AsyncMock, MagicMock, patch
|
||||||
|
|
||||||
|
from homeassistant.components.rituals_perfume_genie.const import ACCOUNT_HASH, DOMAIN
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
def mock_config_entry(uniqe_id: str, entry_id: str = "an_entry_id") -> MockConfigEntry:
|
||||||
|
"""Return a mock Config Entry for the Rituals Perfume Genie integration."""
|
||||||
|
return MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title="name@example.com",
|
||||||
|
unique_id=uniqe_id,
|
||||||
|
data={ACCOUNT_HASH: "an_account_hash"},
|
||||||
|
entry_id=entry_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def mock_diffuser(
|
||||||
|
hublot: str,
|
||||||
|
available: bool = True,
|
||||||
|
battery_percentage: int | Exception = 100,
|
||||||
|
charging: bool | Exception = True,
|
||||||
|
fill: str = "90-100%",
|
||||||
|
has_battery: bool = True,
|
||||||
|
has_cartridge: bool = True,
|
||||||
|
is_on: bool = True,
|
||||||
|
name: str = "Genie",
|
||||||
|
perfume: str = "Ritual of Sakura",
|
||||||
|
version: str = "4.0",
|
||||||
|
wifi_percentage: int = 75,
|
||||||
|
) -> MagicMock:
|
||||||
|
"""Return a mock Diffuser initialized with the given data."""
|
||||||
|
diffuser_mock = MagicMock()
|
||||||
|
diffuser_mock.available = available
|
||||||
|
diffuser_mock.battery_percentage = battery_percentage
|
||||||
|
diffuser_mock.charging = charging
|
||||||
|
diffuser_mock.fill = fill
|
||||||
|
diffuser_mock.has_battery = has_battery
|
||||||
|
diffuser_mock.has_cartridge = has_cartridge
|
||||||
|
diffuser_mock.hublot = hublot
|
||||||
|
diffuser_mock.is_on = is_on
|
||||||
|
diffuser_mock.name = name
|
||||||
|
diffuser_mock.perfume = perfume
|
||||||
|
diffuser_mock.turn_off = AsyncMock()
|
||||||
|
diffuser_mock.turn_on = AsyncMock()
|
||||||
|
diffuser_mock.update_data = AsyncMock()
|
||||||
|
diffuser_mock.version = version
|
||||||
|
diffuser_mock.wifi_percentage = wifi_percentage
|
||||||
|
return diffuser_mock
|
||||||
|
|
||||||
|
|
||||||
|
def mock_diffuser_v1_battery_cartridge():
|
||||||
|
"""Create and return a mock version 1 Diffuser with battery and a cartridge."""
|
||||||
|
return mock_diffuser(hublot="lot123v1")
|
||||||
|
|
||||||
|
|
||||||
|
def mock_diffuser_v2_no_battery_no_cartridge():
|
||||||
|
"""Create and return a mock version 2 Diffuser without battery and cartridge."""
|
||||||
|
return mock_diffuser(
|
||||||
|
hublot="lot123v2",
|
||||||
|
battery_percentage=Exception(),
|
||||||
|
charging=Exception(),
|
||||||
|
has_battery=False,
|
||||||
|
has_cartridge=False,
|
||||||
|
name="Genie V2",
|
||||||
|
perfume="No Cartridge",
|
||||||
|
version="5.0",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def init_integration(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_diffusers: list[MagicMock] = [mock_diffuser(hublot="lot123")],
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the Rituals Perfume Genie integration with the given Config Entry and Diffuser list."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.rituals_perfume_genie.Account.get_devices",
|
||||||
|
return_value=mock_diffusers,
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
assert mock_config_entry.entry_id in hass.data[DOMAIN]
|
||||||
|
assert hass.data[DOMAIN]
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
34
tests/components/rituals_perfume_genie/test_init.py
Normal file
34
tests/components/rituals_perfume_genie/test_init.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
"""Tests for the Rituals Perfume Genie integration."""
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
|
|
||||||
|
from homeassistant.components.rituals_perfume_genie.const import DOMAIN
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from .common import init_integration, mock_config_entry
|
||||||
|
|
||||||
|
|
||||||
|
async def test_config_entry_not_ready(hass: HomeAssistant):
|
||||||
|
"""Test the Rituals configuration entry setup if connection to Rituals is missing."""
|
||||||
|
config_entry = mock_config_entry(uniqe_id="id_123_not_ready")
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.rituals_perfume_genie.Account.get_devices",
|
||||||
|
side_effect=aiohttp.ClientError,
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
|
async def test_config_entry_unload(hass: HomeAssistant) -> None:
|
||||||
|
"""Test the Rituals Perfume Genie configuration entry setup and unloading."""
|
||||||
|
config_entry = mock_config_entry(uniqe_id="id_123_unload")
|
||||||
|
await init_integration(hass, config_entry)
|
||||||
|
|
||||||
|
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert config_entry.state is ConfigEntryState.NOT_LOADED
|
||||||
|
assert config_entry.entry_id not in hass.data[DOMAIN]
|
88
tests/components/rituals_perfume_genie/test_sensor.py
Normal file
88
tests/components/rituals_perfume_genie/test_sensor.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
"""Tests for the Rituals Perfume Genie sensor platform."""
|
||||||
|
from homeassistant.components.rituals_perfume_genie.sensor import (
|
||||||
|
BATTERY_SUFFIX,
|
||||||
|
FILL_SUFFIX,
|
||||||
|
PERFUME_SUFFIX,
|
||||||
|
WIFI_SUFFIX,
|
||||||
|
)
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_DEVICE_CLASS,
|
||||||
|
ATTR_ICON,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
|
DEVICE_CLASS_BATTERY,
|
||||||
|
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
|
PERCENTAGE,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry
|
||||||
|
|
||||||
|
from .common import (
|
||||||
|
init_integration,
|
||||||
|
mock_config_entry,
|
||||||
|
mock_diffuser_v1_battery_cartridge,
|
||||||
|
mock_diffuser_v2_no_battery_no_cartridge,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensors_diffuser_v1_battery_cartridge(hass: HomeAssistant) -> None:
|
||||||
|
"""Test the creation and values of the Rituals Perfume Genie sensors."""
|
||||||
|
config_entry = mock_config_entry(uniqe_id="id_123_sensor_test_diffuser_v1")
|
||||||
|
diffuser = mock_diffuser_v1_battery_cartridge()
|
||||||
|
await init_integration(hass, config_entry, [diffuser])
|
||||||
|
registry = entity_registry.async_get(hass)
|
||||||
|
hublot = diffuser.hublot
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.genie_perfume")
|
||||||
|
assert state
|
||||||
|
assert state.state == diffuser.perfume
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:tag-text"
|
||||||
|
|
||||||
|
entry = registry.async_get("sensor.genie_perfume")
|
||||||
|
assert entry
|
||||||
|
assert entry.unique_id == f"{hublot}{PERFUME_SUFFIX}"
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.genie_fill")
|
||||||
|
assert state
|
||||||
|
assert state.state == diffuser.fill
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:beaker"
|
||||||
|
|
||||||
|
entry = registry.async_get("sensor.genie_fill")
|
||||||
|
assert entry
|
||||||
|
assert entry.unique_id == f"{hublot}{FILL_SUFFIX}"
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.genie_battery")
|
||||||
|
assert state
|
||||||
|
assert state.state == str(diffuser.battery_percentage)
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_BATTERY
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
|
||||||
|
|
||||||
|
entry = registry.async_get("sensor.genie_battery")
|
||||||
|
assert entry
|
||||||
|
assert entry.unique_id == f"{hublot}{BATTERY_SUFFIX}"
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.genie_wifi")
|
||||||
|
assert state
|
||||||
|
assert state.state == str(diffuser.wifi_percentage)
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_SIGNAL_STRENGTH
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
|
||||||
|
|
||||||
|
entry = registry.async_get("sensor.genie_wifi")
|
||||||
|
assert entry
|
||||||
|
assert entry.unique_id == f"{hublot}{WIFI_SUFFIX}"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensors_diffuser_v2_no_battery_no_cartridge(hass: HomeAssistant) -> None:
|
||||||
|
"""Test the creation and values of the Rituals Perfume Genie sensors."""
|
||||||
|
config_entry = mock_config_entry(uniqe_id="id_123_sensor_test_diffuser_v2")
|
||||||
|
|
||||||
|
await init_integration(
|
||||||
|
hass, config_entry, [mock_diffuser_v2_no_battery_no_cartridge()]
|
||||||
|
)
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.genie_v2_perfume")
|
||||||
|
assert state
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:tag-remove"
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.genie_v2_fill")
|
||||||
|
assert state
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:beaker-question"
|
104
tests/components/rituals_perfume_genie/test_switch.py
Normal file
104
tests/components/rituals_perfume_genie/test_switch.py
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
"""Tests for the Rituals Perfume Genie switch platform."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from homeassistant.components.homeassistant import SERVICE_UPDATE_ENTITY
|
||||||
|
from homeassistant.components.rituals_perfume_genie.const import COORDINATORS, DOMAIN
|
||||||
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_ENTITY_ID,
|
||||||
|
ATTR_ICON,
|
||||||
|
SERVICE_TURN_OFF,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
from .common import (
|
||||||
|
init_integration,
|
||||||
|
mock_config_entry,
|
||||||
|
mock_diffuser_v1_battery_cartridge,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_switch_entity(hass: HomeAssistant) -> None:
|
||||||
|
"""Test the creation and values of the Rituals Perfume Genie diffuser switch."""
|
||||||
|
config_entry = mock_config_entry(uniqe_id="id_123_switch_set_state_test")
|
||||||
|
diffuser = mock_diffuser_v1_battery_cartridge()
|
||||||
|
await init_integration(hass, config_entry, [diffuser])
|
||||||
|
|
||||||
|
registry = entity_registry.async_get(hass)
|
||||||
|
|
||||||
|
state = hass.states.get("switch.genie")
|
||||||
|
assert state
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes.get(ATTR_ICON) == "mdi:fan"
|
||||||
|
|
||||||
|
entry = registry.async_get("switch.genie")
|
||||||
|
assert entry
|
||||||
|
assert entry.unique_id == diffuser.hublot
|
||||||
|
|
||||||
|
|
||||||
|
async def test_switch_handle_coordinator_update(hass: HomeAssistant) -> None:
|
||||||
|
"""Test handling a coordinator update."""
|
||||||
|
config_entry = mock_config_entry(uniqe_id="id_123_switch_set_state_test")
|
||||||
|
diffuser = mock_diffuser_v1_battery_cartridge()
|
||||||
|
await init_integration(hass, config_entry, [diffuser])
|
||||||
|
await async_setup_component(hass, "homeassistant", {})
|
||||||
|
coordinator = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]["lot123v1"]
|
||||||
|
diffuser.is_on = False
|
||||||
|
|
||||||
|
state = hass.states.get("switch.genie")
|
||||||
|
assert state
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
call_count_before_update = diffuser.update_data.call_count
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
"homeassistant",
|
||||||
|
SERVICE_UPDATE_ENTITY,
|
||||||
|
{ATTR_ENTITY_ID: ["switch.genie"]},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("switch.genie")
|
||||||
|
assert state
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
assert coordinator.last_update_success
|
||||||
|
assert diffuser.update_data.call_count == call_count_before_update + 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_set_switch_state(hass: HomeAssistant) -> None:
|
||||||
|
"""Test changing the diffuser switch entity state."""
|
||||||
|
config_entry = mock_config_entry(uniqe_id="id_123_switch_set_state_test")
|
||||||
|
await init_integration(hass, config_entry, [mock_diffuser_v1_battery_cartridge()])
|
||||||
|
|
||||||
|
state = hass.states.get("switch.genie")
|
||||||
|
assert state
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
SWITCH_DOMAIN,
|
||||||
|
SERVICE_TURN_OFF,
|
||||||
|
{ATTR_ENTITY_ID: "switch.genie"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
state = hass.states.get("switch.genie")
|
||||||
|
assert state
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
SWITCH_DOMAIN,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
{ATTR_ENTITY_ID: "switch.genie"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
state = hass.states.get("switch.genie")
|
||||||
|
assert state
|
||||||
|
assert state.state == STATE_ON
|
Loading…
x
Reference in New Issue
Block a user