core/tests/components/mealie/test_services.py

298 lines
8.2 KiB
Python
Raw Normal View History

"""Tests for the Mealie services."""
from datetime import date
from unittest.mock import AsyncMock
from aiomealie import MealieConnectionError, MealieNotFoundError, MealieValidationError
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy import SnapshotAssertion
from homeassistant.components.mealie.const import (
ATTR_CONFIG_ENTRY_ID,
ATTR_END_DATE,
ATTR_INCLUDE_TAGS,
ATTR_RECIPE_ID,
ATTR_START_DATE,
ATTR_URL,
DOMAIN,
)
from homeassistant.components.mealie.services import (
SERVICE_GET_MEALPLAN,
SERVICE_GET_RECIPE,
SERVICE_IMPORT_RECIPE,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from . import setup_integration
from tests.common import MockConfigEntry
async def test_service_mealplan(
hass: HomeAssistant,
mock_mealie_client: AsyncMock,
mock_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test the get_mealplan service."""
await setup_integration(hass, mock_config_entry)
freezer.move_to("2023-10-21")
response = await hass.services.async_call(
DOMAIN,
SERVICE_GET_MEALPLAN,
{ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id},
blocking=True,
return_response=True,
)
assert mock_mealie_client.get_mealplans.call_args_list[1][0] == (
date(2023, 10, 21),
date(2023, 10, 21),
)
assert response == snapshot
response = await hass.services.async_call(
DOMAIN,
SERVICE_GET_MEALPLAN,
{
ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id,
ATTR_START_DATE: "2023-10-22",
ATTR_END_DATE: "2023-10-25",
},
blocking=True,
return_response=True,
)
assert response
assert mock_mealie_client.get_mealplans.call_args_list[2][0] == (
date(2023, 10, 22),
date(2023, 10, 25),
)
response = await hass.services.async_call(
DOMAIN,
SERVICE_GET_MEALPLAN,
{
ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id,
ATTR_START_DATE: "2023-10-19",
},
blocking=True,
return_response=True,
)
assert response
assert mock_mealie_client.get_mealplans.call_args_list[3][0] == (
date(2023, 10, 19),
date(2023, 10, 21),
)
response = await hass.services.async_call(
DOMAIN,
SERVICE_GET_MEALPLAN,
{
ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id,
ATTR_END_DATE: "2023-10-22",
},
blocking=True,
return_response=True,
)
assert response
assert mock_mealie_client.get_mealplans.call_args_list[4][0] == (
date(2023, 10, 21),
date(2023, 10, 22),
)
with pytest.raises(ServiceValidationError):
await hass.services.async_call(
DOMAIN,
SERVICE_GET_MEALPLAN,
{
ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id,
ATTR_START_DATE: "2023-10-22",
ATTR_END_DATE: "2023-10-19",
},
blocking=True,
return_response=True,
)
async def test_service_recipe(
hass: HomeAssistant,
mock_mealie_client: AsyncMock,
mock_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the get_recipe service."""
await setup_integration(hass, mock_config_entry)
response = await hass.services.async_call(
DOMAIN,
SERVICE_GET_RECIPE,
{ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id, ATTR_RECIPE_ID: "recipe_id"},
blocking=True,
return_response=True,
)
assert response == snapshot
async def test_service_import_recipe(
hass: HomeAssistant,
mock_mealie_client: AsyncMock,
mock_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the import_recipe service."""
await setup_integration(hass, mock_config_entry)
response = await hass.services.async_call(
DOMAIN,
SERVICE_IMPORT_RECIPE,
{
ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id,
ATTR_URL: "http://example.com",
},
blocking=True,
return_response=True,
)
assert response == snapshot
mock_mealie_client.import_recipe.assert_called_with(
"http://example.com", include_tags=False
)
await hass.services.async_call(
DOMAIN,
SERVICE_IMPORT_RECIPE,
{
ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id,
ATTR_URL: "http://example.com",
ATTR_INCLUDE_TAGS: True,
},
blocking=True,
return_response=False,
)
mock_mealie_client.import_recipe.assert_called_with(
"http://example.com", include_tags=True
)
@pytest.mark.parametrize(
("exception", "raised_exception"),
[
(MealieNotFoundError, ServiceValidationError),
(MealieConnectionError, HomeAssistantError),
],
)
async def test_service_recipe_exceptions(
hass: HomeAssistant,
mock_mealie_client: AsyncMock,
mock_config_entry: MockConfigEntry,
exception: Exception,
raised_exception: type[Exception],
) -> None:
"""Test the get_recipe service."""
await setup_integration(hass, mock_config_entry)
mock_mealie_client.get_recipe.side_effect = exception
with pytest.raises(raised_exception):
await hass.services.async_call(
DOMAIN,
SERVICE_GET_RECIPE,
{
ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id,
ATTR_RECIPE_ID: "recipe_id",
},
blocking=True,
return_response=True,
)
@pytest.mark.parametrize(
("exception", "raised_exception"),
[
(MealieValidationError, ServiceValidationError),
(MealieConnectionError, HomeAssistantError),
],
)
async def test_service_import_recipe_exceptions(
hass: HomeAssistant,
mock_mealie_client: AsyncMock,
mock_config_entry: MockConfigEntry,
exception: Exception,
raised_exception: type[Exception],
) -> None:
"""Test the exceptions of the import_recipe service."""
await setup_integration(hass, mock_config_entry)
mock_mealie_client.import_recipe.side_effect = exception
with pytest.raises(raised_exception):
await hass.services.async_call(
DOMAIN,
SERVICE_IMPORT_RECIPE,
{
ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id,
ATTR_URL: "http://example.com",
},
blocking=True,
return_response=True,
)
async def test_service_mealplan_connection_error(
hass: HomeAssistant,
mock_mealie_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test a connection error in the get_mealplans service."""
await setup_integration(hass, mock_config_entry)
mock_mealie_client.get_mealplans.side_effect = MealieConnectionError
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
DOMAIN,
SERVICE_GET_MEALPLAN,
{ATTR_CONFIG_ENTRY_ID: mock_config_entry.entry_id},
blocking=True,
return_response=True,
)
async def test_service_mealplan_without_entry(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the get_mealplan service without entry."""
mock_config_entry.add_to_hass(hass)
mock_config_entry2 = MockConfigEntry(domain=DOMAIN)
mock_config_entry2.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
with pytest.raises(ServiceValidationError):
await hass.services.async_call(
DOMAIN,
SERVICE_GET_MEALPLAN,
{ATTR_CONFIG_ENTRY_ID: mock_config_entry2.entry_id},
blocking=True,
return_response=True,
)
with pytest.raises(ServiceValidationError):
await hass.services.async_call(
DOMAIN,
SERVICE_GET_MEALPLAN,
{ATTR_CONFIG_ENTRY_ID: "bad-config_id"},
blocking=True,
return_response=True,
)