Skip to content

Commit

Permalink
Add method get_lists_users
Browse files Browse the repository at this point in the history
  • Loading branch information
tr4nt0r committed Jan 21, 2025
1 parent c3239f5 commit 49dc78d
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 0 deletions.
58 changes: 58 additions & 0 deletions bring_api/bring.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
BringNotificationType,
BringSyncCurrentUserResponse,
BringUserSettingsResponse,
BringUsersResponse,
UserLocale,
)

Expand Down Expand Up @@ -1513,3 +1514,60 @@ async def get_activity(self, list_uuid: str) -> BringActivityResponse:
raise BringRequestException(
"Loading list activity failed due to request exception."
) from e

async def get_list_users(self, list_uuid: str) -> BringUsersResponse:
"""Retrieve members of a shared list."""

try:
url = self.url / "v2/bringlists" / list_uuid / "users"
async with self._session.get(url, headers=self.headers) as r:
_LOGGER.debug(
"Response from %s [%s]: %s", url, r.status, await r.text()
)

if r.status == HTTPStatus.UNAUTHORIZED:
try:
errmsg = BringErrorResponse.from_json(await r.text())
except (JSONDecodeError, aiohttp.ClientError):
_LOGGER.debug(
"Exception: Cannot parse request response:", exc_info=True
)
else:
_LOGGER.debug(
"Exception: Cannot get list users: %s", errmsg.message
)
raise BringAuthException(
"Loading list users failed due to authorization failure, "
"the authorization token is invalid or expired."
)

r.raise_for_status()

try:
return BringUsersResponse.from_json(await r.text())
except MissingField as e:
raise BringMissingFieldException(e) from e
except (JSONDecodeError, KeyError) as e:
_LOGGER.debug(
"Exception: Cannot get users for list %s:",
list_uuid,
exc_info=True,
)
raise BringParseException(
"Loading list users failed during parsing of request response."
) from e

except TimeoutError as e:
_LOGGER.debug(
"Exception: Cannot get users for list %s:", list_uuid, exc_info=True
)
raise BringRequestException(
"Loading list users failed due to connection timeout."
) from e
except aiohttp.ClientError as e:
_LOGGER.debug(
"Exception: Cannot get users for list %s:", list_uuid, exc_info=True
)
raise BringRequestException(
"Loading list users failed due to request exception."
) from e
21 changes: 21 additions & 0 deletions bring_api/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,24 @@ class BringErrorResponse(DataClassORJSONMixin):
error: str
error_description: str
errorcode: int


@dataclass(kw_only=True)
class BringUser:
"""A Bring user."""

publicUuid: str
pushEnabled: bool
plusTryOut: bool
country: str
language: str
name: str = ""
email: str = ""
photoPath: str = ""


@dataclass(kw_only=True)
class BringUsersResponse(DataClassORJSONMixin):
"""List users."""

users: list[BringUser] = field(default_factory=list)
3 changes: 3 additions & 0 deletions tests/__snapshots__/test_bring.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
# name: TestGetList.test_get_list
BringItemsResponse(uuid='00000000-0000-0000-0000-000000000000', status='SHARED', items=Items(purchase=[BringPurchase(uuid='43bdd5a2-740a-4230-8b27-d0bbde886da7', itemId='Paprika', specification='grün', attributes=[]), BringPurchase(uuid='2de9d1c0-c211-4129-b6c5-c1260c3fc735', itemId='Zucchetti', specification='gelb', attributes=[])], recently=[BringPurchase(uuid='5681ed79-c8e4-4c8b-95ec-112999d016c0', itemId='Paprika', specification='rot', attributes=[]), BringPurchase(uuid='01eea2cd-f433-4263-ad08-3d71317c4298', itemId='Pouletbrüstli', specification='', attributes=[])]))
# ---
# name: TestGetListUsers.test_get_lists_users
BringUsersResponse(users=[BringUser(publicUuid='98615d7e-0a7d-4a7e-8f73-a9cbb9f1bc32', pushEnabled=True, plusTryOut=False, country='DE', language='de', name='NAME', email='EMAIL', photoPath=''), BringUser(publicUuid='73af455f-c158-4004-a5e0-79f4f8a6d4bd', pushEnabled=True, plusTryOut=False, country='US', language='en', name='NAME', email='EMAIL', photoPath=''), BringUser(publicUuid='7d5e9d08-877a-4c36-8740-a9bf74ec690a', pushEnabled=True, plusTryOut=False, country='US', language='en', name='', email='', photoPath='')])
# ---
# name: TestGetUserAccount.test_get_user_account
BringSyncCurrentUserResponse(email='{email}', emailVerified=True, premiumConfiguration={'hasPremium': False, 'hideSponsoredProducts': False, 'hideSponsoredTemplates': False, 'hideSponsoredPosts': False, 'hideSponsoredCategories': False, 'hideOffersOnMain': False}, publicUserUuid='00000000-0000-0000-0000-000000000000', userLocale=UserLocale(language='de', country='DE'), userUuid='00000000-0000-0000-0000-000000000000', name='{user_name}', photoPath='bring/user/portrait/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx')
# ---
Expand Down
32 changes: 32 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,38 @@
"totalEvents": 2,
}

