Skip to content

Commit

Permalink
feat: subscribe to unread counter in sending manifest (#486)
Browse files Browse the repository at this point in the history
* feat: subscribe to unread counter in sending manifest

* feat: ios and android fullscreen layout params for manifest
  • Loading branch information
kutuzov13 authored Sep 17, 2024
1 parent 4f73ec6 commit dc7da94
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 35 deletions.
6 changes: 6 additions & 0 deletions pybotx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@
from pybotx.client.smartapps_api.exceptions import SyncSmartAppEventHandlerNotFoundError
from pybotx.client.smartapps_api.smartapp_manifest import (
SmartappManifest,
SmartappManifestAndroidParams,
SmartappManifestIosParams,
SmartappManifestUnreadCounterParams,
SmartappManifestWebParams,
)
from pybotx.client.stickers_api.exceptions import (
Expand Down Expand Up @@ -234,6 +237,9 @@
"SmartApp",
"SmartAppEvent",
"SmartappManifest",
"SmartappManifestAndroidParams",
"SmartappManifestIosParams",
"SmartappManifestUnreadCounterParams",
"SmartappManifestWebLayoutChoices",
"SmartappManifestWebParams",
"StatusRecipient",
Expand Down
27 changes: 16 additions & 11 deletions pybotx/bot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,11 @@
from pybotx.client.smartapps_api.smartapp_manifest import (
BotXAPISmartAppManifestRequestPayload,
SmartappManifest,
SmartappManifestAndroidParams,
SmartappManifestIosParams,
SmartAppManifestMethod,
SmartappManifestUnreadCounterParams,
SmartappManifestWebParams,
)
from pybotx.client.smartapps_api.smartapp_notification import (
BotXAPISmartAppNotificationRequestPayload,
Expand Down Expand Up @@ -231,7 +235,6 @@
from pybotx.models.chats import ChatInfo, ChatListItem
from pybotx.models.commands import BotAPICommand, BotCommand
from pybotx.models.enums import ChatTypes
from pybotx.models.enums import SmartappManifestWebLayoutChoices as WebLayoutChoices
from pybotx.models.message.edit_message import EditMessage
from pybotx.models.message.markup import BubbleMarkup, KeyboardMarkup
from pybotx.models.message.message_status import MessageStatus
Expand Down Expand Up @@ -1551,17 +1554,18 @@ async def send_smartapp_manifest(
self,
*,
bot_id: UUID,
web_default_layout: WebLayoutChoices = WebLayoutChoices.minimal,
web_expanded_layout: WebLayoutChoices = WebLayoutChoices.half,
web_always_pinned: bool = False,
ios: Missing[SmartappManifestIosParams] = Undefined,
android: Missing[SmartappManifestAndroidParams] = Undefined,
web_layout: Missing[SmartappManifestWebParams] = Undefined,
unread_counter: Missing[SmartappManifestUnreadCounterParams] = Undefined,
) -> SmartappManifest:
"""Send smartapp manifest with given parameters.
:param bot_id: Bot which should perform the request.
:param web_default_layout: default smartapp layout for web clients.
:param web_expanded_layout: expanded smartapp layout for web clients.
:param web_always_pinned: True if smartapp icon should be always pinned
in the web clients sidebar.
:param ios: Smartapp layout for ios clients.
:param android: Smartapp layout for android clients.
:param web_layout: Smartapp layout for web clients.
:param unread_counter: Entities that can be subscribed to in the unread counter.
:return: Smartapp manifest with the set parameters received from BotX.
"""
Expand All @@ -1572,9 +1576,10 @@ async def send_smartapp_manifest(
self._bot_accounts_storage,
)
payload = BotXAPISmartAppManifestRequestPayload.from_domain(
web_default_layout=web_default_layout,
web_expanded_layout=web_expanded_layout,
web_always_pinned=web_always_pinned,
ios=ios,
android=android,
web_layout=web_layout,
unread_counter=unread_counter,
)
smartapp_manifest_response = await method.execute(payload)
return smartapp_manifest_response.to_domain()
Expand Down
57 changes: 44 additions & 13 deletions pybotx/client/smartapps_api/smartapp_manifest.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,68 @@
from typing import Literal
from typing import List, Literal
from uuid import UUID

from pydantic import Field

from pybotx.client.authorized_botx_method import AuthorizedBotXMethod
from pybotx.models.api_base import VerifiedPayloadBaseModel
from pybotx.missing import Missing, Undefined
from pybotx.models.api_base import UnverifiedPayloadBaseModel, VerifiedPayloadBaseModel
from pybotx.models.enums import SmartappManifestWebLayoutChoices as WebLayoutChoices


class SmartappManifestIosParams(VerifiedPayloadBaseModel):
fullscreen_layout: bool = False


class SmartappManifestAndroidParams(VerifiedPayloadBaseModel):
fullscreen_layout: bool = False


class SmartappManifestWebParams(VerifiedPayloadBaseModel):
default_layout: WebLayoutChoices = WebLayoutChoices.minimal
expanded_layout: WebLayoutChoices = WebLayoutChoices.half
always_pinned: bool = False


class SmartappManifestUnreadCounterParams(VerifiedPayloadBaseModel):
user_huid: List[UUID] = Field(default_factory=list)
group_chat_id: List[UUID] = Field(default_factory=list)
app_id: List[str] = Field(default_factory=list)


class SmartappManifest(VerifiedPayloadBaseModel):
ios: SmartappManifestIosParams
android: SmartappManifestAndroidParams
web: SmartappManifestWebParams
unread_counter_link: SmartappManifestUnreadCounterParams


class SmartappManifestPayload(UnverifiedPayloadBaseModel):
ios: Missing[SmartappManifestIosParams] = Undefined
android: Missing[SmartappManifestAndroidParams] = Undefined
web: Missing[SmartappManifestWebParams] = Undefined
unread_counter_link: Missing[SmartappManifestUnreadCounterParams] = Undefined

class BotXAPISmartAppManifestRequestPayload(VerifiedPayloadBaseModel):
manifest: SmartappManifest

class BotXAPISmartAppManifestRequestPayload(UnverifiedPayloadBaseModel):
manifest: SmartappManifestPayload

@classmethod
def from_domain(
cls,
web_default_layout: WebLayoutChoices = WebLayoutChoices.minimal,
web_expanded_layout: WebLayoutChoices = WebLayoutChoices.half,
web_always_pinned: bool = False,
ios: Missing[SmartappManifestIosParams] = Undefined,
android: Missing[SmartappManifestAndroidParams] = Undefined,
web_layout: Missing[SmartappManifestWebParams] = Undefined,
unread_counter: Missing[SmartappManifestUnreadCounterParams] = Undefined,
) -> "BotXAPISmartAppManifestRequestPayload":
if web_layout is Undefined and unread_counter is Undefined:
return cls(manifest={})

return cls(
manifest=SmartappManifest(
web=SmartappManifestWebParams(
default_layout=web_default_layout,
expanded_layout=web_expanded_layout,
always_pinned=web_always_pinned,
),
manifest=SmartappManifestPayload(
ios=ios,
android=android,
web=web_layout,
unread_counter_link=unread_counter,
),
)

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pybotx"
version = "0.71.0"
version = "0.72.0"
description = "A python library for interacting with eXpress BotX API"
authors = [
"Sidnev Nikolay <[email protected]>",
Expand Down
87 changes: 77 additions & 10 deletions tests/client/smartapps_api/test_smartapp_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
SmartappManifestWebParams,
lifespan_wrapper,
)
from pybotx.client.smartapps_api.smartapp_manifest import (
SmartappManifestAndroidParams,
SmartappManifestIosParams,
SmartappManifestUnreadCounterParams,
)

pytestmark = [
pytest.mark.asyncio,
Expand All @@ -34,23 +39,45 @@ async def test__send_smartapp_manifest__all_params_provided__succeed(
headers={"Authorization": "Bearer token", "Content-Type": "application/json"},
json={
"manifest": {
"ios": {
"fullscreen_layout": False,
},
"android": {
"fullscreen_layout": False,
},
"web": {
"always_pinned": True,
"default_layout": "full",
"expanded_layout": "full",
},
"unread_counter_link": {
"user_huid": ["e3568b81-0446-4030-9210-1725841bf8f0"],
"group_chat_id": ["adc03af8-9193-4d3b-b913-7a023cdb4029"],
"app_id": ["test_app"],
},
},
},
).mock(
return_value=httpx.Response(
HTTPStatus.ACCEPTED,
json={
"result": {
"ios": {
"fullscreen_layout": False,
},
"android": {
"fullscreen_layout": False,
},
"web": {
"always_pinned": True,
"default_layout": "full",
"expanded_layout": "full",
},
"unread_counter_link": {
"user_huid": ["e3568b81-0446-4030-9210-1725841bf8f0"],
"group_chat_id": ["adc03af8-9193-4d3b-b913-7a023cdb4029"],
"app_id": ["test_app"],
},
},
"status": "ok",
},
Expand All @@ -63,19 +90,43 @@ async def test__send_smartapp_manifest__all_params_provided__succeed(
async with lifespan_wrapper(built_bot) as bot:
smartapp_manifest = await bot.send_smartapp_manifest(
bot_id=bot_id,
web_default_layout=SmartappManifestWebLayoutChoices.full,
web_expanded_layout=SmartappManifestWebLayoutChoices.full,
web_always_pinned=True,
ios=SmartappManifestIosParams(
fullscreen_layout=False,
),
android=SmartappManifestAndroidParams(
fullscreen_layout=False,
),
web_layout=SmartappManifestWebParams(
default_layout=SmartappManifestWebLayoutChoices.full,
expanded_layout=SmartappManifestWebLayoutChoices.full,
always_pinned=True,
),
unread_counter=SmartappManifestUnreadCounterParams(
user_huid=[UUID("e3568b81-0446-4030-9210-1725841bf8f0")],
group_chat_id=[UUID("adc03af8-9193-4d3b-b913-7a023cdb4029")],
app_id=["test_app"],
),
)

# - Assert -
assert endpoint.called
assert smartapp_manifest == SmartappManifest(
ios=SmartappManifestIosParams(
fullscreen_layout=False,
),
android=SmartappManifestAndroidParams(
fullscreen_layout=False,
),
web=SmartappManifestWebParams(
default_layout=SmartappManifestWebLayoutChoices.full,
expanded_layout=SmartappManifestWebLayoutChoices.full,
always_pinned=True,
),
unread_counter_link=SmartappManifestUnreadCounterParams(
user_huid=[UUID("e3568b81-0446-4030-9210-1725841bf8f0")],
group_chat_id=[UUID("adc03af8-9193-4d3b-b913-7a023cdb4029")],
app_id=["test_app"],
),
)


Expand All @@ -90,24 +141,29 @@ async def test__send_smartapp_manifest__only_default_params_provided__succeed(
f"https://{host}/api/v1/botx/smartapps/manifest",
headers={"Authorization": "Bearer token", "Content-Type": "application/json"},
json={
"manifest": {
"web": {
"always_pinned": False,
"default_layout": "minimal",
"expanded_layout": "half",
},
},
"manifest": {},
},
).mock(
return_value=httpx.Response(
HTTPStatus.ACCEPTED,
json={
"result": {
"ios": {
"fullscreen_layout": False,
},
"android": {
"fullscreen_layout": False,
},
"web": {
"always_pinned": False,
"default_layout": "minimal",
"expanded_layout": "half",
},
"unread_counter_link": {
"app_id": [],
"group_chat_id": [],
"user_huid": [],
},
},
"status": "ok",
},
Expand All @@ -123,9 +179,20 @@ async def test__send_smartapp_manifest__only_default_params_provided__succeed(
# - Assert -
assert endpoint.called
assert smartapp_manifest == SmartappManifest(
ios=SmartappManifestIosParams(
fullscreen_layout=False,
),
android=SmartappManifestAndroidParams(
fullscreen_layout=False,
),
web=SmartappManifestWebParams(
default_layout=SmartappManifestWebLayoutChoices.minimal,
expanded_layout=SmartappManifestWebLayoutChoices.half,
always_pinned=False,
),
unread_counter_link=SmartappManifestUnreadCounterParams(
user_huid=[],
group_chat_id=[],
app_id=[],
),
)

0 comments on commit dc7da94

Please sign in to comment.