mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 19:57:07 +00:00
Refactor Bring! integration to poll activity data at a slower interval (#142621)
* Refactor Bring integration to poll activity with slower interval * add test
This commit is contained in:
parent
4cecb6c851
commit
9a2f17c2b2
@ -10,7 +10,12 @@ from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
||||
from .coordinator import BringConfigEntry, BringDataUpdateCoordinator
|
||||
from .coordinator import (
|
||||
BringActivityCoordinator,
|
||||
BringConfigEntry,
|
||||
BringCoordinators,
|
||||
BringDataUpdateCoordinator,
|
||||
)
|
||||
|
||||
PLATFORMS: list[Platform] = [Platform.EVENT, Platform.SENSOR, Platform.TODO]
|
||||
|
||||
@ -26,7 +31,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: BringConfigEntry) -> boo
|
||||
coordinator = BringDataUpdateCoordinator(hass, entry, bring)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
entry.runtime_data = coordinator
|
||||
activity_coordinator = BringActivityCoordinator(hass, entry, coordinator)
|
||||
await activity_coordinator.async_config_entry_first_refresh()
|
||||
|
||||
entry.runtime_data = BringCoordinators(coordinator, activity_coordinator)
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
|
@ -30,7 +30,15 @@ from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
type BringConfigEntry = ConfigEntry[BringDataUpdateCoordinator]
|
||||
type BringConfigEntry = ConfigEntry[BringCoordinators]
|
||||
|
||||
|
||||
@dataclass
|
||||
class BringCoordinators:
|
||||
"""Data class holding coordinators."""
|
||||
|
||||
data: BringDataUpdateCoordinator
|
||||
activity: BringActivityCoordinator
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@ -39,17 +47,28 @@ class BringData(DataClassORJSONMixin):
|
||||
|
||||
lst: BringList
|
||||
content: BringItemsResponse
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BringActivityData(DataClassORJSONMixin):
|
||||
"""Coordinator data class."""
|
||||
|
||||
activity: BringActivityResponse
|
||||
users: BringUsersResponse
|
||||
|
||||
|
||||
class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]):
|
||||
"""A Bring Data Update Coordinator."""
|
||||
class BringBaseCoordinator[_DataT](DataUpdateCoordinator[_DataT]):
|
||||
"""Bring base coordinator."""
|
||||
|
||||
config_entry: BringConfigEntry
|
||||
user_settings: BringUserSettingsResponse
|
||||
lists: list[BringList]
|
||||
|
||||
|
||||
class BringDataUpdateCoordinator(BringBaseCoordinator[dict[str, BringData]]):
|
||||
"""A Bring Data Update Coordinator."""
|
||||
|
||||
user_settings: BringUserSettingsResponse
|
||||
|
||||
def __init__(
|
||||
self, hass: HomeAssistant, config_entry: BringConfigEntry, bring: Bring
|
||||
) -> None:
|
||||
@ -90,16 +109,19 @@ class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]):
|
||||
current_lists := {lst.listUuid for lst in self.lists}
|
||||
):
|
||||
self._purge_deleted_lists()
|
||||
new_lists = current_lists - self.previous_lists
|
||||
self.previous_lists = current_lists
|
||||
|
||||
list_dict: dict[str, BringData] = {}
|
||||
for lst in self.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
|
||||
and lst.listUuid not in new_lists
|
||||
):
|
||||
continue
|
||||
try:
|
||||
items = await self.bring.get_list(lst.listUuid)
|
||||
activity = await self.bring.get_activity(lst.listUuid)
|
||||
users = await self.bring.get_list_users(lst.listUuid)
|
||||
except BringRequestException as e:
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
@ -111,7 +133,7 @@ class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]):
|
||||
translation_key="setup_parse_exception",
|
||||
) from e
|
||||
else:
|
||||
list_dict[lst.listUuid] = BringData(lst, items, activity, users)
|
||||
list_dict[lst.listUuid] = BringData(lst, items)
|
||||
|
||||
return list_dict
|
||||
|
||||
@ -156,3 +178,60 @@ class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]):
|
||||
device_reg.async_update_device(
|
||||
device.id, remove_config_entry_id=self.config_entry.entry_id
|
||||
)
|
||||
|
||||
|
||||
class BringActivityCoordinator(BringBaseCoordinator[dict[str, BringActivityData]]):
|
||||
"""A Bring Activity Data Update Coordinator."""
|
||||
|
||||
user_settings: BringUserSettingsResponse
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
config_entry: BringConfigEntry,
|
||||
coordinator: BringDataUpdateCoordinator,
|
||||
) -> None:
|
||||
"""Initialize the Bring Activity data coordinator."""
|
||||
super().__init__(
|
||||
hass,
|
||||
_LOGGER,
|
||||
config_entry=config_entry,
|
||||
name=DOMAIN,
|
||||
update_interval=timedelta(minutes=10),
|
||||
)
|
||||
|
||||
self.coordinator = coordinator
|
||||
self.lists = coordinator.lists
|
||||
|
||||
async def _async_update_data(self) -> dict[str, BringActivityData]:
|
||||
"""Fetch activity data from bring."""
|
||||
|
||||
list_dict: dict[str, BringActivityData] = {}
|
||||
for lst in self.lists:
|
||||
if (
|
||||
ctx := set(self.coordinator.async_contexts())
|
||||
) and lst.listUuid not in ctx:
|
||||
continue
|
||||
try:
|
||||
activity = await self.coordinator.bring.get_activity(lst.listUuid)
|
||||
users = await self.coordinator.bring.get_list_users(lst.listUuid)
|
||||
except BringAuthException as e:
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="setup_authentication_exception",
|
||||
translation_placeholders={CONF_EMAIL: self.coordinator.bring.mail},
|
||||
) from e
|
||||
except BringRequestException as e:
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="setup_request_exception",
|
||||
) from e
|
||||
except BringParseException as e:
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="setup_parse_exception",
|
||||
) from e
|
||||
else:
|
||||
list_dict[lst.listUuid] = BringActivityData(activity, users)
|
||||
|
||||
return list_dict
|
||||
|
@ -20,9 +20,12 @@ async def async_get_config_entry_diagnostics(
|
||||
|
||||
return {
|
||||
"data": {
|
||||
k: async_redact_data(v.to_dict(), TO_REDACT)
|
||||
for k, v in config_entry.runtime_data.data.items()
|
||||
k: v.to_dict() for k, v in config_entry.runtime_data.data.data.items()
|
||||
},
|
||||
"lists": [lst.to_dict() for lst in config_entry.runtime_data.lists],
|
||||
"user_settings": config_entry.runtime_data.user_settings.to_dict(),
|
||||
"activity": {
|
||||
k: async_redact_data(v.to_dict(), TO_REDACT)
|
||||
for k, v in config_entry.runtime_data.activity.data.items()
|
||||
},
|
||||
"lists": [lst.to_dict() for lst in config_entry.runtime_data.data.lists],
|
||||
"user_settings": config_entry.runtime_data.data.user_settings.to_dict(),
|
||||
}
|
||||
|
@ -8,17 +8,17 @@ from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import BringDataUpdateCoordinator
|
||||
from .coordinator import BringBaseCoordinator
|
||||
|
||||
|
||||
class BringBaseEntity(CoordinatorEntity[BringDataUpdateCoordinator]):
|
||||
class BringBaseEntity(CoordinatorEntity[BringBaseCoordinator]):
|
||||
"""Bring base entity."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: BringDataUpdateCoordinator,
|
||||
coordinator: BringBaseCoordinator,
|
||||
bring_list: BringList,
|
||||
) -> None:
|
||||
"""Initialize the entity."""
|
||||
@ -34,5 +34,7 @@ class BringBaseEntity(CoordinatorEntity[BringDataUpdateCoordinator]):
|
||||
},
|
||||
manufacturer="Bring! Labs AG",
|
||||
model="Bring! Grocery Shopping List",
|
||||
configuration_url=f"https://web.getbring.com/app/lists/{list(self.coordinator.lists).index(bring_list)}",
|
||||
configuration_url=f"https://web.getbring.com/app/lists/{list(self.coordinator.lists).index(bring_list)}"
|
||||
if bring_list in self.coordinator.lists
|
||||
else None,
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import BringConfigEntry
|
||||
from .coordinator import BringDataUpdateCoordinator
|
||||
from .coordinator import BringActivityCoordinator
|
||||
from .entity import BringBaseEntity
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
@ -32,18 +32,18 @@ async def async_setup_entry(
|
||||
"""Add event entities."""
|
||||
nonlocal lists_added
|
||||
|
||||
if new_lists := {lst.listUuid for lst in coordinator.lists} - lists_added:
|
||||
if new_lists := {lst.listUuid for lst in coordinator.data.lists} - lists_added:
|
||||
async_add_entities(
|
||||
BringEventEntity(
|
||||
coordinator,
|
||||
coordinator.activity,
|
||||
bring_list,
|
||||
)
|
||||
for bring_list in coordinator.lists
|
||||
for bring_list in coordinator.data.lists
|
||||
if bring_list.listUuid in new_lists
|
||||
)
|
||||
lists_added |= new_lists
|
||||
|
||||
coordinator.async_add_listener(add_entities)
|
||||
coordinator.activity.async_add_listener(add_entities)
|
||||
add_entities()
|
||||
|
||||
|
||||
@ -51,10 +51,11 @@ class BringEventEntity(BringBaseEntity, EventEntity):
|
||||
"""An event entity."""
|
||||
|
||||
_attr_translation_key = "activities"
|
||||
coordinator: BringActivityCoordinator
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: BringDataUpdateCoordinator,
|
||||
coordinator: BringActivityCoordinator,
|
||||
bring_list: BringList,
|
||||
) -> None:
|
||||
"""Initialize the entity."""
|
||||
|
@ -88,7 +88,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the sensor platform."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.data
|
||||
lists_added: set[str] = set()
|
||||
|
||||
@callback
|
||||
@ -117,6 +117,7 @@ class BringSensorEntity(BringBaseEntity, SensorEntity):
|
||||
"""A sensor entity."""
|
||||
|
||||
entity_description: BringSensorEntityDescription
|
||||
coordinator: BringDataUpdateCoordinator
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -44,7 +44,7 @@ async def async_setup_entry(
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the sensor from a config entry created in the integrations UI."""
|
||||
coordinator = config_entry.runtime_data
|
||||
coordinator = config_entry.runtime_data.data
|
||||
lists_added: set[str] = set()
|
||||
|
||||
@callback
|
||||
@ -88,6 +88,7 @@ class BringTodoListEntity(BringBaseEntity, TodoListEntity):
|
||||
| TodoListEntityFeature.DELETE_TODO_ITEM
|
||||
| TodoListEntityFeature.SET_DESCRIPTION_ON_ITEM
|
||||
)
|
||||
coordinator: BringDataUpdateCoordinator
|
||||
|
||||
def __init__(
|
||||
self, coordinator: BringDataUpdateCoordinator, bring_list: BringList
|
||||
|
@ -1,7 +1,7 @@
|
||||
# serializer version: 1
|
||||
# name: test_diagnostics
|
||||
dict({
|
||||
'data': dict({
|
||||
'activity': dict({
|
||||
'b4776778-7f6c-496e-951b-92a35d3db0dd': dict({
|
||||
'activity': dict({
|
||||
'timeline': list([
|
||||
@ -79,58 +79,6 @@
|
||||
'timestamp': '2025-01-01T03:09:33.036000+00:00',
|
||||
'totalEvents': 3,
|
||||
}),
|
||||
'content': dict({
|
||||
'items': dict({
|
||||
'purchase': list([
|
||||
dict({
|
||||
'attributes': list([
|
||||
dict({
|
||||
'content': dict({
|
||||
'convenient': True,
|
||||
'discounted': True,
|
||||
'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',
|
||||
}),
|
||||
]),
|
||||
'recently': list([
|
||||
dict({
|
||||
'attributes': list([
|
||||
]),
|
||||
'itemId': 'Ananas',
|
||||
'specification': '',
|
||||
'uuid': 'fc8db30a-647e-4e6c-9d71-3b85d6a2d954',
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
'status': 'REGISTERED',
|
||||
'uuid': 'b4776778-7f6c-496e-951b-92a35d3db0dd',
|
||||
}),
|
||||
'lst': dict({
|
||||
'listUuid': 'b4776778-7f6c-496e-951b-92a35d3db0dd',
|
||||
'name': '**REDACTED**',
|
||||
'theme': 'ch.publisheria.bring.theme.home',
|
||||
}),
|
||||
'users': dict({
|
||||
'users': list([
|
||||
dict({
|
||||
@ -246,6 +194,101 @@
|
||||
'timestamp': '2025-01-01T03:09:33.036000+00:00',
|
||||
'totalEvents': 3,
|
||||
}),
|
||||
'users': dict({
|
||||
'users': list([
|
||||
dict({
|
||||
'country': 'DE',
|
||||
'email': '**REDACTED**',
|
||||
'language': 'de',
|
||||
'name': '**REDACTED**',
|
||||
'photoPath': '',
|
||||
'plusExpiry': None,
|
||||
'plusTryOut': False,
|
||||
'publicUuid': '9a21fdfc-63a4-441a-afc1-ef3030605a9d',
|
||||
'pushEnabled': True,
|
||||
}),
|
||||
dict({
|
||||
'country': 'US',
|
||||
'email': '**REDACTED**',
|
||||
'language': 'en',
|
||||
'name': '**REDACTED**',
|
||||
'photoPath': '',
|
||||
'plusExpiry': None,
|
||||
'plusTryOut': False,
|
||||
'publicUuid': '73af455f-c158-4004-a5e0-79f4f8a6d4bd',
|
||||
'pushEnabled': True,
|
||||
}),
|
||||
dict({
|
||||
'country': 'US',
|
||||
'email': None,
|
||||
'language': 'en',
|
||||
'name': None,
|
||||
'photoPath': None,
|
||||
'plusExpiry': None,
|
||||
'plusTryOut': False,
|
||||
'publicUuid': '7d5e9d08-877a-4c36-8740-a9bf74ec690a',
|
||||
'pushEnabled': True,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'data': dict({
|
||||
'b4776778-7f6c-496e-951b-92a35d3db0dd': dict({
|
||||
'content': dict({
|
||||
'items': dict({
|
||||
'purchase': list([
|
||||
dict({
|
||||
'attributes': list([
|
||||
dict({
|
||||
'content': dict({
|
||||
'convenient': True,
|
||||
'discounted': True,
|
||||
'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',
|
||||
}),
|
||||
]),
|
||||
'recently': list([
|
||||
dict({
|
||||
'attributes': list([
|
||||
]),
|
||||
'itemId': 'Ananas',
|
||||
'specification': '',
|
||||
'uuid': 'fc8db30a-647e-4e6c-9d71-3b85d6a2d954',
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
'status': 'REGISTERED',
|
||||
'uuid': 'b4776778-7f6c-496e-951b-92a35d3db0dd',
|
||||
}),
|
||||
'lst': dict({
|
||||
'listUuid': 'b4776778-7f6c-496e-951b-92a35d3db0dd',
|
||||
'name': 'Baumarkt',
|
||||
'theme': 'ch.publisheria.bring.theme.home',
|
||||
}),
|
||||
}),
|
||||
'e542eef6-dba7-4c31-a52c-29e6ab9d83a5': dict({
|
||||
'content': dict({
|
||||
'items': dict({
|
||||
'purchase': list([
|
||||
@ -295,46 +338,9 @@
|
||||
}),
|
||||
'lst': dict({
|
||||
'listUuid': 'e542eef6-dba7-4c31-a52c-29e6ab9d83a5',
|
||||
'name': '**REDACTED**',
|
||||
'name': 'Einkauf',
|
||||
'theme': 'ch.publisheria.bring.theme.home',
|
||||
}),
|
||||
'users': dict({
|
||||
'users': list([
|
||||
dict({
|
||||
'country': 'DE',
|
||||
'email': '**REDACTED**',
|
||||
'language': 'de',
|
||||
'name': '**REDACTED**',
|
||||
'photoPath': '',
|
||||
'plusExpiry': None,
|
||||
'plusTryOut': False,
|
||||
'publicUuid': '9a21fdfc-63a4-441a-afc1-ef3030605a9d',
|
||||
'pushEnabled': True,
|
||||
}),
|
||||
dict({
|
||||
'country': 'US',
|
||||
'email': '**REDACTED**',
|
||||
'language': 'en',
|
||||
'name': '**REDACTED**',
|
||||
'photoPath': '',
|
||||
'plusExpiry': None,
|
||||
'plusTryOut': False,
|
||||
'publicUuid': '73af455f-c158-4004-a5e0-79f4f8a6d4bd',
|
||||
'pushEnabled': True,
|
||||
}),
|
||||
dict({
|
||||
'country': 'US',
|
||||
'email': None,
|
||||
'language': 'en',
|
||||
'name': None,
|
||||
'photoPath': None,
|
||||
'plusExpiry': None,
|
||||
'plusTryOut': False,
|
||||
'publicUuid': '7d5e9d08-877a-4c36-8740-a9bf74ec690a',
|
||||
'pushEnabled': True,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'lists': list([
|
||||
|
@ -139,6 +139,31 @@ async def test_config_entry_not_ready_udpdate_failed(
|
||||
assert bring_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("exception", "state"),
|
||||
[
|
||||
(BringRequestException, ConfigEntryState.SETUP_RETRY),
|
||||
(BringParseException, ConfigEntryState.SETUP_RETRY),
|
||||
(BringAuthException, ConfigEntryState.SETUP_ERROR),
|
||||
],
|
||||
)
|
||||
async def test_activity_coordinator_errors(
|
||||
hass: HomeAssistant,
|
||||
bring_config_entry: MockConfigEntry,
|
||||
mock_bring_client: AsyncMock,
|
||||
exception: Exception,
|
||||
state: ConfigEntryState,
|
||||
) -> None:
|
||||
"""Test config entry not ready from update failed in _async_update_data."""
|
||||
mock_bring_client.get_activity.side_effect = exception
|
||||
|
||||
bring_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(bring_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert bring_config_entry.state is state
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("exception", "state"),
|
||||
[
|
||||
@ -263,3 +288,44 @@ async def test_create_devices(
|
||||
assert device_registry.async_get_device(
|
||||
{(DOMAIN, f"{bring_config_entry.unique_id}_{list_uuid}")}
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_bring_client")
|
||||
async def test_coordinator_update_intervals(
|
||||
hass: HomeAssistant,
|
||||
bring_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
mock_bring_client: AsyncMock,
|
||||
) -> None:
|
||||
"""Test the coordinator updates at the specified intervals."""
|
||||
await setup_integration(hass, bring_config_entry)
|
||||
|
||||
assert bring_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
# fetch 2 lists on first refresh
|
||||
assert mock_bring_client.load_lists.await_count == 2
|
||||
assert mock_bring_client.get_activity.await_count == 2
|
||||
|
||||
mock_bring_client.load_lists.reset_mock()
|
||||
mock_bring_client.get_activity.reset_mock()
|
||||
|
||||
mock_bring_client.load_lists.return_value = BringListResponse.from_json(
|
||||
load_fixture("lists2.json", DOMAIN)
|
||||
)
|
||||
freezer.tick(timedelta(seconds=90))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# main coordinator refreshes, activity does not
|
||||
assert mock_bring_client.load_lists.await_count == 1
|
||||
assert mock_bring_client.get_activity.await_count == 0
|
||||
|
||||
mock_bring_client.load_lists.reset_mock()
|
||||
mock_bring_client.get_activity.reset_mock()
|
||||
|
||||
freezer.tick(timedelta(seconds=510))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# assert activity refreshes after 10min and has up-to-date lists data
|
||||
assert mock_bring_client.get_activity.await_count == 1
|
||||
|
@ -1,12 +1,6 @@
|
||||
"""Test for utility functions of the Bring! integration."""
|
||||
|
||||
from bring_api import (
|
||||
BringActivityResponse,
|
||||
BringItemsResponse,
|
||||
BringListResponse,
|
||||
BringUserSettingsResponse,
|
||||
)
|
||||
from bring_api.types import BringUsersResponse
|
||||
from bring_api import BringItemsResponse, BringListResponse, BringUserSettingsResponse
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.bring.const import DOMAIN
|
||||
@ -47,10 +41,8 @@ def test_sum_attributes(attribute: str, expected: int) -> None:
|
||||
"""Test function sum_attributes."""
|
||||
items = BringItemsResponse.from_json(load_fixture("items.json", DOMAIN))
|
||||
lst = BringListResponse.from_json(load_fixture("lists.json", DOMAIN))
|
||||
activity = BringActivityResponse.from_json(load_fixture("activity.json", DOMAIN))
|
||||
users = BringUsersResponse.from_json(load_fixture("users.json", DOMAIN))
|
||||
result = sum_attributes(
|
||||
BringData(lst.lists[0], items, activity, users),
|
||||
BringData(lst.lists[0], items),
|
||||
attribute,
|
||||
)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user