Add unique id to Mealie config entry (#120816)

This commit is contained in:
Joost Lekkerkerker 2024-06-29 17:48:28 +02:00 committed by GitHub
parent 0ab7647fea
commit 25932dff28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 47 additions and 17 deletions

View File

@ -50,12 +50,9 @@ class MealieMealplanCalendarEntity(MealieEntity, CalendarEntity):
self, coordinator: MealieCoordinator, entry_type: MealplanEntryType
) -> None:
"""Create the Calendar entity."""
super().__init__(coordinator)
super().__init__(coordinator, entry_type.name.lower())
self._entry_type = entry_type
self._attr_translation_key = entry_type.name.lower()
self._attr_unique_id = (
f"{self.coordinator.config_entry.entry_id}_{entry_type.name.lower()}"
)
@property
def event(self) -> CalendarEvent | None:

View File

@ -28,14 +28,13 @@ class MealieConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a flow initialized by the user."""
errors: dict[str, str] = {}
if user_input:
self._async_abort_entries_match({CONF_HOST: user_input[CONF_HOST]})
client = MealieClient(
user_input[CONF_HOST],
token=user_input[CONF_API_TOKEN],
session=async_get_clientsession(self.hass),
)
try:
await client.get_mealplan_today()
info = await client.get_user_info()
except MealieConnectionError:
errors["base"] = "cannot_connect"
except MealieAuthenticationError:
@ -44,6 +43,8 @@ class MealieConfigFlow(ConfigFlow, domain=DOMAIN):
LOGGER.exception("Unexpected error")
errors["base"] = "unknown"
else:
await self.async_set_unique_id(info.user_id)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title="Mealie",
data=user_input,

View File

@ -12,10 +12,13 @@ class MealieEntity(CoordinatorEntity[MealieCoordinator]):
_attr_has_entity_name = True
def __init__(self, coordinator: MealieCoordinator) -> None:
def __init__(self, coordinator: MealieCoordinator, key: str) -> None:
"""Initialize Mealie entity."""
super().__init__(coordinator)
unique_id = coordinator.config_entry.unique_id
assert unique_id is not None
self._attr_unique_id = f"{unique_id}_{key}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, coordinator.config_entry.entry_id)},
identifiers={(DOMAIN, unique_id)},
entry_type=DeviceEntryType.SERVICE,
)

View File

@ -2,7 +2,7 @@
from unittest.mock import patch
from aiomealie import Mealplan, MealplanResponse
from aiomealie import Mealplan, MealplanResponse, UserInfo
from mashumaro.codecs.orjson import ORJSONDecoder
import pytest
from typing_extensions import Generator
@ -44,6 +44,9 @@ def mock_mealie_client() -> Generator[AsyncMock]:
client.get_mealplan_today.return_value = ORJSONDecoder(list[Mealplan]).decode(
load_fixture("get_mealplan_today.json", DOMAIN)
)
client.get_user_info.return_value = UserInfo.from_json(
load_fixture("users_self.json", DOMAIN)
)
yield client
@ -55,4 +58,5 @@ def mock_config_entry() -> MockConfigEntry:
title="Mealie",
data={CONF_HOST: "demo.mealie.io", CONF_API_TOKEN: "token"},
entry_id="01J0BC4QM2YBRP6H5G933CETT7",
unique_id="bf1c62fe-4941-4332-9886-e54e88dbdba0",
)

View File

@ -0,0 +1,24 @@
{
"id": "bf1c62fe-4941-4332-9886-e54e88dbdba0",
"username": "admin",
"fullName": "Change Me",
"email": "changeme@example.com",
"authMethod": "Mealie",
"admin": true,
"group": "home",
"advanced": true,
"canInvite": true,
"canManage": true,
"canOrganize": true,
"groupId": "24477569-f6af-4b53-9e3f-6d04b0ca6916",
"groupSlug": "home",
"tokens": [
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb25nX3Rva2VuIjp0cnVlLCJpZCI6ImJmMWM2MmZlLTQ5NDEtNDMzMi05ODg2LWU1NGU4OGRiZGJhMCIsIm5hbWUiOiJ0ZXN0aW5nIiwiaW50ZWdyYXRpb25faWQiOiJnZW5lcmljIiwiZXhwIjoxODczOTA5ODk4fQ.xwXZp4fL2g1RbIqGtBeOaS6RDfsYbQDHj8XtRM3wlX0",
"name": "testing",
"id": 2,
"createdAt": "2024-05-20T10:31:38.179669"
}
],
"cacheKey": "1234"
}

View File

@ -192,7 +192,7 @@
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'breakfast',
'unique_id': '01J0BC4QM2YBRP6H5G933CETT7_breakfast',
'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_breakfast',
'unit_of_measurement': None,
})
# ---
@ -244,7 +244,7 @@
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'dinner',
'unique_id': '01J0BC4QM2YBRP6H5G933CETT7_dinner',
'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_dinner',
'unit_of_measurement': None,
})
# ---
@ -296,7 +296,7 @@
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'lunch',
'unique_id': '01J0BC4QM2YBRP6H5G933CETT7_lunch',
'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_lunch',
'unit_of_measurement': None,
})
# ---
@ -348,7 +348,7 @@
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'side',
'unique_id': '01J0BC4QM2YBRP6H5G933CETT7_side',
'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_side',
'unit_of_measurement': None,
})
# ---

View File

@ -13,7 +13,7 @@
'identifiers': set({
tuple(
'mealie',
'01J0BC4QM2YBRP6H5G933CETT7',
'bf1c62fe-4941-4332-9886-e54e88dbdba0',
),
}),
'is_new': False,

View File

@ -37,6 +37,7 @@ async def test_full_flow(
CONF_HOST: "demo.mealie.io",
CONF_API_TOKEN: "token",
}
assert result["result"].unique_id == "bf1c62fe-4941-4332-9886-e54e88dbdba0"
@pytest.mark.parametrize(
@ -55,7 +56,7 @@ async def test_flow_errors(
error: str,
) -> None:
"""Test flow errors."""
mock_mealie_client.get_mealplan_today.side_effect = exception
mock_mealie_client.get_user_info.side_effect = exception
result = await hass.config_entries.flow.async_init(
DOMAIN,
@ -72,7 +73,7 @@ async def test_flow_errors(
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": error}
mock_mealie_client.get_mealplan_today.side_effect = None
mock_mealie_client.get_user_info.side_effect = None
result = await hass.config_entries.flow.async_configure(
result["flow_id"],

View File

@ -26,7 +26,7 @@ async def test_device_info(
"""Test device registry integration."""
await setup_integration(hass, mock_config_entry)
device_entry = device_registry.async_get_device(
identifiers={(DOMAIN, mock_config_entry.entry_id)}
identifiers={(DOMAIN, mock_config_entry.unique_id)}
)
assert device_entry is not None
assert device_entry == snapshot