hass-core/tests/components/tibber/test_services.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

259 lines
8.7 KiB
Python
Raw Normal View History

"""Test service for Tibber integration."""
import asyncio
import datetime as dt
from unittest.mock import MagicMock
2024-07-16 22:36:31 +02:00
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.tibber.const import DOMAIN
from homeassistant.components.tibber.services import PRICE_SERVICE_NAME, __get_prices
from homeassistant.core import ServiceCall
from homeassistant.exceptions import ServiceValidationError
2024-07-16 22:36:31 +02:00
STARTTIME = dt.datetime.fromtimestamp(1615766400)
def generate_mock_home_data():
"""Create mock data from the tibber connection."""
2024-07-16 22:36:31 +02:00
tomorrow = STARTTIME + dt.timedelta(days=1)
mock_homes = [
MagicMock(
name="first_home",
info={
"viewer": {
"home": {
"currentSubscription": {
"priceInfo": {
"today": [
{
2024-07-16 22:36:31 +02:00
"startsAt": STARTTIME.isoformat(),
"total": 0.46914,
"level": "VERY_EXPENSIVE",
},
{
"startsAt": (
2024-07-16 22:36:31 +02:00
STARTTIME + dt.timedelta(hours=1)
).isoformat(),
"total": 0.46914,
"level": "VERY_EXPENSIVE",
},
],
"tomorrow": [
{
"startsAt": tomorrow.isoformat(),
"total": 0.46914,
"level": "VERY_EXPENSIVE",
},
{
"startsAt": (
tomorrow + dt.timedelta(hours=1)
).isoformat(),
"total": 0.46914,
"level": "VERY_EXPENSIVE",
},
],
}
}
}
}
},
),
MagicMock(
name="second_home",
info={
"viewer": {
"home": {
"currentSubscription": {
"priceInfo": {
"today": [
{
2024-07-16 22:36:31 +02:00
"startsAt": STARTTIME.isoformat(),
"total": 0.46914,
"level": "VERY_EXPENSIVE",
},
{
"startsAt": (
2024-07-16 22:36:31 +02:00
STARTTIME + dt.timedelta(hours=1)
).isoformat(),
"total": 0.46914,
"level": "VERY_EXPENSIVE",
},
],
"tomorrow": [
{
"startsAt": tomorrow.isoformat(),
"total": 0.46914,
"level": "VERY_EXPENSIVE",
},
{
"startsAt": (
tomorrow + dt.timedelta(hours=1)
).isoformat(),
"total": 0.46914,
"level": "VERY_EXPENSIVE",
},
],
}
}
}
}
},
),
]
mock_homes[0].name = "first_home"
mock_homes[1].name = "second_home"
return mock_homes
def create_mock_tibber_connection():
"""Create a mock tibber connection."""
tibber_connection = MagicMock()
tibber_connection.get_homes.return_value = generate_mock_home_data()
return tibber_connection
def create_mock_hass():
"""Create a mock hass object."""
mock_hass = MagicMock
mock_hass.data = {"tibber": create_mock_tibber_connection()}
return mock_hass
2024-07-16 22:36:31 +02:00
async def test_get_prices(
freezer: FrozenDateTimeFactory,
) -> None:
"""Test __get_prices with mock data."""
2024-07-16 22:36:31 +02:00
freezer.move_to(STARTTIME)
tomorrow = STARTTIME + dt.timedelta(days=1)
call = ServiceCall(
DOMAIN,
PRICE_SERVICE_NAME,
2024-07-16 22:36:31 +02:00
{"start": STARTTIME.date().isoformat(), "end": tomorrow.date().isoformat()},
)
result = await __get_prices(call, hass=create_mock_hass())
assert result == {
"prices": {
"first_home": [
{
2024-07-16 22:36:31 +02:00
"start_time": STARTTIME,
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
{
2024-07-16 22:36:31 +02:00
"start_time": STARTTIME + dt.timedelta(hours=1),
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
],
"second_home": [
{
2024-07-16 22:36:31 +02:00
"start_time": STARTTIME,
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
{
2024-07-16 22:36:31 +02:00
"start_time": STARTTIME + dt.timedelta(hours=1),
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
],
}
}
2024-07-16 22:36:31 +02:00
async def test_get_prices_no_input(
freezer: FrozenDateTimeFactory,
) -> None:
"""Test __get_prices with no input."""
2024-07-16 22:36:31 +02:00
freezer.move_to(STARTTIME)
call = ServiceCall(DOMAIN, PRICE_SERVICE_NAME, {})
result = await __get_prices(call, hass=create_mock_hass())
assert result == {
"prices": {
"first_home": [
{
2024-07-16 22:36:31 +02:00
"start_time": STARTTIME,
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
{
2024-07-16 22:36:31 +02:00
"start_time": STARTTIME + dt.timedelta(hours=1),
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
],
"second_home": [
{
2024-07-16 22:36:31 +02:00
"start_time": STARTTIME,
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
{
2024-07-16 22:36:31 +02:00
"start_time": STARTTIME + dt.timedelta(hours=1),
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
],
}
}
2024-07-16 22:36:31 +02:00
async def test_get_prices_start_tomorrow(
freezer: FrozenDateTimeFactory,
) -> None:
"""Test __get_prices with start date tomorrow."""
2024-07-16 22:36:31 +02:00
freezer.move_to(STARTTIME)
tomorrow = STARTTIME + dt.timedelta(days=1)
call = ServiceCall(
DOMAIN, PRICE_SERVICE_NAME, {"start": tomorrow.date().isoformat()}
)
result = await __get_prices(call, hass=create_mock_hass())
assert result == {
"prices": {
"first_home": [
{
"start_time": tomorrow,
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
{
"start_time": tomorrow + dt.timedelta(hours=1),
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
],
"second_home": [
{
"start_time": tomorrow,
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
{
"start_time": tomorrow + dt.timedelta(hours=1),
"price": 0.46914,
"level": "VERY_EXPENSIVE",
},
],
}
}
2024-07-16 22:36:31 +02:00
async def test_get_prices_invalid_input() -> None:
"""Test __get_prices with invalid input."""
call = ServiceCall(DOMAIN, PRICE_SERVICE_NAME, {"start": "test"})
task = asyncio.create_task(__get_prices(call, hass=create_mock_hass()))
with pytest.raises(ServiceValidationError) as excinfo:
await task
assert "Invalid datetime provided." in str(excinfo.value)