Improve timer tests (#168277)

This commit is contained in:
Erik Montnemery
2026-04-15 11:21:59 +02:00
committed by GitHub
parent f397f4c908
commit d6be6e8810

View File

@@ -5,6 +5,7 @@ import logging
from typing import Any
from unittest.mock import patch
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.timer import (
@@ -33,7 +34,6 @@ from homeassistant.components.timer import (
STATUS_IDLE,
STATUS_PAUSED,
Timer,
_format_timedelta,
)
from homeassistant.const import (
ATTR_EDITABLE,
@@ -132,20 +132,27 @@ async def test_config_options(hass: HomeAssistant) -> None:
assert state_3 is not None
assert state_1.state == STATUS_IDLE
assert ATTR_ICON not in state_1.attributes
assert ATTR_FRIENDLY_NAME not in state_1.attributes
assert state_1.attributes == {
ATTR_EDITABLE: False,
ATTR_DURATION: "0:00:00",
}
assert state_2.state == STATUS_IDLE
assert state_2.attributes.get(ATTR_FRIENDLY_NAME) == "Hello World"
assert state_2.attributes.get(ATTR_ICON) == "mdi:work"
assert state_2.attributes.get(ATTR_DURATION) == "0:00:10"
assert state_2.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
ATTR_FRIENDLY_NAME: "Hello World",
ATTR_ICON: "mdi:work",
}
assert state_3.state == STATUS_IDLE
assert str(cv.time_period(DEFAULT_DURATION)) == state_3.attributes.get(
CONF_DURATION
)
assert state_3.attributes == {
ATTR_DURATION: str(cv.time_period(DEFAULT_DURATION)),
ATTR_EDITABLE: False,
}
@pytest.mark.freeze_time("2023-06-05 17:47:50")
async def test_methods_and_events(hass: HomeAssistant) -> None:
"""Test methods and events."""
hass.set_state(CoreState.starting)
@@ -155,13 +162,17 @@ async def test_methods_and_events(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_IDLE
assert state.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
}
results: list[tuple[Event, str]] = []
results: list[tuple[Event, State | None]] = []
@callback
def fake_event_listener(event: Event):
"""Fake event listener for trigger."""
results.append((event, hass.states.get("timer.test1").state))
results.append((event, hass.states.get("timer.test1")))
hass.bus.async_listen(EVENT_TIMER_STARTED, fake_event_listener)
hass.bus.async_listen(EVENT_TIMER_RESTARTED, fake_event_listener)
@@ -170,102 +181,142 @@ async def test_methods_and_events(hass: HomeAssistant) -> None:
hass.bus.async_listen(EVENT_TIMER_CANCELLED, fake_event_listener)
hass.bus.async_listen(EVENT_TIMER_CHANGED, fake_event_listener)
finish_10 = (utcnow() + timedelta(seconds=10)).isoformat()
finish_5 = (utcnow() + timedelta(seconds=5)).isoformat()
steps = [
{
"call": SERVICE_START,
"state": STATUS_ACTIVE,
"event": EVENT_TIMER_STARTED,
"data": {},
"call_data": {},
"expected_state": STATUS_ACTIVE,
"expected_extra_attributes": {
ATTR_FINISHES_AT: finish_10,
ATTR_REMAINING: "0:00:10",
},
"expected_event": EVENT_TIMER_STARTED,
},
{
"call": SERVICE_PAUSE,
"state": STATUS_PAUSED,
"event": EVENT_TIMER_PAUSED,
"data": {},
"call_data": {},
"expected_state": STATUS_PAUSED,
"expected_extra_attributes": {ATTR_REMAINING: "0:00:10"},
"expected_event": EVENT_TIMER_PAUSED,
},
{
"call": SERVICE_START,
"state": STATUS_ACTIVE,
"event": EVENT_TIMER_RESTARTED,
"data": {},
"call_data": {},
"expected_state": STATUS_ACTIVE,
"expected_extra_attributes": {
ATTR_FINISHES_AT: finish_10,
ATTR_REMAINING: "0:00:10",
},
"expected_event": EVENT_TIMER_RESTARTED,
},
{
"call": SERVICE_CANCEL,
"state": STATUS_IDLE,
"event": EVENT_TIMER_CANCELLED,
"data": {},
"call_data": {},
"expected_state": STATUS_IDLE,
"expected_extra_attributes": {},
"expected_event": EVENT_TIMER_CANCELLED,
},
{
"call": SERVICE_CANCEL,
"state": STATUS_IDLE,
"event": None,
"data": {},
"call_data": {},
"expected_state": STATUS_IDLE,
"expected_extra_attributes": {},
"expected_event": None,
},
{
"call": SERVICE_START,
"state": STATUS_ACTIVE,
"event": EVENT_TIMER_STARTED,
"data": {},
"call_data": {},
"expected_state": STATUS_ACTIVE,
"expected_extra_attributes": {
ATTR_FINISHES_AT: finish_10,
ATTR_REMAINING: "0:00:10",
},
"expected_event": EVENT_TIMER_STARTED,
},
{
"call": SERVICE_FINISH,
"state": STATUS_IDLE,
"event": EVENT_TIMER_FINISHED,
"data": {},
"call_data": {},
"expected_state": STATUS_IDLE,
"expected_extra_attributes": {},
"expected_event": EVENT_TIMER_FINISHED,
},
{
"call": SERVICE_FINISH,
"state": STATUS_IDLE,
"event": None,
"data": {},
"call_data": {},
"expected_state": STATUS_IDLE,
"expected_extra_attributes": {},
"expected_event": None,
},
{
"call": SERVICE_START,
"state": STATUS_ACTIVE,
"event": EVENT_TIMER_STARTED,
"data": {},
"call_data": {},
"expected_state": STATUS_ACTIVE,
"expected_extra_attributes": {
ATTR_FINISHES_AT: finish_10,
ATTR_REMAINING: "0:00:10",
},
"expected_event": EVENT_TIMER_STARTED,
},
{
"call": SERVICE_PAUSE,
"state": STATUS_PAUSED,
"event": EVENT_TIMER_PAUSED,
"data": {},
"call_data": {},
"expected_state": STATUS_PAUSED,
"expected_extra_attributes": {ATTR_REMAINING: "0:00:10"},
"expected_event": EVENT_TIMER_PAUSED,
},
{
"call": SERVICE_CANCEL,
"state": STATUS_IDLE,
"event": EVENT_TIMER_CANCELLED,
"data": {},
"call_data": {},
"expected_state": STATUS_IDLE,
"expected_extra_attributes": {},
"expected_event": EVENT_TIMER_CANCELLED,
},
{
"call": SERVICE_START,
"state": STATUS_ACTIVE,
"event": EVENT_TIMER_STARTED,
"data": {},
"call_data": {},
"expected_state": STATUS_ACTIVE,
"expected_extra_attributes": {
ATTR_FINISHES_AT: finish_10,
ATTR_REMAINING: "0:00:10",
},
"expected_event": EVENT_TIMER_STARTED,
},
{
"call": SERVICE_CHANGE,
"state": STATUS_ACTIVE,
"event": EVENT_TIMER_CHANGED,
"data": {CONF_DURATION: -5},
"call_data": {CONF_DURATION: -5},
"expected_state": STATUS_ACTIVE,
"expected_extra_attributes": {
ATTR_FINISHES_AT: finish_5,
ATTR_REMAINING: "0:00:05",
},
"expected_event": EVENT_TIMER_CHANGED,
},
{
"call": SERVICE_START,
"state": STATUS_ACTIVE,
"event": EVENT_TIMER_RESTARTED,
"data": {},
"call_data": {},
"expected_state": STATUS_ACTIVE,
"expected_extra_attributes": {
ATTR_FINISHES_AT: finish_5,
ATTR_REMAINING: "0:00:05",
},
"expected_event": EVENT_TIMER_RESTARTED,
},
{
"call": SERVICE_PAUSE,
"state": STATUS_PAUSED,
"event": EVENT_TIMER_PAUSED,
"data": {},
"call_data": {},
"expected_state": STATUS_PAUSED,
"expected_extra_attributes": {ATTR_REMAINING: "0:00:05"},
"expected_event": EVENT_TIMER_PAUSED,
},
{
"call": SERVICE_FINISH,
"state": STATUS_IDLE,
"event": EVENT_TIMER_FINISHED,
"data": {},
"call_data": {},
"expected_state": STATUS_IDLE,
"expected_extra_attributes": {},
"expected_event": EVENT_TIMER_FINISHED,
},
]
@@ -275,22 +326,38 @@ async def test_methods_and_events(hass: HomeAssistant) -> None:
await hass.services.async_call(
DOMAIN,
step["call"],
{CONF_ENTITY_ID: "timer.test1", **step["data"]},
{CONF_ENTITY_ID: "timer.test1", **step["call_data"]},
blocking=True,
)
await hass.async_block_till_done()
state = hass.states.get("timer.test1")
assert state
if step["state"] is not None:
assert state.state == step["state"]
if step["expected_state"] is not None:
assert state.state == step["expected_state"]
assert (
state.attributes
== {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
}
| step["expected_extra_attributes"]
)
if step["event"] is not None:
if step["expected_event"] is not None:
expected_events += 1
last_result = results[-1]
event, state = last_result
assert event.event_type == step["event"]
assert state == step["state"]
assert event.event_type == step["expected_event"]
assert state.state == step["expected_state"]
assert (
state.attributes
== {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
}
| step["expected_extra_attributes"]
)
assert len(results) == expected_events
@@ -302,7 +369,10 @@ async def test_start_service(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_IDLE
assert state.attributes[ATTR_DURATION] == "0:00:10"
assert state.attributes == {
ATTR_EDITABLE: False,
ATTR_DURATION: "0:00:10",
}
await hass.services.async_call(
DOMAIN, SERVICE_START, {CONF_ENTITY_ID: "timer.test1"}, blocking=True
@@ -311,8 +381,12 @@ async def test_start_service(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes[ATTR_DURATION] == "0:00:10"
assert state.attributes[ATTR_REMAINING] == "0:00:10"
assert state.attributes == {
ATTR_EDITABLE: False,
ATTR_DURATION: "0:00:10",
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=10)).isoformat(),
ATTR_REMAINING: "0:00:10",
}
await hass.services.async_call(
DOMAIN, SERVICE_CANCEL, {CONF_ENTITY_ID: "timer.test1"}, blocking=True
@@ -321,8 +395,10 @@ async def test_start_service(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_IDLE
assert state.attributes[ATTR_DURATION] == "0:00:10"
assert ATTR_REMAINING not in state.attributes
assert state.attributes == {
ATTR_EDITABLE: False,
ATTR_DURATION: "0:00:10",
}
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
@@ -342,8 +418,12 @@ async def test_start_service(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes[ATTR_DURATION] == "0:00:15"
assert state.attributes[ATTR_REMAINING] == "0:00:15"
assert state.attributes == {
ATTR_EDITABLE: False,
ATTR_DURATION: "0:00:15",
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=15)).isoformat(),
ATTR_REMAINING: "0:00:15",
}
with pytest.raises(
HomeAssistantError,
@@ -376,8 +456,12 @@ async def test_start_service(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes[ATTR_DURATION] == "0:00:15"
assert state.attributes[ATTR_REMAINING] == "0:00:12"
assert state.attributes == {
ATTR_EDITABLE: False,
ATTR_DURATION: "0:00:15",
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=12)).isoformat(),
ATTR_REMAINING: "0:00:12",
}
await hass.services.async_call(
DOMAIN,
@@ -388,8 +472,12 @@ async def test_start_service(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes[ATTR_DURATION] == "0:00:15"
assert state.attributes[ATTR_REMAINING] == "0:00:14"
assert state.attributes == {
ATTR_EDITABLE: False,
ATTR_DURATION: "0:00:15",
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=14)).isoformat(),
ATTR_REMAINING: "0:00:14",
}
await hass.services.async_call(
DOMAIN, SERVICE_CANCEL, {CONF_ENTITY_ID: "timer.test1"}, blocking=True
@@ -398,8 +486,10 @@ async def test_start_service(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_IDLE
assert state.attributes[ATTR_DURATION] == "0:00:10"
assert ATTR_REMAINING not in state.attributes
assert state.attributes == {
ATTR_EDITABLE: False,
ATTR_DURATION: "0:00:10",
}
with pytest.raises(
HomeAssistantError,
@@ -415,11 +505,16 @@ async def test_start_service(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_IDLE
assert state.attributes[ATTR_DURATION] == "0:00:10"
assert ATTR_REMAINING not in state.attributes
assert state.attributes == {
ATTR_EDITABLE: False,
ATTR_DURATION: "0:00:10",
}
async def test_wait_till_timer_expires(hass: HomeAssistant) -> None:
@pytest.mark.freeze_time("2023-06-05 17:47:50")
async def test_wait_till_timer_expires(
hass: HomeAssistant, freezer: FrozenDateTimeFactory
) -> None:
"""Test for a timer to end."""
hass.set_state(CoreState.starting)
@@ -428,6 +523,10 @@ async def test_wait_till_timer_expires(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_IDLE
assert state.attributes == {
ATTR_DURATION: "0:00:20",
ATTR_EDITABLE: False,
}
results = []
@@ -450,6 +549,12 @@ async def test_wait_till_timer_expires(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes == {
ATTR_DURATION: "0:00:20",
ATTR_EDITABLE: False,
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=20)).isoformat(),
ATTR_REMAINING: "0:00:20",
}
assert results[-1].event_type == EVENT_TIMER_STARTED
assert len(results) == 1
@@ -465,23 +570,41 @@ async def test_wait_till_timer_expires(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes == {
ATTR_DURATION: "0:00:20",
ATTR_EDITABLE: False,
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=15)).isoformat(),
ATTR_REMAINING: "0:00:15",
}
assert results[-1].event_type == EVENT_TIMER_CHANGED
assert len(results) == 2
async_fire_time_changed(hass, utcnow() + timedelta(seconds=10))
freezer.tick(10)
async_fire_time_changed(hass)
await hass.async_block_till_done()
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes == {
ATTR_DURATION: "0:00:20",
ATTR_EDITABLE: False,
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=5)).isoformat(),
ATTR_REMAINING: "0:00:15",
}
async_fire_time_changed(hass, utcnow() + timedelta(seconds=20))
freezer.tick(20)
async_fire_time_changed(hass)
await hass.async_block_till_done()
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_IDLE
assert state.attributes == {
ATTR_DURATION: "0:00:20",
ATTR_EDITABLE: False,
}
assert results[-1].event_type == EVENT_TIMER_FINISHED
assert len(results) == 3
@@ -496,6 +619,10 @@ async def test_no_initial_state_and_no_restore_state(hass: HomeAssistant) -> Non
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_IDLE
assert state.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
}
async def test_config_reload(
@@ -538,13 +665,18 @@ async def test_config_reload(
assert entity_registry.async_get_entity_id(DOMAIN, DOMAIN, "test_3") is None
assert state_1.state == STATUS_IDLE
assert ATTR_ICON not in state_1.attributes
assert ATTR_FRIENDLY_NAME not in state_1.attributes
assert state_1.attributes == {
ATTR_DURATION: "0:00:00",
ATTR_EDITABLE: False,
}
assert state_2.state == STATUS_IDLE
assert state_2.attributes.get(ATTR_FRIENDLY_NAME) == "Hello World"
assert state_2.attributes.get(ATTR_ICON) == "mdi:work"
assert state_2.attributes.get(ATTR_DURATION) == "0:00:10"
assert state_2.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
ATTR_FRIENDLY_NAME: "Hello World",
ATTR_ICON: "mdi:work",
}
with patch(
"homeassistant.config.load_yaml_config_file",
@@ -589,15 +721,21 @@ async def test_config_reload(
assert entity_registry.async_get_entity_id(DOMAIN, DOMAIN, "test_3") is not None
assert state_2.state == STATUS_IDLE
assert state_2.attributes.get(ATTR_FRIENDLY_NAME) == "Hello World reloaded"
assert state_2.attributes.get(ATTR_ICON) == "mdi:work-reloaded"
assert state_2.attributes.get(ATTR_DURATION) == "0:00:20"
assert state_2.attributes == {
ATTR_DURATION: "0:00:20",
ATTR_EDITABLE: False,
ATTR_FRIENDLY_NAME: "Hello World reloaded",
ATTR_ICON: "mdi:work-reloaded",
}
assert state_3.state == STATUS_IDLE
assert ATTR_ICON not in state_3.attributes
assert ATTR_FRIENDLY_NAME not in state_3.attributes
assert state_3.attributes == {
ATTR_DURATION: "0:00:00",
ATTR_EDITABLE: False,
}
@pytest.mark.freeze_time("2023-06-05 17:47:50")
async def test_timer_restarted_event(hass: HomeAssistant) -> None:
"""Ensure restarted event is called after starting a paused or running timer."""
hass.set_state(CoreState.starting)
@@ -607,6 +745,10 @@ async def test_timer_restarted_event(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_IDLE
assert state.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
}
results = []
@@ -628,6 +770,12 @@ async def test_timer_restarted_event(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=10)).isoformat(),
ATTR_REMAINING: "0:00:10",
}
assert results[-1].event_type == EVENT_TIMER_STARTED
assert len(results) == 1
@@ -639,6 +787,12 @@ async def test_timer_restarted_event(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=10)).isoformat(),
ATTR_REMAINING: "0:00:10",
}
assert results[-1].event_type == EVENT_TIMER_RESTARTED
assert len(results) == 2
@@ -650,6 +804,11 @@ async def test_timer_restarted_event(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_PAUSED
assert state.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
ATTR_REMAINING: "0:00:10",
}
assert results[-1].event_type == EVENT_TIMER_PAUSED
assert len(results) == 3
@@ -661,11 +820,18 @@ async def test_timer_restarted_event(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=10)).isoformat(),
ATTR_REMAINING: "0:00:10",
}
assert results[-1].event_type == EVENT_TIMER_RESTARTED
assert len(results) == 4
@pytest.mark.freeze_time("2023-06-05 17:47:50")
async def test_state_changed_when_timer_restarted(hass: HomeAssistant) -> None:
"""Ensure timer's state changes when it restarted."""
hass.set_state(CoreState.starting)
@@ -675,6 +841,10 @@ async def test_state_changed_when_timer_restarted(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_IDLE
assert state.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
}
results = []
@@ -692,6 +862,12 @@ async def test_state_changed_when_timer_restarted(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=10)).isoformat(),
ATTR_REMAINING: "0:00:10",
}
assert results[-1].event_type == EVENT_STATE_CHANGED
assert len(results) == 1
@@ -703,6 +879,12 @@ async def test_state_changed_when_timer_restarted(hass: HomeAssistant) -> None:
state = hass.states.get("timer.test1")
assert state
assert state.state == STATUS_ACTIVE
assert state.attributes == {
ATTR_DURATION: "0:00:10",
ATTR_EDITABLE: False,
ATTR_FINISHES_AT: (utcnow() + timedelta(seconds=10)).isoformat(),
ATTR_REMAINING: "0:00:10",
}
assert results[-1].event_type == EVENT_STATE_CHANGED
assert len(results) == 2
@@ -713,8 +895,11 @@ async def test_load_from_storage(hass: HomeAssistant, storage_setup) -> None:
assert await storage_setup()
state = hass.states.get(f"{DOMAIN}.timer_from_storage")
assert state.state == STATUS_IDLE
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "timer from storage"
assert state.attributes.get(ATTR_EDITABLE)
assert state.attributes == {
ATTR_DURATION: "0:00:00",
ATTR_EDITABLE: True,
ATTR_FRIENDLY_NAME: "timer from storage",
}
async def test_editable_state_attribute(hass: HomeAssistant, storage_setup) -> None:
@@ -723,12 +908,18 @@ async def test_editable_state_attribute(hass: HomeAssistant, storage_setup) -> N
state = hass.states.get(f"{DOMAIN}.{DOMAIN}_from_storage")
assert state.state == STATUS_IDLE
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "timer from storage"
assert state.attributes.get(ATTR_EDITABLE)
assert state.attributes == {
ATTR_DURATION: "0:00:00",
ATTR_EDITABLE: True,
ATTR_FRIENDLY_NAME: "timer from storage",
}
state = hass.states.get(f"{DOMAIN}.from_yaml")
assert not state.attributes.get(ATTR_EDITABLE)
assert state.state == STATUS_IDLE
assert state.attributes == {
ATTR_DURATION: "0:00:00",
ATTR_EDITABLE: False,
}
async def test_ws_list(
@@ -797,7 +988,12 @@ async def test_update(
timer_entity_id = f"{DOMAIN}.{DOMAIN}_{timer_id}"
state = hass.states.get(timer_entity_id)
assert state.attributes[ATTR_FRIENDLY_NAME] == "timer from storage"
assert state.state == STATUS_IDLE
assert state.attributes == {
ATTR_DURATION: "0:00:00",
ATTR_EDITABLE: True,
ATTR_FRIENDLY_NAME: "timer from storage",
}
assert (
entity_registry.async_get_entity_id(DOMAIN, DOMAIN, timer_id) == timer_entity_id
)
@@ -827,8 +1023,13 @@ async def test_update(
}
state = hass.states.get(timer_entity_id)
assert state.attributes[ATTR_DURATION] == _format_timedelta(cv.time_period(33))
assert state.attributes[ATTR_RESTORE]
assert state.state == STATUS_IDLE
assert state.attributes == {
ATTR_DURATION: "0:00:33",
ATTR_EDITABLE: True,
ATTR_FRIENDLY_NAME: "timer from storage",
ATTR_RESTORE: True,
}
async def test_ws_create(
@@ -862,7 +1063,11 @@ async def test_ws_create(
state = hass.states.get(timer_entity_id)
assert state.state == STATUS_IDLE
assert state.attributes[ATTR_DURATION] == _format_timedelta(cv.time_period(42))
assert state.attributes == {
ATTR_DURATION: "0:00:42",
ATTR_EDITABLE: True,
ATTR_FRIENDLY_NAME: "New Timer",
}
assert (
entity_registry.async_get_entity_id(DOMAIN, DOMAIN, timer_id) == timer_entity_id
)
@@ -919,10 +1124,12 @@ async def test_restore_paused(hass: HomeAssistant) -> None:
await entity.async_added_to_hass()
await hass.async_block_till_done()
assert entity.state == STATUS_PAUSED
assert entity.extra_state_attributes[ATTR_DURATION] == "0:00:30"
assert entity.extra_state_attributes[ATTR_REMAINING] == "0:00:15"
assert ATTR_FINISHES_AT not in entity.extra_state_attributes
assert entity.extra_state_attributes[ATTR_RESTORE]
assert entity.extra_state_attributes == {
ATTR_DURATION: "0:00:30",
ATTR_EDITABLE: True,
ATTR_REMAINING: "0:00:15",
ATTR_RESTORE: True,
}
@pytest.mark.freeze_time("2023-06-05 17:47:50")
@@ -967,10 +1174,13 @@ async def test_restore_active_resume(hass: HomeAssistant) -> None:
await hass.async_block_till_done()
assert entity.state == STATUS_ACTIVE
assert entity.extra_state_attributes[ATTR_DURATION] == "0:00:30"
assert entity.extra_state_attributes[ATTR_REMAINING] == "0:00:15"
assert entity.extra_state_attributes[ATTR_FINISHES_AT] == finish.isoformat()
assert entity.extra_state_attributes[ATTR_RESTORE]
assert entity.extra_state_attributes == {
ATTR_DURATION: "0:00:30",
ATTR_EDITABLE: True,
ATTR_FINISHES_AT: finish.isoformat(),
ATTR_REMAINING: "0:00:15",
ATTR_RESTORE: True,
}
assert len(events) == 1
@@ -1013,8 +1223,9 @@ async def test_restore_active_finished_outside_grace(hass: HomeAssistant) -> Non
await hass.async_block_till_done()
assert entity.state == STATUS_IDLE
assert entity.extra_state_attributes[ATTR_DURATION] == "0:01:00"
assert ATTR_REMAINING not in entity.extra_state_attributes
assert ATTR_FINISHES_AT not in entity.extra_state_attributes
assert entity.extra_state_attributes[ATTR_RESTORE]
assert entity.extra_state_attributes == {
ATTR_DURATION: "0:01:00",
ATTR_EDITABLE: True,
ATTR_RESTORE: True,
}
assert len(events) == 1