mirror of
https://github.com/elisspace/core.git
synced 2026-09-30 14:29:54 +00:00
Add datetime platform (#81943)
Co-authored-by: Franck Nijhof <frenck@frenck.nl> Co-authored-by: Franck Nijhof <git@frenck.dev>
This commit is contained in:
co-authored by
Franck Nijhof
Franck Nijhof
parent
940942a74a
commit
24290e5d08
@@ -0,0 +1 @@
|
||||
"""Tests for the datetime component."""
|
||||
@@ -0,0 +1,98 @@
|
||||
"""The tests for the datetime component."""
|
||||
from datetime import datetime, timezone
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.datetime import (
|
||||
ATTR_DATETIME,
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
DateTimeEntity,
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, CONF_PLATFORM
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
DEFAULT_VALUE = datetime(2020, 1, 1, 12, 0, 0, tzinfo=timezone.utc)
|
||||
|
||||
|
||||
class MockDateTimeEntity(DateTimeEntity):
|
||||
"""Mock datetime device to use in tests."""
|
||||
|
||||
def __init__(self, native_value: datetime | None = DEFAULT_VALUE) -> None:
|
||||
"""Initialize mock datetime entity."""
|
||||
self._attr_native_value = native_value
|
||||
|
||||
async def async_set_value(self, value: datetime) -> None:
|
||||
"""Change the date/time."""
|
||||
self._attr_native_value = value
|
||||
|
||||
|
||||
async def test_datetime(hass: HomeAssistant, enable_custom_integrations: None) -> None:
|
||||
"""Test date/time entity."""
|
||||
hass.config.set_time_zone("UTC")
|
||||
platform = getattr(hass.components, f"test.{DOMAIN}")
|
||||
platform.init()
|
||||
|
||||
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("datetime.test")
|
||||
assert state.state == "2020-01-01T01:02:03+00:00"
|
||||
assert state.attributes == {ATTR_FRIENDLY_NAME: "test"}
|
||||
|
||||
# Test updating datetime
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{ATTR_DATETIME: datetime(2022, 3, 3, 3, 4, 5), ATTR_ENTITY_ID: "datetime.test"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("datetime.test")
|
||||
assert state.state == "2022-03-03T03:04:05+00:00"
|
||||
|
||||
# Test updating datetime with UTC timezone
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{ATTR_DATETIME: "2022-03-03T03:04:05+00:00", ATTR_ENTITY_ID: "datetime.test"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("datetime.test")
|
||||
assert state.state == "2022-03-03T03:04:05+00:00"
|
||||
|
||||
# Test updating datetime with non UTC timezone
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{ATTR_DATETIME: "2022-03-03T03:04:05-05:00", ATTR_ENTITY_ID: "datetime.test"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("datetime.test")
|
||||
assert state.state == "2022-03-03T08:04:05+00:00"
|
||||
|
||||
# Test that non UTC timezone gets converted to UTC
|
||||
assert (
|
||||
MockDateTimeEntity(
|
||||
native_value=datetime(2020, 1, 2, 3, 4, 5, tzinfo=ZoneInfo("US/Eastern"))
|
||||
).state
|
||||
== "2020-01-02T08:04:05+00:00"
|
||||
)
|
||||
|
||||
# Test None state
|
||||
date_entity = MockDateTimeEntity(native_value=None)
|
||||
assert date_entity.state is None
|
||||
assert date_entity.state_attributes is None
|
||||
|
||||
# Test that timezone is required to process state
|
||||
with pytest.raises(ValueError):
|
||||
assert MockDateTimeEntity(
|
||||
native_value=datetime(2020, 1, 2, 3, 4, 5, tzinfo=None)
|
||||
).state
|
||||
@@ -0,0 +1,35 @@
|
||||
"""The tests for the demo datetime component."""
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.datetime import ATTR_DATETIME, DOMAIN, SERVICE_SET_VALUE
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
ENTITY_DATETIME = "datetime.date_and_time"
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
async def setup_demo_datetime(hass: HomeAssistant) -> None:
|
||||
"""Initialize setup demo datetime."""
|
||||
assert await async_setup_component(hass, DOMAIN, {"datetime": {"platform": "demo"}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
def test_setup_params(hass: HomeAssistant) -> None:
|
||||
"""Test the initial parameters."""
|
||||
state = hass.states.get(ENTITY_DATETIME)
|
||||
assert state.state == "2020-01-01T12:00:00+00:00"
|
||||
|
||||
|
||||
async def test_set_datetime(hass: HomeAssistant) -> None:
|
||||
"""Test set datetime service."""
|
||||
hass.config.set_time_zone("UTC")
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{ATTR_ENTITY_ID: ENTITY_DATETIME, ATTR_DATETIME: "2021-02-03 01:02:03"},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(ENTITY_DATETIME)
|
||||
assert state.state == "2021-02-03T01:02:03+00:00"
|
||||
@@ -19,12 +19,16 @@ from homeassistant.components.input_datetime import (
|
||||
CONFIG_SCHEMA,
|
||||
DEFAULT_TIME,
|
||||
DOMAIN,
|
||||
FMT_DATE,
|
||||
FMT_DATETIME,
|
||||
FMT_TIME,
|
||||
SERVICE_RELOAD,
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, ATTR_NAME
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_FRIENDLY_NAME,
|
||||
ATTR_NAME,
|
||||
FORMAT_DATE,
|
||||
FORMAT_DATETIME,
|
||||
FORMAT_TIME,
|
||||
)
|
||||
from homeassistant.core import Context, CoreState, HomeAssistant, State
|
||||
from homeassistant.exceptions import Unauthorized
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
@@ -136,7 +140,7 @@ async def test_set_datetime(hass: HomeAssistant) -> None:
|
||||
await async_set_date_and_time(hass, entity_id, dt_obj)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == dt_obj.strftime(FMT_DATETIME)
|
||||
assert state.state == dt_obj.strftime(FORMAT_DATETIME)
|
||||
assert state.attributes["has_time"]
|
||||
assert state.attributes["has_date"]
|
||||
|
||||
@@ -164,7 +168,7 @@ async def test_set_datetime_2(hass: HomeAssistant) -> None:
|
||||
await async_set_datetime(hass, entity_id, dt_obj)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == dt_obj.strftime(FMT_DATETIME)
|
||||
assert state.state == dt_obj.strftime(FORMAT_DATETIME)
|
||||
assert state.attributes["has_time"]
|
||||
assert state.attributes["has_date"]
|
||||
|
||||
@@ -192,7 +196,7 @@ async def test_set_datetime_3(hass: HomeAssistant) -> None:
|
||||
await async_set_timestamp(hass, entity_id, dt_util.as_utc(dt_obj).timestamp())
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == dt_obj.strftime(FMT_DATETIME)
|
||||
assert state.state == dt_obj.strftime(FORMAT_DATETIME)
|
||||
assert state.attributes["has_time"]
|
||||
assert state.attributes["has_date"]
|
||||
|
||||
@@ -218,7 +222,7 @@ async def test_set_datetime_time(hass: HomeAssistant) -> None:
|
||||
await async_set_date_and_time(hass, entity_id, dt_obj)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == dt_obj.strftime(FMT_TIME)
|
||||
assert state.state == dt_obj.strftime(FORMAT_TIME)
|
||||
assert state.attributes["has_time"]
|
||||
assert not state.attributes["has_date"]
|
||||
|
||||
@@ -337,7 +341,7 @@ async def test_restore_state(hass: HomeAssistant) -> None:
|
||||
"test_bogus_data": {
|
||||
"has_time": True,
|
||||
"has_date": True,
|
||||
"initial": initial.strftime(FMT_DATETIME),
|
||||
"initial": initial.strftime(FORMAT_DATETIME),
|
||||
},
|
||||
"test_was_time": {"has_time": False, "has_date": True},
|
||||
"test_was_date": {"has_time": True, "has_date": False},
|
||||
@@ -347,22 +351,22 @@ async def test_restore_state(hass: HomeAssistant) -> None:
|
||||
|
||||
dt_obj = datetime.datetime(2017, 9, 7, 19, 46)
|
||||
state_time = hass.states.get("input_datetime.test_time")
|
||||
assert state_time.state == dt_obj.strftime(FMT_TIME)
|
||||
assert state_time.state == dt_obj.strftime(FORMAT_TIME)
|
||||
|
||||
state_date = hass.states.get("input_datetime.test_date")
|
||||
assert state_date.state == dt_obj.strftime(FMT_DATE)
|
||||
assert state_date.state == dt_obj.strftime(FORMAT_DATE)
|
||||
|
||||
state_datetime = hass.states.get("input_datetime.test_datetime")
|
||||
assert state_datetime.state == dt_obj.strftime(FMT_DATETIME)
|
||||
assert state_datetime.state == dt_obj.strftime(FORMAT_DATETIME)
|
||||
|
||||
state_bogus = hass.states.get("input_datetime.test_bogus_data")
|
||||
assert state_bogus.state == initial.strftime(FMT_DATETIME)
|
||||
assert state_bogus.state == initial.strftime(FORMAT_DATETIME)
|
||||
|
||||
state_was_time = hass.states.get("input_datetime.test_was_time")
|
||||
assert state_was_time.state == default.strftime(FMT_DATE)
|
||||
assert state_was_time.state == default.strftime(FORMAT_DATE)
|
||||
|
||||
state_was_date = hass.states.get("input_datetime.test_was_date")
|
||||
assert state_was_date.state == default.strftime(FMT_TIME)
|
||||
assert state_was_date.state == default.strftime(FORMAT_TIME)
|
||||
|
||||
|
||||
async def test_default_value(hass: HomeAssistant) -> None:
|
||||
@@ -381,15 +385,15 @@ async def test_default_value(hass: HomeAssistant) -> None:
|
||||
|
||||
dt_obj = datetime.datetime.combine(datetime.date.today(), DEFAULT_TIME)
|
||||
state_time = hass.states.get("input_datetime.test_time")
|
||||
assert state_time.state == dt_obj.strftime(FMT_TIME)
|
||||
assert state_time.state == dt_obj.strftime(FORMAT_TIME)
|
||||
assert state_time.attributes.get("timestamp") is not None
|
||||
|
||||
state_date = hass.states.get("input_datetime.test_date")
|
||||
assert state_date.state == dt_obj.strftime(FMT_DATE)
|
||||
assert state_date.state == dt_obj.strftime(FORMAT_DATE)
|
||||
assert state_date.attributes.get("timestamp") is not None
|
||||
|
||||
state_datetime = hass.states.get("input_datetime.test_datetime")
|
||||
assert state_datetime.state == dt_obj.strftime(FMT_DATETIME)
|
||||
assert state_datetime.state == dt_obj.strftime(FORMAT_DATETIME)
|
||||
assert state_datetime.attributes.get("timestamp") is not None
|
||||
|
||||
|
||||
@@ -446,7 +450,7 @@ async def test_reload(
|
||||
assert state_1 is not None
|
||||
assert state_2 is None
|
||||
assert state_3 is not None
|
||||
assert dt_obj.strftime(FMT_DATE) == state_1.state
|
||||
assert dt_obj.strftime(FORMAT_DATE) == state_1.state
|
||||
assert ent_reg.async_get_entity_id(DOMAIN, DOMAIN, "dt1") == f"{DOMAIN}.dt1"
|
||||
assert ent_reg.async_get_entity_id(DOMAIN, DOMAIN, "dt2") is None
|
||||
assert ent_reg.async_get_entity_id(DOMAIN, DOMAIN, "dt3") == f"{DOMAIN}.dt3"
|
||||
@@ -484,10 +488,10 @@ async def test_reload(
|
||||
assert state_1 is not None
|
||||
assert state_2 is not None
|
||||
assert state_3 is None
|
||||
assert state_1.state == DEFAULT_TIME.strftime(FMT_TIME)
|
||||
assert state_1.state == DEFAULT_TIME.strftime(FORMAT_TIME)
|
||||
assert state_2.state == datetime.datetime.combine(
|
||||
datetime.date.today(), DEFAULT_TIME
|
||||
).strftime(FMT_DATETIME)
|
||||
).strftime(FORMAT_DATETIME)
|
||||
|
||||
assert ent_reg.async_get_entity_id(DOMAIN, DOMAIN, "dt1") == f"{DOMAIN}.dt1"
|
||||
assert ent_reg.async_get_entity_id(DOMAIN, DOMAIN, "dt2") == f"{DOMAIN}.dt2"
|
||||
@@ -705,7 +709,7 @@ async def test_timestamp(hass: HomeAssistant) -> None:
|
||||
assert (
|
||||
dt_util.as_local(
|
||||
dt_util.utc_from_timestamp(state_with_tz.attributes[ATTR_TIMESTAMP])
|
||||
).strftime(FMT_DATETIME)
|
||||
).strftime(FORMAT_DATETIME)
|
||||
== "2020-12-13 01:00:00"
|
||||
)
|
||||
|
||||
@@ -719,13 +723,13 @@ async def test_timestamp(hass: HomeAssistant) -> None:
|
||||
assert (
|
||||
dt_util.utc_from_timestamp(
|
||||
state_without_tz.attributes[ATTR_TIMESTAMP]
|
||||
).strftime(FMT_DATETIME)
|
||||
).strftime(FORMAT_DATETIME)
|
||||
== "2020-12-13 18:00:00"
|
||||
)
|
||||
assert (
|
||||
dt_util.as_local(
|
||||
dt_util.utc_from_timestamp(state_without_tz.attributes[ATTR_TIMESTAMP])
|
||||
).strftime(FMT_DATETIME)
|
||||
).strftime(FORMAT_DATETIME)
|
||||
== "2020-12-13 10:00:00"
|
||||
)
|
||||
# Use datetime.datetime.fromtimestamp
|
||||
@@ -734,7 +738,7 @@ async def test_timestamp(hass: HomeAssistant) -> None:
|
||||
datetime.datetime.fromtimestamp(
|
||||
state_without_tz.attributes[ATTR_TIMESTAMP], datetime.timezone.utc
|
||||
)
|
||||
).strftime(FMT_DATETIME)
|
||||
).strftime(FORMAT_DATETIME)
|
||||
== "2020-12-13 10:00:00"
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
"""Provide a mock time platform.
|
||||
|
||||
Call init before using it in your tests to ensure clean test data.
|
||||
"""
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from homeassistant.components.datetime import DateTimeEntity
|
||||
|
||||
from tests.common import MockEntity
|
||||
|
||||
UNIQUE_DATETIME = "unique_datetime"
|
||||
|
||||
ENTITIES = []
|
||||
|
||||
|
||||
class MockDateTimeEntity(MockEntity, DateTimeEntity):
|
||||
"""Mock date/time class."""
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the native value of this date/time."""
|
||||
return self._handle("native_value")
|
||||
|
||||
def set_value(self, value: datetime) -> None:
|
||||
"""Change the time."""
|
||||
self._values["native_value"] = value
|
||||
|
||||
|
||||
def init(empty=False):
|
||||
"""Initialize the platform with entities."""
|
||||
global ENTITIES
|
||||
|
||||
ENTITIES = (
|
||||
[]
|
||||
if empty
|
||||
else [
|
||||
MockDateTimeEntity(
|
||||
name="test",
|
||||
unique_id=UNIQUE_DATETIME,
|
||||
native_value=datetime(2020, 1, 1, 1, 2, 3, tzinfo=timezone.utc),
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_platform(
|
||||
hass, config, async_add_entities_callback, discovery_info=None
|
||||
):
|
||||
"""Return mock entities."""
|
||||
async_add_entities_callback(ENTITIES)
|
||||
Reference in New Issue
Block a user