BRING_GET_LIST_USERS_RESPONSE = {
"users": [
{
"publicUuid": "98615d7e-0a7d-4a7e-8f73-a9cbb9f1bc32",
"name": "NAME",
"email": "EMAIL",
"photoPath": "",
"pushEnabled": True,
"plusTryOut": False,
"country": "DE",
"language": "de",
},
{
"publicUuid": "73af455f-c158-4004-a5e0-79f4f8a6d4bd",
"name": "NAME",
"email": "EMAIL",
"photoPath": "",
"pushEnabled": True,
"plusTryOut": False,
"country": "US",
"language": "en",
},
{
"publicUuid": "7d5e9d08-877a-4c36-8740-a9bf74ec690a",
"pushEnabled": True,
"plusTryOut": False,
"country": "US",
"language": "en",
},
]
}

BRING_ERROR_RESPONSE = {
"message": "",
"error": "",
Expand Down
84 changes: 84 additions & 0 deletions tests/test_bring.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import time

import aiohttp
from aioresponses import aioresponses
from dotenv import load_dotenv
import pytest
from syrupy.assertion import SnapshotAssertion
Expand Down Expand Up @@ -35,6 +36,7 @@
BRING_GET_ACTIVITY_RESPONSE,
BRING_GET_ALL_ITEM_DETAILS_RESPONSE,
BRING_GET_LIST_RESPONSE,
BRING_GET_LIST_USERS_RESPONSE,
BRING_LOAD_LISTS_RESPONSE,
BRING_LOGIN_RESPONSE,
BRING_TOKEN_RESPONSE,
Expand Down Expand Up @@ -1613,3 +1615,85 @@ async def test_parse_exception(self, mocked, bring, status, exception):

with pytest.raises(exception):
await bring.get_activity(UUID)


class TestGetListUsers:
"""Tests for get_list_users method."""

async def test_get_lists_users(
self,
bring: Bring,
mocked: aioresponses,
monkeypatch: pytest.MonkeyPatch,
snapshot: SnapshotAssertion,
):
"""Test get_list_users."""

mocked.get(
f"https://api.getbring.com/rest/v2/bringlists/{UUID}/users",
status=HTTPStatus.OK,
payload=BRING_GET_LIST_USERS_RESPONSE,
)
monkeypatch.setattr(bring, "uuid", UUID)

activity = await bring.get_list_users(UUID)

assert activity == snapshot

@pytest.mark.parametrize(
"exception",
[
asyncio.TimeoutError,
aiohttp.ClientError,
],
)
async def test_request_exception(
self, mocked: aioresponses, bring: Bring, exception: Exception
):
"""Test request exceptions."""

mocked.get(
f"https://api.getbring.com/rest/v2/bringlists/{UUID}/users",
exception=exception,
)

with pytest.raises(BringRequestException):
await bring.get_list_users(UUID)

async def test_auth_exception(self, mocked: aioresponses, bring: Bring):
"""Test request exceptions."""

mocked.get(
f"https://api.getbring.com/rest/v2/bringlists/{UUID}/users",
status=HTTPStatus.UNAUTHORIZED,
payload=BRING_ERROR_RESPONSE,
)

with pytest.raises(BringAuthException):
await bring.get_list_users(UUID)

@pytest.mark.parametrize(
("status", "exception"),
[
(HTTPStatus.OK, BringParseException),
(HTTPStatus.UNAUTHORIZED, BringAuthException),
],
)
async def test_parse_exception(
self,
mocked: aioresponses,
bring: Bring,
status: HTTPStatus,
exception: Exception,
):
"""Test request exceptions."""

mocked.get(
f"https://api.getbring.com/rest/v2/bringlists/{UUID}/users",
status=status,
body="not json",
content_type="application/json",
)

with pytest.raises(exception):
await bring.get_list_users(UUID)

0 comments on commit 49dc78d

Please sign in to comment.