mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 10:17:09 +00:00
Add unique id to Mealie config entry (#120816)
This commit is contained in:
parent
0ab7647fea
commit
25932dff28
@ -50,12 +50,9 @@ class MealieMealplanCalendarEntity(MealieEntity, CalendarEntity):
|
|||||||
self, coordinator: MealieCoordinator, entry_type: MealplanEntryType
|
self, coordinator: MealieCoordinator, entry_type: MealplanEntryType
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Create the Calendar entity."""
|
"""Create the Calendar entity."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator, entry_type.name.lower())
|
||||||
self._entry_type = entry_type
|
self._entry_type = entry_type
|
||||||
self._attr_translation_key = entry_type.name.lower()
|
self._attr_translation_key = entry_type.name.lower()
|
||||||
self._attr_unique_id = (
|
|
||||||
f"{self.coordinator.config_entry.entry_id}_{entry_type.name.lower()}"
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def event(self) -> CalendarEvent | None:
|
def event(self) -> CalendarEvent | None:
|
||||||
|
@ -28,14 +28,13 @@ class MealieConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
"""Handle a flow initialized by the user."""
|
"""Handle a flow initialized by the user."""
|
||||||
errors: dict[str, str] = {}
|
errors: dict[str, str] = {}
|
||||||
if user_input:
|
if user_input:
|
||||||
self._async_abort_entries_match({CONF_HOST: user_input[CONF_HOST]})
|
|
||||||
client = MealieClient(
|
client = MealieClient(
|
||||||
user_input[CONF_HOST],
|
user_input[CONF_HOST],
|
||||||
token=user_input[CONF_API_TOKEN],
|
token=user_input[CONF_API_TOKEN],
|
||||||
session=async_get_clientsession(self.hass),
|
session=async_get_clientsession(self.hass),
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
await client.get_mealplan_today()
|
info = await client.get_user_info()
|
||||||
except MealieConnectionError:
|
except MealieConnectionError:
|
||||||
errors["base"] = "cannot_connect"
|
errors["base"] = "cannot_connect"
|
||||||
except MealieAuthenticationError:
|
except MealieAuthenticationError:
|
||||||
@ -44,6 +43,8 @@ class MealieConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
LOGGER.exception("Unexpected error")
|
LOGGER.exception("Unexpected error")
|
||||||
errors["base"] = "unknown"
|
errors["base"] = "unknown"
|
||||||
else:
|
else:
|
||||||
|
await self.async_set_unique_id(info.user_id)
|
||||||
|
self._abort_if_unique_id_configured()
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title="Mealie",
|
title="Mealie",
|
||||||
data=user_input,
|
data=user_input,
|
||||||
|
@ -12,10 +12,13 @@ class MealieEntity(CoordinatorEntity[MealieCoordinator]):
|
|||||||
|
|
||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
def __init__(self, coordinator: MealieCoordinator) -> None:
|
def __init__(self, coordinator: MealieCoordinator, key: str) -> None:
|
||||||
"""Initialize Mealie entity."""
|
"""Initialize Mealie entity."""
|
||||||
super().__init__(coordinator)
|
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(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, coordinator.config_entry.entry_id)},
|
identifiers={(DOMAIN, unique_id)},
|
||||||
entry_type=DeviceEntryType.SERVICE,
|
entry_type=DeviceEntryType.SERVICE,
|
||||||
)
|
)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from aiomealie import Mealplan, MealplanResponse
|
from aiomealie import Mealplan, MealplanResponse, UserInfo
|
||||||
from mashumaro.codecs.orjson import ORJSONDecoder
|
from mashumaro.codecs.orjson import ORJSONDecoder
|
||||||
import pytest
|
import pytest
|
||||||
from typing_extensions import Generator
|
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(
|
client.get_mealplan_today.return_value = ORJSONDecoder(list[Mealplan]).decode(
|
||||||
load_fixture("get_mealplan_today.json", DOMAIN)
|
load_fixture("get_mealplan_today.json", DOMAIN)
|
||||||
)
|
)
|
||||||
|
client.get_user_info.return_value = UserInfo.from_json(
|
||||||
|
load_fixture("users_self.json", DOMAIN)
|
||||||
|
)
|
||||||
yield client
|
yield client
|
||||||
|
|
||||||
|
|
||||||
@ -55,4 +58,5 @@ def mock_config_entry() -> MockConfigEntry:
|
|||||||
title="Mealie",
|
title="Mealie",
|
||||||
data={CONF_HOST: "demo.mealie.io", CONF_API_TOKEN: "token"},
|
data={CONF_HOST: "demo.mealie.io", CONF_API_TOKEN: "token"},
|
||||||
entry_id="01J0BC4QM2YBRP6H5G933CETT7",
|
entry_id="01J0BC4QM2YBRP6H5G933CETT7",
|
||||||
|
unique_id="bf1c62fe-4941-4332-9886-e54e88dbdba0",
|
||||||
)
|
)
|
||||||
|
24
tests/components/mealie/fixtures/users_self.json
Normal file
24
tests/components/mealie/fixtures/users_self.json
Normal 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"
|
||||||
|
}
|
@ -192,7 +192,7 @@
|
|||||||
'previous_unique_id': None,
|
'previous_unique_id': None,
|
||||||
'supported_features': 0,
|
'supported_features': 0,
|
||||||
'translation_key': 'breakfast',
|
'translation_key': 'breakfast',
|
||||||
'unique_id': '01J0BC4QM2YBRP6H5G933CETT7_breakfast',
|
'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_breakfast',
|
||||||
'unit_of_measurement': None,
|
'unit_of_measurement': None,
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
@ -244,7 +244,7 @@
|
|||||||
'previous_unique_id': None,
|
'previous_unique_id': None,
|
||||||
'supported_features': 0,
|
'supported_features': 0,
|
||||||
'translation_key': 'dinner',
|
'translation_key': 'dinner',
|
||||||
'unique_id': '01J0BC4QM2YBRP6H5G933CETT7_dinner',
|
'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_dinner',
|
||||||
'unit_of_measurement': None,
|
'unit_of_measurement': None,
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
@ -296,7 +296,7 @@
|
|||||||
'previous_unique_id': None,
|
'previous_unique_id': None,
|
||||||
'supported_features': 0,
|
'supported_features': 0,
|
||||||
'translation_key': 'lunch',
|
'translation_key': 'lunch',
|
||||||
'unique_id': '01J0BC4QM2YBRP6H5G933CETT7_lunch',
|
'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_lunch',
|
||||||
'unit_of_measurement': None,
|
'unit_of_measurement': None,
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
@ -348,7 +348,7 @@
|
|||||||
'previous_unique_id': None,
|
'previous_unique_id': None,
|
||||||
'supported_features': 0,
|
'supported_features': 0,
|
||||||
'translation_key': 'side',
|
'translation_key': 'side',
|
||||||
'unique_id': '01J0BC4QM2YBRP6H5G933CETT7_side',
|
'unique_id': 'bf1c62fe-4941-4332-9886-e54e88dbdba0_side',
|
||||||
'unit_of_measurement': None,
|
'unit_of_measurement': None,
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
'identifiers': set({
|
'identifiers': set({
|
||||||
tuple(
|
tuple(
|
||||||
'mealie',
|
'mealie',
|
||||||
'01J0BC4QM2YBRP6H5G933CETT7',
|
'bf1c62fe-4941-4332-9886-e54e88dbdba0',
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
'is_new': False,
|
'is_new': False,
|
||||||
|
@ -37,6 +37,7 @@ async def test_full_flow(
|
|||||||
CONF_HOST: "demo.mealie.io",
|
CONF_HOST: "demo.mealie.io",
|
||||||
CONF_API_TOKEN: "token",
|
CONF_API_TOKEN: "token",
|
||||||
}
|
}
|
||||||
|
assert result["result"].unique_id == "bf1c62fe-4941-4332-9886-e54e88dbdba0"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@ -55,7 +56,7 @@ async def test_flow_errors(
|
|||||||
error: str,
|
error: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test flow errors."""
|
"""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(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
@ -72,7 +73,7 @@ async def test_flow_errors(
|
|||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["errors"] == {"base": error}
|
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 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
|
@ -26,7 +26,7 @@ async def test_device_info(
|
|||||||
"""Test device registry integration."""
|
"""Test device registry integration."""
|
||||||
await setup_integration(hass, mock_config_entry)
|
await setup_integration(hass, mock_config_entry)
|
||||||
device_entry = device_registry.async_get_device(
|
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 is not None
|
||||||
assert device_entry == snapshot
|
assert device_entry == snapshot
|
||||||
|
Loading…
x
Reference in New Issue
Block a user