mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Bump bring-api to 1.0.0 (#136657)
This commit is contained in:
parent
7f3e56eb58
commit
fa4b93da2b
@ -63,7 +63,8 @@ class BringConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
):
|
):
|
||||||
self._abort_if_unique_id_configured()
|
self._abort_if_unique_id_configured()
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title=self.info.get("name") or user_input[CONF_EMAIL], data=user_input
|
title=self.info.name or user_input[CONF_EMAIL],
|
||||||
|
data=user_input,
|
||||||
)
|
)
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ from bring_api import (
|
|||||||
BringRequestException,
|
BringRequestException,
|
||||||
)
|
)
|
||||||
from bring_api.types import BringItemsResponse, BringList, BringUserSettingsResponse
|
from bring_api.types import BringItemsResponse, BringList, BringUserSettingsResponse
|
||||||
|
from mashumaro.mixins.orjson import DataClassORJSONMixin
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_EMAIL
|
from homeassistant.const import CONF_EMAIL
|
||||||
@ -24,9 +26,13 @@ from .const import DOMAIN
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class BringData(BringList, BringItemsResponse):
|
@dataclass(frozen=True)
|
||||||
|
class BringData(DataClassORJSONMixin):
|
||||||
"""Coordinator data class."""
|
"""Coordinator data class."""
|
||||||
|
|
||||||
|
lst: BringList
|
||||||
|
content: BringItemsResponse
|
||||||
|
|
||||||
|
|
||||||
class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]):
|
class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]):
|
||||||
"""A Bring Data Update Coordinator."""
|
"""A Bring Data Update Coordinator."""
|
||||||
@ -67,11 +73,11 @@ class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]):
|
|||||||
return self.data
|
return self.data
|
||||||
|
|
||||||
list_dict: dict[str, BringData] = {}
|
list_dict: dict[str, BringData] = {}
|
||||||
for lst in lists_response["lists"]:
|
for lst in lists_response.lists:
|
||||||
if (ctx := set(self.async_contexts())) and lst["listUuid"] not in ctx:
|
if (ctx := set(self.async_contexts())) and lst.listUuid not in ctx:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
items = await self.bring.get_list(lst["listUuid"])
|
items = await self.bring.get_list(lst.listUuid)
|
||||||
except BringRequestException as e:
|
except BringRequestException as e:
|
||||||
raise UpdateFailed(
|
raise UpdateFailed(
|
||||||
"Unable to connect and retrieve data from bring"
|
"Unable to connect and retrieve data from bring"
|
||||||
@ -79,7 +85,7 @@ class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]):
|
|||||||
except BringParseException as e:
|
except BringParseException as e:
|
||||||
raise UpdateFailed("Unable to parse response from bring") from e
|
raise UpdateFailed("Unable to parse response from bring") from e
|
||||||
else:
|
else:
|
||||||
list_dict[lst["listUuid"]] = BringData(**lst, **items)
|
list_dict[lst.listUuid] = BringData(lst, items)
|
||||||
|
|
||||||
return list_dict
|
return list_dict
|
||||||
|
|
||||||
|
@ -2,15 +2,16 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import BringConfigEntry
|
from . import BringConfigEntry
|
||||||
from .coordinator import BringData
|
|
||||||
|
|
||||||
|
|
||||||
async def async_get_config_entry_diagnostics(
|
async def async_get_config_entry_diagnostics(
|
||||||
hass: HomeAssistant, config_entry: BringConfigEntry
|
hass: HomeAssistant, config_entry: BringConfigEntry
|
||||||
) -> dict[str, BringData]:
|
) -> dict[str, Any]:
|
||||||
"""Return diagnostics for a config entry."""
|
"""Return diagnostics for a config entry."""
|
||||||
|
|
||||||
return config_entry.runtime_data.data
|
return {k: v.to_dict() for k, v in config_entry.runtime_data.data.items()}
|
||||||
|
@ -20,13 +20,13 @@ class BringBaseEntity(CoordinatorEntity[BringDataUpdateCoordinator]):
|
|||||||
bring_list: BringData,
|
bring_list: BringData,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the entity."""
|
"""Initialize the entity."""
|
||||||
super().__init__(coordinator, bring_list["listUuid"])
|
super().__init__(coordinator, bring_list.lst.listUuid)
|
||||||
|
|
||||||
self._list_uuid = bring_list["listUuid"]
|
self._list_uuid = bring_list.lst.listUuid
|
||||||
|
|
||||||
self.device_info = DeviceInfo(
|
self.device_info = DeviceInfo(
|
||||||
entry_type=DeviceEntryType.SERVICE,
|
entry_type=DeviceEntryType.SERVICE,
|
||||||
name=bring_list["name"],
|
name=bring_list.lst.name,
|
||||||
identifiers={
|
identifiers={
|
||||||
(DOMAIN, f"{coordinator.config_entry.unique_id}_{self._list_uuid}")
|
(DOMAIN, f"{coordinator.config_entry.unique_id}_{self._list_uuid}")
|
||||||
},
|
},
|
||||||
|
@ -7,5 +7,5 @@
|
|||||||
"integration_type": "service",
|
"integration_type": "service",
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["bring_api"],
|
"loggers": ["bring_api"],
|
||||||
"requirements": ["bring-api==0.9.1"]
|
"requirements": ["bring-api==1.0.0"]
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ SENSOR_DESCRIPTIONS: tuple[BringSensorEntityDescription, ...] = (
|
|||||||
translation_key=BringSensor.LIST_LANGUAGE,
|
translation_key=BringSensor.LIST_LANGUAGE,
|
||||||
value_fn=(
|
value_fn=(
|
||||||
lambda lst, settings: x.lower()
|
lambda lst, settings: x.lower()
|
||||||
if (x := list_language(lst["listUuid"], settings))
|
if (x := list_language(lst.lst.listUuid, settings))
|
||||||
else None
|
else None
|
||||||
),
|
),
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
@ -75,7 +75,7 @@ SENSOR_DESCRIPTIONS: tuple[BringSensorEntityDescription, ...] = (
|
|||||||
BringSensorEntityDescription(
|
BringSensorEntityDescription(
|
||||||
key=BringSensor.LIST_ACCESS,
|
key=BringSensor.LIST_ACCESS,
|
||||||
translation_key=BringSensor.LIST_ACCESS,
|
translation_key=BringSensor.LIST_ACCESS,
|
||||||
value_fn=lambda lst, _: lst["status"].lower(),
|
value_fn=lambda lst, _: lst.content.status.value.lower(),
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
options=["registered", "shared", "invitation"],
|
options=["registered", "shared", "invitation"],
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from itertools import chain
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ async def async_setup_entry(
|
|||||||
SERVICE_PUSH_NOTIFICATION,
|
SERVICE_PUSH_NOTIFICATION,
|
||||||
{
|
{
|
||||||
vol.Required(ATTR_NOTIFICATION_TYPE): vol.All(
|
vol.Required(ATTR_NOTIFICATION_TYPE): vol.All(
|
||||||
vol.Upper, cv.enum(BringNotificationType)
|
vol.Upper, vol.Coerce(BringNotificationType)
|
||||||
),
|
),
|
||||||
vol.Optional(ATTR_ITEM_NAME): cv.string,
|
vol.Optional(ATTR_ITEM_NAME): cv.string,
|
||||||
},
|
},
|
||||||
@ -92,21 +93,21 @@ class BringTodoListEntity(BringBaseEntity, TodoListEntity):
|
|||||||
return [
|
return [
|
||||||
*(
|
*(
|
||||||
TodoItem(
|
TodoItem(
|
||||||
uid=item["uuid"],
|
uid=item.uuid,
|
||||||
summary=item["itemId"],
|
summary=item.itemId,
|
||||||
description=item["specification"] or "",
|
description=item.specification,
|
||||||
status=TodoItemStatus.NEEDS_ACTION,
|
status=TodoItemStatus.NEEDS_ACTION,
|
||||||
)
|
)
|
||||||
for item in self.bring_list["purchase"]
|
for item in self.bring_list.content.items.purchase
|
||||||
),
|
),
|
||||||
*(
|
*(
|
||||||
TodoItem(
|
TodoItem(
|
||||||
uid=item["uuid"],
|
uid=item.uuid,
|
||||||
summary=item["itemId"],
|
summary=item.itemId,
|
||||||
description=item["specification"] or "",
|
description=item.specification,
|
||||||
status=TodoItemStatus.COMPLETED,
|
status=TodoItemStatus.COMPLETED,
|
||||||
)
|
)
|
||||||
for item in self.bring_list["recently"]
|
for item in self.bring_list.content.items.recently
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -119,7 +120,7 @@ class BringTodoListEntity(BringBaseEntity, TodoListEntity):
|
|||||||
"""Add an item to the To-do list."""
|
"""Add an item to the To-do list."""
|
||||||
try:
|
try:
|
||||||
await self.coordinator.bring.save_item(
|
await self.coordinator.bring.save_item(
|
||||||
self.bring_list["listUuid"],
|
self._list_uuid,
|
||||||
item.summary or "",
|
item.summary or "",
|
||||||
item.description or "",
|
item.description or "",
|
||||||
str(uuid.uuid4()),
|
str(uuid.uuid4()),
|
||||||
@ -154,26 +155,25 @@ class BringTodoListEntity(BringBaseEntity, TodoListEntity):
|
|||||||
|
|
||||||
bring_list = self.bring_list
|
bring_list = self.bring_list
|
||||||
|
|
||||||
bring_purchase_item = next(
|
current_item = next(
|
||||||
(i for i in bring_list["purchase"] if i["uuid"] == item.uid),
|
(
|
||||||
|
i
|
||||||
|
for i in chain(
|
||||||
|
bring_list.content.items.purchase, bring_list.content.items.recently
|
||||||
|
)
|
||||||
|
if i.uuid == item.uid
|
||||||
|
),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
bring_recently_item = next(
|
|
||||||
(i for i in bring_list["recently"] if i["uuid"] == item.uid),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
|
|
||||||
current_item = bring_purchase_item or bring_recently_item
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
assert item.uid
|
assert item.uid
|
||||||
assert current_item
|
assert current_item
|
||||||
|
|
||||||
if item.summary == current_item["itemId"]:
|
if item.summary == current_item.itemId:
|
||||||
try:
|
try:
|
||||||
await self.coordinator.bring.batch_update_list(
|
await self.coordinator.bring.batch_update_list(
|
||||||
bring_list["listUuid"],
|
self._list_uuid,
|
||||||
BringItem(
|
BringItem(
|
||||||
itemId=item.summary or "",
|
itemId=item.summary or "",
|
||||||
spec=item.description or "",
|
spec=item.description or "",
|
||||||
@ -192,10 +192,10 @@ class BringTodoListEntity(BringBaseEntity, TodoListEntity):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
await self.coordinator.bring.batch_update_list(
|
await self.coordinator.bring.batch_update_list(
|
||||||
bring_list["listUuid"],
|
self._list_uuid,
|
||||||
[
|
[
|
||||||
BringItem(
|
BringItem(
|
||||||
itemId=current_item["itemId"],
|
itemId=current_item.itemId,
|
||||||
spec=item.description or "",
|
spec=item.description or "",
|
||||||
uuid=item.uid,
|
uuid=item.uid,
|
||||||
operation=BringItemOperation.REMOVE,
|
operation=BringItemOperation.REMOVE,
|
||||||
@ -225,7 +225,7 @@ class BringTodoListEntity(BringBaseEntity, TodoListEntity):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
await self.coordinator.bring.batch_update_list(
|
await self.coordinator.bring.batch_update_list(
|
||||||
self.bring_list["listUuid"],
|
self._list_uuid,
|
||||||
[
|
[
|
||||||
BringItem(
|
BringItem(
|
||||||
itemId=uid,
|
itemId=uid,
|
||||||
|
@ -14,27 +14,25 @@ def list_language(
|
|||||||
"""Get the lists language setting."""
|
"""Get the lists language setting."""
|
||||||
try:
|
try:
|
||||||
list_settings = next(
|
list_settings = next(
|
||||||
filter(
|
filter(lambda x: x.listUuid == list_uuid, user_settings.userlistsettings)
|
||||||
lambda x: x["listUuid"] == list_uuid,
|
|
||||||
user_settings["userlistsettings"],
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return next(
|
return (
|
||||||
filter(
|
next(
|
||||||
lambda x: x["key"] == "listArticleLanguage",
|
filter(
|
||||||
list_settings["usersettings"],
|
lambda x: x.key == "listArticleLanguage", list_settings.usersettings
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)["value"]
|
).value
|
||||||
|
|
||||||
except (StopIteration, KeyError):
|
except StopIteration:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def sum_attributes(bring_list: BringData, attribute: str) -> int:
|
def sum_attributes(bring_list: BringData, attribute: str) -> int:
|
||||||
"""Count items with given attribute set."""
|
"""Count items with given attribute set."""
|
||||||
return sum(
|
return sum(
|
||||||
item["attributes"][0]["content"][attribute]
|
getattr(item.attributes[0].content, attribute)
|
||||||
for item in bring_list["purchase"]
|
for item in bring_list.content.items.purchase
|
||||||
if len(item.get("attributes", []))
|
if item.attributes
|
||||||
)
|
)
|
||||||
|
2
requirements_all.txt
generated
2
requirements_all.txt
generated
@ -644,7 +644,7 @@ boto3==1.34.131
|
|||||||
botocore==1.34.131
|
botocore==1.34.131
|
||||||
|
|
||||||
# homeassistant.components.bring
|
# homeassistant.components.bring
|
||||||
bring-api==0.9.1
|
bring-api==1.0.0
|
||||||
|
|
||||||
# homeassistant.components.broadlink
|
# homeassistant.components.broadlink
|
||||||
broadlink==0.19.0
|
broadlink==0.19.0
|
||||||
|
2
requirements_test_all.txt
generated
2
requirements_test_all.txt
generated
@ -564,7 +564,7 @@ boschshcpy==0.2.91
|
|||||||
botocore==1.34.131
|
botocore==1.34.131
|
||||||
|
|
||||||
# homeassistant.components.bring
|
# homeassistant.components.bring
|
||||||
bring-api==0.9.1
|
bring-api==1.0.0
|
||||||
|
|
||||||
# homeassistant.components.broadlink
|
# homeassistant.components.broadlink
|
||||||
broadlink==0.19.0
|
broadlink==0.19.0
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
"""Common fixtures for the Bring! tests."""
|
"""Common fixtures for the Bring! tests."""
|
||||||
|
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
from typing import cast
|
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from bring_api.types import BringAuthResponse
|
from bring_api.types import (
|
||||||
|
BringAuthResponse,
|
||||||
|
BringItemsResponse,
|
||||||
|
BringListResponse,
|
||||||
|
BringUserSettingsResponse,
|
||||||
|
)
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.bring.const import DOMAIN
|
from homeassistant.components.bring.const import DOMAIN
|
||||||
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
|
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
|
||||||
|
|
||||||
from tests.common import MockConfigEntry, load_json_object_fixture
|
from tests.common import MockConfigEntry, load_fixture
|
||||||
|
|
||||||
EMAIL = "test-email"
|
EMAIL = "test-email"
|
||||||
PASSWORD = "test-password"
|
PASSWORD = "test-password"
|
||||||
@ -44,11 +48,17 @@ def mock_bring_client() -> Generator[AsyncMock]:
|
|||||||
client = mock_client.return_value
|
client = mock_client.return_value
|
||||||
client.uuid = UUID
|
client.uuid = UUID
|
||||||
client.mail = EMAIL
|
client.mail = EMAIL
|
||||||
client.login.return_value = cast(BringAuthResponse, {"name": "Bring"})
|
client.login.return_value = BringAuthResponse.from_json(
|
||||||
client.load_lists.return_value = load_json_object_fixture("lists.json", DOMAIN)
|
load_fixture("login.json", DOMAIN)
|
||||||
client.get_list.return_value = load_json_object_fixture("items.json", DOMAIN)
|
)
|
||||||
client.get_all_user_settings.return_value = load_json_object_fixture(
|
client.load_lists.return_value = BringListResponse.from_json(
|
||||||
"usersettings.json", DOMAIN
|
load_fixture("lists.json", DOMAIN)
|
||||||
|
)
|
||||||
|
client.get_list.return_value = BringItemsResponse.from_json(
|
||||||
|
load_fixture("items.json", DOMAIN)
|
||||||
|
)
|
||||||
|
client.get_all_user_settings.return_value = BringUserSettingsResponse.from_json(
|
||||||
|
load_fixture("usersettings.json", DOMAIN)
|
||||||
)
|
)
|
||||||
yield client
|
yield client
|
||||||
|
|
||||||
|
@ -1,44 +1,46 @@
|
|||||||
{
|
{
|
||||||
"uuid": "77a151f8-77c4-47a3-8295-c750a0e69d4f",
|
"uuid": "77a151f8-77c4-47a3-8295-c750a0e69d4f",
|
||||||
"status": "REGISTERED",
|
"status": "REGISTERED",
|
||||||
"purchase": [
|
"items": {
|
||||||
{
|
"purchase": [
|
||||||
"uuid": "b5d0790b-5f32-4d5c-91da-e29066f167de",
|
{
|
||||||
"itemId": "Paprika",
|
"uuid": "b5d0790b-5f32-4d5c-91da-e29066f167de",
|
||||||
"specification": "Rot",
|
"itemId": "Paprika",
|
||||||
"attributes": [
|
"specification": "Rot",
|
||||||
{
|
"attributes": [
|
||||||
"type": "PURCHASE_CONDITIONS",
|
{
|
||||||
"content": {
|
"type": "PURCHASE_CONDITIONS",
|
||||||
"urgent": true,
|
"content": {
|
||||||
"convenient": true,
|
"urgent": true,
|
||||||
"discounted": true
|
"convenient": true,
|
||||||
|
"discounted": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
]
|
},
|
||||||
},
|
{
|
||||||
{
|
"uuid": "72d370ab-d8ca-4e41-b956-91df94795b4e",
|
||||||
"uuid": "72d370ab-d8ca-4e41-b956-91df94795b4e",
|
"itemId": "Pouletbrüstli",
|
||||||
"itemId": "Pouletbrüstli",
|
"specification": "Bio",
|
||||||
"specification": "Bio",
|
"attributes": [
|
||||||
"attributes": [
|
{
|
||||||
{
|
"type": "PURCHASE_CONDITIONS",
|
||||||
"type": "PURCHASE_CONDITIONS",
|
"content": {
|
||||||
"content": {
|
"urgent": true,
|
||||||
"urgent": true,
|
"convenient": true,
|
||||||
"convenient": true,
|
"discounted": true
|
||||||
"discounted": true
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
]
|
}
|
||||||
}
|
],
|
||||||
],
|
"recently": [
|
||||||
"recently": [
|
{
|
||||||
{
|
"uuid": "fc8db30a-647e-4e6c-9d71-3b85d6a2d954",
|
||||||
"uuid": "fc8db30a-647e-4e6c-9d71-3b85d6a2d954",
|
"itemId": "Ananas",
|
||||||
"itemId": "Ananas",
|
"specification": "",
|
||||||
"specification": "",
|
"attributes": []
|
||||||
"attributes": []
|
}
|
||||||
}
|
]
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,44 +1,46 @@
|
|||||||
{
|
{
|
||||||
"uuid": "77a151f8-77c4-47a3-8295-c750a0e69d4f",
|
"uuid": "77a151f8-77c4-47a3-8295-c750a0e69d4f",
|
||||||
"status": "INVITATION",
|
"status": "INVITATION",
|
||||||
"purchase": [
|
"items": {
|
||||||
{
|
"purchase": [
|
||||||
"uuid": "b5d0790b-5f32-4d5c-91da-e29066f167de",
|
{
|
||||||
"itemId": "Paprika",
|
"uuid": "b5d0790b-5f32-4d5c-91da-e29066f167de",
|
||||||
"specification": "Rot",
|
"itemId": "Paprika",
|
||||||
"attributes": [
|
"specification": "Rot",
|
||||||
{
|
"attributes": [
|
||||||
"type": "PURCHASE_CONDITIONS",
|
{
|
||||||
"content": {
|
"type": "PURCHASE_CONDITIONS",
|
||||||
"urgent": true,
|
"content": {
|
||||||
"convenient": true,
|
"urgent": true,
|
||||||
"discounted": true
|
"convenient": true,
|
||||||
|
"discounted": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
]
|
},
|
||||||
},
|
{
|
||||||
{
|
"uuid": "72d370ab-d8ca-4e41-b956-91df94795b4e",
|
||||||
"uuid": "72d370ab-d8ca-4e41-b956-91df94795b4e",
|
"itemId": "Pouletbrüstli",
|
||||||
"itemId": "Pouletbrüstli",
|
"specification": "Bio",
|
||||||
"specification": "Bio",
|
"attributes": [
|
||||||
"attributes": [
|
{
|
||||||
{
|
"type": "PURCHASE_CONDITIONS",
|
||||||
"type": "PURCHASE_CONDITIONS",
|
"content": {
|
||||||
"content": {
|
"urgent": true,
|
||||||
"urgent": true,
|
"convenient": true,
|
||||||
"convenient": true,
|
"discounted": true
|
||||||
"discounted": true
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
]
|
}
|
||||||
}
|
],
|
||||||
],
|
"recently": [
|
||||||
"recently": [
|
{
|
||||||
{
|
"uuid": "fc8db30a-647e-4e6c-9d71-3b85d6a2d954",
|
||||||
"uuid": "fc8db30a-647e-4e6c-9d71-3b85d6a2d954",
|
"itemId": "Ananas",
|
||||||
"itemId": "Ananas",
|
"specification": "",
|
||||||
"specification": "",
|
"attributes": []
|
||||||
"attributes": []
|
}
|
||||||
}
|
]
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,44 +1,46 @@
|
|||||||
{
|
{
|
||||||
"uuid": "77a151f8-77c4-47a3-8295-c750a0e69d4f",
|
"uuid": "77a151f8-77c4-47a3-8295-c750a0e69d4f",
|
||||||
"status": "SHARED",
|
"status": "SHARED",
|
||||||
"purchase": [
|
"items": {
|
||||||
{
|
"purchase": [
|
||||||
"uuid": "b5d0790b-5f32-4d5c-91da-e29066f167de",
|
{
|
||||||
"itemId": "Paprika",
|
"uuid": "b5d0790b-5f32-4d5c-91da-e29066f167de",
|
||||||
"specification": "Rot",
|
"itemId": "Paprika",
|
||||||
"attributes": [
|
"specification": "Rot",
|
||||||
{
|
"attributes": [
|
||||||
"type": "PURCHASE_CONDITIONS",
|
{
|
||||||
"content": {
|
"type": "PURCHASE_CONDITIONS",
|
||||||
"urgent": true,
|
"content": {
|
||||||
"convenient": true,
|
"urgent": true,
|
||||||
"discounted": true
|
"convenient": true,
|
||||||
|
"discounted": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
]
|
},
|
||||||
},
|
{
|
||||||
{
|
"uuid": "72d370ab-d8ca-4e41-b956-91df94795b4e",
|
||||||
"uuid": "72d370ab-d8ca-4e41-b956-91df94795b4e",
|
"itemId": "Pouletbrüstli",
|
||||||
"itemId": "Pouletbrüstli",
|
"specification": "Bio",
|
||||||
"specification": "Bio",
|
"attributes": [
|
||||||
"attributes": [
|
{
|
||||||
{
|
"type": "PURCHASE_CONDITIONS",
|
||||||
"type": "PURCHASE_CONDITIONS",
|
"content": {
|
||||||
"content": {
|
"urgent": true,
|
||||||
"urgent": true,
|
"convenient": true,
|
||||||
"convenient": true,
|
"discounted": true
|
||||||
"discounted": true
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
]
|
}
|
||||||
}
|
],
|
||||||
],
|
"recently": [
|
||||||
"recently": [
|
{
|
||||||
{
|
"uuid": "fc8db30a-647e-4e6c-9d71-3b85d6a2d954",
|
||||||
"uuid": "fc8db30a-647e-4e6c-9d71-3b85d6a2d954",
|
"itemId": "Ananas",
|
||||||
"itemId": "Ananas",
|
"specification": "",
|
||||||
"specification": "",
|
"attributes": []
|
||||||
"attributes": []
|
}
|
||||||
}
|
]
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
|
12
tests/components/bring/fixtures/login.json
Normal file
12
tests/components/bring/fixtures/login.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"uuid": "4d717571-174a-4bc1-ab24-929c7227ca43",
|
||||||
|
"publicUuid": "9a21fdfc-63a4-441a-afc1-ef3030605a9d",
|
||||||
|
"email": "test-email",
|
||||||
|
"name": "Bring",
|
||||||
|
"photoPath": "",
|
||||||
|
"bringListUUID": "e542eef6-dba7-4c31-a52c-29e6ab9d83a5",
|
||||||
|
"access_token": "ACCESS_TOKEN",
|
||||||
|
"refresh_token": "REFRESH_TOKEN",
|
||||||
|
"token_type": "Bearer",
|
||||||
|
"expires_in": 604799
|
||||||
|
}
|
@ -2,100 +2,112 @@
|
|||||||
# name: test_diagnostics
|
# name: test_diagnostics
|
||||||
dict({
|
dict({
|
||||||
'b4776778-7f6c-496e-951b-92a35d3db0dd': dict({
|
'b4776778-7f6c-496e-951b-92a35d3db0dd': dict({
|
||||||
'listUuid': 'b4776778-7f6c-496e-951b-92a35d3db0dd',
|
'content': dict({
|
||||||
'name': 'Baumarkt',
|
'items': dict({
|
||||||
'purchase': list([
|
'purchase': list([
|
||||||
dict({
|
|
||||||
'attributes': list([
|
|
||||||
dict({
|
dict({
|
||||||
'content': dict({
|
'attributes': list([
|
||||||
'convenient': True,
|
dict({
|
||||||
'discounted': True,
|
'content': dict({
|
||||||
'urgent': True,
|
'convenient': True,
|
||||||
}),
|
'discounted': True,
|
||||||
'type': 'PURCHASE_CONDITIONS',
|
'urgent': True,
|
||||||
|
}),
|
||||||
|
'type': 'PURCHASE_CONDITIONS',
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
'itemId': 'Paprika',
|
||||||
|
'specification': 'Rot',
|
||||||
|
'uuid': 'b5d0790b-5f32-4d5c-91da-e29066f167de',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'attributes': list([
|
||||||
|
dict({
|
||||||
|
'content': dict({
|
||||||
|
'convenient': True,
|
||||||
|
'discounted': True,
|
||||||
|
'urgent': True,
|
||||||
|
}),
|
||||||
|
'type': 'PURCHASE_CONDITIONS',
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
'itemId': 'Pouletbrüstli',
|
||||||
|
'specification': 'Bio',
|
||||||
|
'uuid': '72d370ab-d8ca-4e41-b956-91df94795b4e',
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
'itemId': 'Paprika',
|
'recently': list([
|
||||||
'specification': 'Rot',
|
|
||||||
'uuid': 'b5d0790b-5f32-4d5c-91da-e29066f167de',
|
|
||||||
}),
|
|
||||||
dict({
|
|
||||||
'attributes': list([
|
|
||||||
dict({
|
dict({
|
||||||
'content': dict({
|
'attributes': list([
|
||||||
'convenient': True,
|
]),
|
||||||
'discounted': True,
|
'itemId': 'Ananas',
|
||||||
'urgent': True,
|
'specification': '',
|
||||||
}),
|
'uuid': 'fc8db30a-647e-4e6c-9d71-3b85d6a2d954',
|
||||||
'type': 'PURCHASE_CONDITIONS',
|
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
'itemId': 'Pouletbrüstli',
|
|
||||||
'specification': 'Bio',
|
|
||||||
'uuid': '72d370ab-d8ca-4e41-b956-91df94795b4e',
|
|
||||||
}),
|
}),
|
||||||
]),
|
'status': 'REGISTERED',
|
||||||
'recently': list([
|
'uuid': '77a151f8-77c4-47a3-8295-c750a0e69d4f',
|
||||||
dict({
|
}),
|
||||||
'attributes': list([
|
'lst': dict({
|
||||||
]),
|
'listUuid': 'b4776778-7f6c-496e-951b-92a35d3db0dd',
|
||||||
'itemId': 'Ananas',
|
'name': 'Baumarkt',
|
||||||
'specification': '',
|
'theme': 'ch.publisheria.bring.theme.home',
|
||||||
'uuid': 'fc8db30a-647e-4e6c-9d71-3b85d6a2d954',
|
}),
|
||||||
}),
|
|
||||||
]),
|
|
||||||
'status': 'REGISTERED',
|
|
||||||
'theme': 'ch.publisheria.bring.theme.home',
|
|
||||||
'uuid': '77a151f8-77c4-47a3-8295-c750a0e69d4f',
|
|
||||||
}),
|
}),
|
||||||
'e542eef6-dba7-4c31-a52c-29e6ab9d83a5': dict({
|
'e542eef6-dba7-4c31-a52c-29e6ab9d83a5': dict({
|
||||||
'listUuid': 'e542eef6-dba7-4c31-a52c-29e6ab9d83a5',
|
'content': dict({
|
||||||
'name': 'Einkauf',
|
'items': dict({
|
||||||
'purchase': list([
|
'purchase': list([
|
||||||
dict({
|
|
||||||
'attributes': list([
|
|
||||||
dict({
|
dict({
|
||||||
'content': dict({
|
'attributes': list([
|
||||||
'convenient': True,
|
dict({
|
||||||
'discounted': True,
|
'content': dict({
|
||||||
'urgent': True,
|
'convenient': True,
|
||||||
}),
|
'discounted': True,
|
||||||
'type': 'PURCHASE_CONDITIONS',
|
'urgent': True,
|
||||||
|
}),
|
||||||
|
'type': 'PURCHASE_CONDITIONS',
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
'itemId': 'Paprika',
|
||||||
|
'specification': 'Rot',
|
||||||
|
'uuid': 'b5d0790b-5f32-4d5c-91da-e29066f167de',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'attributes': list([
|
||||||
|
dict({
|
||||||
|
'content': dict({
|
||||||
|
'convenient': True,
|
||||||
|
'discounted': True,
|
||||||
|
'urgent': True,
|
||||||
|
}),
|
||||||
|
'type': 'PURCHASE_CONDITIONS',
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
'itemId': 'Pouletbrüstli',
|
||||||
|
'specification': 'Bio',
|
||||||
|
'uuid': '72d370ab-d8ca-4e41-b956-91df94795b4e',
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
'itemId': 'Paprika',
|
'recently': list([
|
||||||
'specification': 'Rot',
|
|
||||||
'uuid': 'b5d0790b-5f32-4d5c-91da-e29066f167de',
|
|
||||||
}),
|
|
||||||
dict({
|
|
||||||
'attributes': list([
|
|
||||||
dict({
|
dict({
|
||||||
'content': dict({
|
'attributes': list([
|
||||||
'convenient': True,
|
]),
|
||||||
'discounted': True,
|
'itemId': 'Ananas',
|
||||||
'urgent': True,
|
'specification': '',
|
||||||
}),
|
'uuid': 'fc8db30a-647e-4e6c-9d71-3b85d6a2d954',
|
||||||
'type': 'PURCHASE_CONDITIONS',
|
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
'itemId': 'Pouletbrüstli',
|
|
||||||
'specification': 'Bio',
|
|
||||||
'uuid': '72d370ab-d8ca-4e41-b956-91df94795b4e',
|
|
||||||
}),
|
}),
|
||||||
]),
|
'status': 'REGISTERED',
|
||||||
'recently': list([
|
'uuid': '77a151f8-77c4-47a3-8295-c750a0e69d4f',
|
||||||
dict({
|
}),
|
||||||
'attributes': list([
|
'lst': dict({
|
||||||
]),
|
'listUuid': 'e542eef6-dba7-4c31-a52c-29e6ab9d83a5',
|
||||||
'itemId': 'Ananas',
|
'name': 'Einkauf',
|
||||||
'specification': '',
|
'theme': 'ch.publisheria.bring.theme.home',
|
||||||
'uuid': 'fc8db30a-647e-4e6c-9d71-3b85d6a2d954',
|
}),
|
||||||
}),
|
|
||||||
]),
|
|
||||||
'status': 'REGISTERED',
|
|
||||||
'theme': 'ch.publisheria.bring.theme.home',
|
|
||||||
'uuid': '77a151f8-77c4-47a3-8295-c750a0e69d4f',
|
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
|
from bring_api import BringItemsResponse
|
||||||
import pytest
|
import pytest
|
||||||
from syrupy.assertion import SnapshotAssertion
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ from homeassistant.const import Platform
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
from tests.common import MockConfigEntry, load_json_object_fixture, snapshot_platform
|
from tests.common import MockConfigEntry, load_fixture, snapshot_platform
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
@ -62,10 +63,9 @@ async def test_list_access_states(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Snapshot test states of list access sensor."""
|
"""Snapshot test states of list access sensor."""
|
||||||
|
|
||||||
mock_bring_client.get_list.return_value = load_json_object_fixture(
|
mock_bring_client.get_list.return_value = BringItemsResponse.from_json(
|
||||||
f"{fixture}.json", DOMAIN
|
load_fixture(f"{fixture}.json", DOMAIN)
|
||||||
)
|
)
|
||||||
|
|
||||||
bring_config_entry.add_to_hass(hass)
|
bring_config_entry.add_to_hass(hass)
|
||||||
await hass.config_entries.async_setup(bring_config_entry.entry_id)
|
await hass.config_entries.async_setup(bring_config_entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
"""Test for utility functions of the Bring! integration."""
|
"""Test for utility functions of the Bring! integration."""
|
||||||
|
|
||||||
from typing import cast
|
from bring_api import BringItemsResponse, BringListResponse, BringUserSettingsResponse
|
||||||
|
|
||||||
from bring_api import BringUserSettingsResponse
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.bring.const import DOMAIN
|
from homeassistant.components.bring.const import DOMAIN
|
||||||
from homeassistant.components.bring.coordinator import BringData
|
from homeassistant.components.bring.coordinator import BringData
|
||||||
from homeassistant.components.bring.util import list_language, sum_attributes
|
from homeassistant.components.bring.util import list_language, sum_attributes
|
||||||
|
|
||||||
from tests.common import load_json_object_fixture
|
from tests.common import load_fixture
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@ -17,7 +15,7 @@ from tests.common import load_json_object_fixture
|
|||||||
[
|
[
|
||||||
("e542eef6-dba7-4c31-a52c-29e6ab9d83a5", "de-DE"),
|
("e542eef6-dba7-4c31-a52c-29e6ab9d83a5", "de-DE"),
|
||||||
("b4776778-7f6c-496e-951b-92a35d3db0dd", "en-US"),
|
("b4776778-7f6c-496e-951b-92a35d3db0dd", "en-US"),
|
||||||
("00000000-0000-0000-0000-00000000", None),
|
("00000000-0000-0000-0000-000000000000", None),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_list_language(list_uuid: str, expected: str | None) -> None:
|
def test_list_language(list_uuid: str, expected: str | None) -> None:
|
||||||
@ -25,10 +23,7 @@ def test_list_language(list_uuid: str, expected: str | None) -> None:
|
|||||||
|
|
||||||
result = list_language(
|
result = list_language(
|
||||||
list_uuid,
|
list_uuid,
|
||||||
cast(
|
BringUserSettingsResponse.from_json(load_fixture("usersettings.json", DOMAIN)),
|
||||||
BringUserSettingsResponse,
|
|
||||||
load_json_object_fixture("usersettings.json", DOMAIN),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result == expected
|
assert result == expected
|
||||||
@ -44,12 +39,11 @@ def test_list_language(list_uuid: str, expected: str | None) -> None:
|
|||||||
)
|
)
|
||||||
def test_sum_attributes(attribute: str, expected: int) -> None:
|
def test_sum_attributes(attribute: str, expected: int) -> None:
|
||||||
"""Test function sum_attributes."""
|
"""Test function sum_attributes."""
|
||||||
|
items = BringItemsResponse.from_json(load_fixture("items.json", DOMAIN))
|
||||||
|
lst = BringListResponse.from_json(load_fixture("lists.json", DOMAIN))
|
||||||
|
|
||||||
result = sum_attributes(
|
result = sum_attributes(
|
||||||
cast(
|
BringData(lst.lists[0], items),
|
||||||
BringData,
|
|
||||||
load_json_object_fixture("items.json", DOMAIN),
|
|
||||||
),
|
|
||||||
attribute,
|
attribute,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user