mirror of
https://github.com/home-assistant/core.git
synced 2026-08-06 21:35:13 +01:00
104 lines
3.4 KiB
Python
104 lines
3.4 KiB
Python
"""Tests for the moon triggers."""
|
|
|
|
from datetime import datetime, timedelta
|
|
from typing import Any
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from homeassistant.components import automation
|
|
from homeassistant.core import HomeAssistant, ServiceCall
|
|
from homeassistant.setup import async_setup_component
|
|
from homeassistant.util import dt as dt_util
|
|
|
|
from tests.common import MockConfigEntry, async_fire_time_changed
|
|
|
|
_PHASE = "homeassistant.components.moon.helpers.moon.phase"
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
async def setup_moon(hass: HomeAssistant, mock_config_entry: MockConfigEntry) -> None:
|
|
"""Set up the moon integration so its trigger platform is available."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
async def _arm(hass: HomeAssistant, options: dict[str, Any] | None = None) -> None:
|
|
"""Set up an automation with the moon phase_changed trigger."""
|
|
trigger: dict[str, Any] = {"platform": "moon.phase_changed"}
|
|
if options is not None:
|
|
trigger["options"] = options
|
|
await async_setup_component(
|
|
hass,
|
|
automation.DOMAIN,
|
|
{
|
|
automation.DOMAIN: {
|
|
"trigger": trigger,
|
|
"action": {
|
|
"service": "test.automation",
|
|
"data_template": {
|
|
"phase": "{{ trigger.phase }}",
|
|
"previous_phase": "{{ trigger.previous_phase }}",
|
|
},
|
|
},
|
|
}
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
def _next_local_midnight() -> datetime:
|
|
"""Return the next local midnight, when the phase trigger re-evaluates."""
|
|
return dt_util.start_of_local_day() + timedelta(days=1)
|
|
|
|
|
|
async def test_phase_changed_fires_on_any_change(
|
|
hass: HomeAssistant, service_calls: list[ServiceCall]
|
|
) -> None:
|
|
"""Test the trigger fires on every phase change when unfiltered."""
|
|
with patch(_PHASE, return_value=0.0):
|
|
await _arm(hass)
|
|
assert len(service_calls) == 0
|
|
|
|
with patch(_PHASE, return_value=14.0):
|
|
async_fire_time_changed(hass, _next_local_midnight())
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(service_calls) == 1
|
|
assert service_calls[0].data["phase"] == "full_moon"
|
|
assert service_calls[0].data["previous_phase"] == "new_moon"
|
|
|
|
|
|
async def test_phase_changed_ignores_same_phase(
|
|
hass: HomeAssistant, service_calls: list[ServiceCall]
|
|
) -> None:
|
|
"""Test the trigger does not fire when the phase is unchanged."""
|
|
with patch(_PHASE, return_value=14.0):
|
|
await _arm(hass)
|
|
async_fire_time_changed(hass, _next_local_midnight())
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(service_calls) == 0
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("new_value", "expected_calls"),
|
|
[(14.0, 1), (5.0, 0)],
|
|
)
|
|
async def test_phase_changed_with_phase_filter(
|
|
hass: HomeAssistant,
|
|
service_calls: list[ServiceCall],
|
|
new_value: float,
|
|
expected_calls: int,
|
|
) -> None:
|
|
"""Test the trigger only fires for the configured phase."""
|
|
with patch(_PHASE, return_value=0.0):
|
|
await _arm(hass, options={"phase": "full_moon"})
|
|
|
|
with patch(_PHASE, return_value=new_value):
|
|
async_fire_time_changed(hass, _next_local_midnight())
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(service_calls) == expected_calls
|