Fix Mealie test coverage (#133659)
parent
1e420f16f7
commit
9a0035e090
|
@ -35,9 +35,7 @@ rules:
|
|||
log-when-unavailable: done
|
||||
parallel-updates: done
|
||||
reauthentication-flow: done
|
||||
test-coverage:
|
||||
status: todo
|
||||
comment: Platform missing tests
|
||||
test-coverage: done
|
||||
# Gold
|
||||
devices: done
|
||||
diagnostics: done
|
||||
|
|
|
@ -148,29 +148,19 @@ class MealieShoppingListTodoListEntity(MealieEntity, TodoListEntity):
|
|||
"""Update an item on the list."""
|
||||
list_items = self.shopping_items
|
||||
|
||||
for items in list_items:
|
||||
if items.item_id == item.uid:
|
||||
position = items.position
|
||||
break
|
||||
|
||||
list_item: ShoppingItem | None = next(
|
||||
(x for x in list_items if x.item_id == item.uid), None
|
||||
)
|
||||
assert list_item is not None
|
||||
position = list_item.position
|
||||
|
||||
if not list_item:
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="item_not_found_error",
|
||||
translation_placeholders={"shopping_list_item": item.uid or ""},
|
||||
)
|
||||
|
||||
udpdate_shopping_item = MutateShoppingItem(
|
||||
update_shopping_item = MutateShoppingItem(
|
||||
item_id=list_item.item_id,
|
||||
list_id=list_item.list_id,
|
||||
note=list_item.note,
|
||||
display=list_item.display,
|
||||
checked=item.status == TodoItemStatus.COMPLETED,
|
||||
position=list_item.position,
|
||||
position=position,
|
||||
is_food=list_item.is_food,
|
||||
disable_amount=list_item.disable_amount,
|
||||
quantity=list_item.quantity,
|
||||
|
@ -182,16 +172,16 @@ class MealieShoppingListTodoListEntity(MealieEntity, TodoListEntity):
|
|||
stripped_item_summary = item.summary.strip() if item.summary else item.summary
|
||||
|
||||
if list_item.display.strip() != stripped_item_summary:
|
||||
udpdate_shopping_item.note = stripped_item_summary
|
||||
udpdate_shopping_item.position = position
|
||||
udpdate_shopping_item.is_food = False
|
||||
udpdate_shopping_item.food_id = None
|
||||
udpdate_shopping_item.quantity = 0.0
|
||||
udpdate_shopping_item.checked = item.status == TodoItemStatus.COMPLETED
|
||||
update_shopping_item.note = stripped_item_summary
|
||||
update_shopping_item.position = position
|
||||
update_shopping_item.is_food = False
|
||||
update_shopping_item.food_id = None
|
||||
update_shopping_item.quantity = 0.0
|
||||
update_shopping_item.checked = item.status == TodoItemStatus.COMPLETED
|
||||
|
||||
try:
|
||||
await self.coordinator.client.update_shopping_item(
|
||||
list_item.item_id, udpdate_shopping_item
|
||||
list_item.item_id, update_shopping_item
|
||||
)
|
||||
except MealieError as exception:
|
||||
raise HomeAssistantError(
|
||||
|
|
|
@ -4,9 +4,10 @@ from datetime import date
|
|||
from http import HTTPStatus
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from aiomealie import MealplanResponse
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.const import STATE_OFF, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
|
@ -40,13 +41,28 @@ async def test_entities(
|
|||
mock_mealie_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the API returns the calendar."""
|
||||
"""Test the calendar entities."""
|
||||
with patch("homeassistant.components.mealie.PLATFORMS", [Platform.CALENDAR]):
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
|
||||
async def test_no_meal_planned(
|
||||
hass: HomeAssistant,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_registry: er.EntityRegistry,
|
||||
mock_mealie_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the calendar handles no meal planned."""
|
||||
mock_mealie_client.get_mealplans.return_value = MealplanResponse([])
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert hass.states.get("calendar.mealie_dinner").state == STATE_OFF
|
||||
|
||||
|
||||
async def test_api_events(
|
||||
hass: HomeAssistant,
|
||||
snapshot: SnapshotAssertion,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
"""Tests for the Mealie todo."""
|
||||
|
||||
from datetime import timedelta
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from unittest.mock import AsyncMock, call, patch
|
||||
|
||||
from aiomealie import MealieError, ShoppingListsResponse
|
||||
from aiomealie import MealieError, MutateShoppingItem, ShoppingListsResponse
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
@ -18,7 +18,7 @@ from homeassistant.components.todo import (
|
|||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from . import setup_integration
|
||||
|
@ -29,6 +29,7 @@ from tests.common import (
|
|||
load_fixture,
|
||||
snapshot_platform,
|
||||
)
|
||||
from tests.typing import WebSocketGenerator
|
||||
|
||||
|
||||
async def test_entities(
|
||||
|
@ -45,23 +46,38 @@ async def test_entities(
|
|||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
|
||||
async def test_add_todo_list_item(
|
||||
@pytest.mark.parametrize(
|
||||
("service", "data", "method"),
|
||||
[
|
||||
(TodoServices.ADD_ITEM, {ATTR_ITEM: "Soda"}, "add_shopping_item"),
|
||||
(
|
||||
TodoServices.UPDATE_ITEM,
|
||||
{ATTR_ITEM: "aubergine", ATTR_RENAME: "Eggplant", ATTR_STATUS: "completed"},
|
||||
"update_shopping_item",
|
||||
),
|
||||
(TodoServices.REMOVE_ITEM, {ATTR_ITEM: "aubergine"}, "delete_shopping_item"),
|
||||
],
|
||||
)
|
||||
async def test_todo_actions(
|
||||
hass: HomeAssistant,
|
||||
mock_mealie_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
service: str,
|
||||
data: dict[str, str],
|
||||
method: str,
|
||||
) -> None:
|
||||
"""Test for adding a To-do Item."""
|
||||
"""Test todo actions."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.ADD_ITEM,
|
||||
{ATTR_ITEM: "Soda"},
|
||||
service,
|
||||
data,
|
||||
target={ATTR_ENTITY_ID: "todo.mealie_supermarket"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mock_mealie_client.add_shopping_item.assert_called_once()
|
||||
getattr(mock_mealie_client, method).assert_called_once()
|
||||
|
||||
|
||||
async def test_add_todo_list_item_error(
|
||||
|
@ -74,7 +90,9 @@ async def test_add_todo_list_item_error(
|
|||
|
||||
mock_mealie_client.add_shopping_item.side_effect = MealieError
|
||||
|
||||
with pytest.raises(HomeAssistantError):
|
||||
with pytest.raises(
|
||||
HomeAssistantError, match="An error occurred adding an item to Supermarket"
|
||||
):
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.ADD_ITEM,
|
||||
|
@ -84,25 +102,6 @@ async def test_add_todo_list_item_error(
|
|||
)
|
||||
|
||||
|
||||
async def test_update_todo_list_item(
|
||||
hass: HomeAssistant,
|
||||
mock_mealie_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test for updating a To-do Item."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.UPDATE_ITEM,
|
||||
{ATTR_ITEM: "aubergine", ATTR_RENAME: "Eggplant", ATTR_STATUS: "completed"},
|
||||
target={ATTR_ENTITY_ID: "todo.mealie_supermarket"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mock_mealie_client.update_shopping_item.assert_called_once()
|
||||
|
||||
|
||||
async def test_update_todo_list_item_error(
|
||||
hass: HomeAssistant,
|
||||
mock_mealie_client: AsyncMock,
|
||||
|
@ -113,7 +112,9 @@ async def test_update_todo_list_item_error(
|
|||
|
||||
mock_mealie_client.update_shopping_item.side_effect = MealieError
|
||||
|
||||
with pytest.raises(HomeAssistantError):
|
||||
with pytest.raises(
|
||||
HomeAssistantError, match="An error occurred updating an item in Supermarket"
|
||||
):
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.UPDATE_ITEM,
|
||||
|
@ -123,23 +124,24 @@ async def test_update_todo_list_item_error(
|
|||
)
|
||||
|
||||
|
||||
async def test_delete_todo_list_item(
|
||||
async def test_update_non_existent_item(
|
||||
hass: HomeAssistant,
|
||||
mock_mealie_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test for deleting a To-do Item."""
|
||||
"""Test for updating a non-existent To-do Item."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.REMOVE_ITEM,
|
||||
{ATTR_ITEM: "aubergine"},
|
||||
target={ATTR_ENTITY_ID: "todo.mealie_supermarket"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mock_mealie_client.delete_shopping_item.assert_called_once()
|
||||
with pytest.raises(
|
||||
ServiceValidationError, match="Unable to find to-do list item: eggplant"
|
||||
):
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.UPDATE_ITEM,
|
||||
{ATTR_ITEM: "eggplant", ATTR_RENAME: "Aubergine", ATTR_STATUS: "completed"},
|
||||
target={ATTR_ENTITY_ID: "todo.mealie_supermarket"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
async def test_delete_todo_list_item_error(
|
||||
|
@ -153,7 +155,9 @@ async def test_delete_todo_list_item_error(
|
|||
mock_mealie_client.delete_shopping_item = AsyncMock()
|
||||
mock_mealie_client.delete_shopping_item.side_effect = MealieError
|
||||
|
||||
with pytest.raises(HomeAssistantError):
|
||||
with pytest.raises(
|
||||
HomeAssistantError, match="An error occurred deleting an item in Supermarket"
|
||||
):
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.REMOVE_ITEM,
|
||||
|
@ -163,6 +167,172 @@ async def test_delete_todo_list_item_error(
|
|||
)
|
||||
|
||||
|
||||
async def test_moving_todo_item(
|
||||
hass: HomeAssistant,
|
||||
mock_mealie_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test for moving a To-do Item to place."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
client = await hass_ws_client()
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 1,
|
||||
"type": "todo/item/move",
|
||||
"entity_id": "todo.mealie_supermarket",
|
||||
"uid": "f45430f7-3edf-45a9-a50f-73bb375090be",
|
||||
"previous_uid": "84d8fd74-8eb0-402e-84b6-71f251bfb7cc",
|
||||
}
|
||||
)
|
||||
resp = await client.receive_json()
|
||||
assert resp.get("id") == 1
|
||||
assert resp.get("success")
|
||||
assert resp.get("result") is None
|
||||
|
||||
assert mock_mealie_client.update_shopping_item.call_count == 3
|
||||
calls = mock_mealie_client.update_shopping_item.mock_calls
|
||||
|
||||
assert calls[0] == call(
|
||||
"84d8fd74-8eb0-402e-84b6-71f251bfb7cc",
|
||||
MutateShoppingItem(
|
||||
item_id="84d8fd74-8eb0-402e-84b6-71f251bfb7cc",
|
||||
list_id="9ce096fe-ded2-4077-877d-78ba450ab13e",
|
||||
note="",
|
||||
display=None,
|
||||
checked=False,
|
||||
position=0,
|
||||
is_food=True,
|
||||
disable_amount=None,
|
||||
quantity=1.0,
|
||||
label_id=None,
|
||||
food_id="09322430-d24c-4b1a-abb6-22b6ed3a88f5",
|
||||
unit_id="7bf539d4-fc78-48bc-b48e-c35ccccec34a",
|
||||
),
|
||||
)
|
||||
|
||||
assert calls[1] == call(
|
||||
"f45430f7-3edf-45a9-a50f-73bb375090be",
|
||||
MutateShoppingItem(
|
||||
item_id="f45430f7-3edf-45a9-a50f-73bb375090be",
|
||||
list_id="9ce096fe-ded2-4077-877d-78ba450ab13e",
|
||||
note="Apples",
|
||||
display=None,
|
||||
checked=False,
|
||||
position=1,
|
||||
is_food=False,
|
||||
disable_amount=None,
|
||||
quantity=2.0,
|
||||
label_id=None,
|
||||
food_id=None,
|
||||
unit_id=None,
|
||||
),
|
||||
)
|
||||
|
||||
assert calls[2] == call(
|
||||
"69913b9a-7c75-4935-abec-297cf7483f88",
|
||||
MutateShoppingItem(
|
||||
item_id="69913b9a-7c75-4935-abec-297cf7483f88",
|
||||
list_id="9ce096fe-ded2-4077-877d-78ba450ab13e",
|
||||
note="",
|
||||
display=None,
|
||||
checked=False,
|
||||
position=2,
|
||||
is_food=True,
|
||||
disable_amount=None,
|
||||
quantity=0.0,
|
||||
label_id=None,
|
||||
food_id="96801494-4e26-4148-849a-8155deb76327",
|
||||
unit_id=None,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def test_not_moving_todo_item(
|
||||
hass: HomeAssistant,
|
||||
mock_mealie_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test for moving a To-do Item to the same place."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
client = await hass_ws_client()
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 1,
|
||||
"type": "todo/item/move",
|
||||
"entity_id": "todo.mealie_supermarket",
|
||||
"uid": "f45430f7-3edf-45a9-a50f-73bb375090be",
|
||||
"previous_uid": "f45430f7-3edf-45a9-a50f-73bb375090be",
|
||||
}
|
||||
)
|
||||
resp = await client.receive_json()
|
||||
assert resp.get("id") == 1
|
||||
assert resp.get("success")
|
||||
assert resp.get("result") is None
|
||||
|
||||
assert mock_mealie_client.update_shopping_item.call_count == 0
|
||||
|
||||
|
||||
async def test_moving_todo_item_invalid_uid(
|
||||
hass: HomeAssistant,
|
||||
mock_mealie_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test for moving a To-do Item to place with invalid UID."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
client = await hass_ws_client()
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 1,
|
||||
"type": "todo/item/move",
|
||||
"entity_id": "todo.mealie_supermarket",
|
||||
"uid": "cheese",
|
||||
}
|
||||
)
|
||||
resp = await client.receive_json()
|
||||
assert resp.get("id") == 1
|
||||
assert resp.get("success") is False
|
||||
assert resp.get("result") is None
|
||||
assert resp["error"]["code"] == "failed"
|
||||
assert resp["error"]["message"] == "Item cheese not found"
|
||||
|
||||
assert mock_mealie_client.update_shopping_item.call_count == 0
|
||||
|
||||
|
||||
async def test_moving_todo_item_invalid_previous_uid(
|
||||
hass: HomeAssistant,
|
||||
mock_mealie_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test for moving a To-do Item to place with invalid previous UID."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
client = await hass_ws_client()
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 1,
|
||||
"type": "todo/item/move",
|
||||
"entity_id": "todo.mealie_supermarket",
|
||||
"uid": "f45430f7-3edf-45a9-a50f-73bb375090be",
|
||||
"previous_uid": "cheese",
|
||||
}
|
||||
)
|
||||
resp = await client.receive_json()
|
||||
assert resp.get("id") == 1
|
||||
assert resp.get("success") is False
|
||||
assert resp.get("result") is None
|
||||
assert resp["error"]["code"] == "failed"
|
||||
assert resp["error"]["message"] == "Item cheese not found"
|
||||
|
||||
assert mock_mealie_client.update_shopping_item.call_count == 0
|
||||
|
||||
|
||||
async def test_runtime_management(
|
||||
hass: HomeAssistant,
|
||||
mock_mealie_client: AsyncMock,
|
||||
|
|
Loading…
Reference in New Issue