Skip to content

Commit

Permalink
feat: add chat_deleted_by_user event
Browse files Browse the repository at this point in the history
  • Loading branch information
Kiruha01 committed Jul 2, 2024
1 parent 848971a commit b865af4
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 226 deletions.
369 changes: 147 additions & 222 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pybotx/bot/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from pybotx.models.status import StatusRecipient
from pybotx.models.system_events.added_to_chat import AddedToChatEvent
from pybotx.models.system_events.chat_created import ChatCreatedEvent
from pybotx.models.system_events.chat_deleted_by_user import ChatDeletedByUserEvent
from pybotx.models.system_events.cts_login import CTSLoginEvent
from pybotx.models.system_events.cts_logout import CTSLogoutEvent
from pybotx.models.system_events.deleted_from_chat import DeletedFromChatEvent
Expand All @@ -35,6 +36,7 @@
SystemEventHandlerFunc = Union[
HandlerFunc[AddedToChatEvent],
HandlerFunc[ChatCreatedEvent],
HandlerFunc[ChatDeletedByUserEvent],
HandlerFunc[DeletedFromChatEvent],
HandlerFunc[LeftFromChatEvent],
HandlerFunc[CTSLoginEvent],
Expand Down
11 changes: 11 additions & 0 deletions pybotx/bot/handler_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
from pybotx.models.status import BotMenu, StatusRecipient
from pybotx.models.system_events.added_to_chat import AddedToChatEvent
from pybotx.models.system_events.chat_created import ChatCreatedEvent
from pybotx.models.system_events.chat_deleted_by_user import ChatDeletedByUserEvent
from pybotx.models.system_events.cts_login import CTSLoginEvent
from pybotx.models.system_events.cts_logout import CTSLogoutEvent
from pybotx.models.system_events.deleted_from_chat import DeletedFromChatEvent
Expand Down Expand Up @@ -242,6 +243,16 @@ def chat_created(

return handler_func

def chat_deleted_by_user(
self,
handler_func: HandlerFunc[ChatDeletedByUserEvent],
) -> HandlerFunc[ChatDeletedByUserEvent]:
"""Decorate `chat_deleted_by_user` event handler."""

self._system_event(ChatDeletedByUserEvent, handler_func)

return handler_func

def added_to_chat(
self,
handler_func: HandlerFunc[AddedToChatEvent],
Expand Down
6 changes: 6 additions & 0 deletions pybotx/models/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
BotAPIAddedToChat,
)
from pybotx.models.system_events.chat_created import BotAPIChatCreated, ChatCreatedEvent
from pybotx.models.system_events.chat_deleted_by_user import (
BotAPIChatDeletedByUser,
ChatDeletedByUserEvent,
)
from pybotx.models.system_events.cts_login import BotAPICTSLogin, CTSLoginEvent
from pybotx.models.system_events.cts_logout import BotAPICTSLogout, CTSLogoutEvent
from pybotx.models.system_events.deleted_from_chat import (
Expand All @@ -34,6 +38,7 @@
BotAPISmartAppEvent,
BotAPIInternalBotNotification,
BotAPIChatCreated,
BotAPIChatDeletedByUser,
BotAPIAddedToChat,
BotAPIDeletedFromChat,
BotAPILeftFromChat,
Expand All @@ -48,6 +53,7 @@
SmartAppEvent,
InternalBotNotificationEvent,
ChatCreatedEvent,
ChatDeletedByUserEvent,
AddedToChatEvent,
DeletedFromChatEvent,
LeftFromChatEvent,
Expand Down
9 changes: 7 additions & 2 deletions pybotx/models/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class BotAPICommandTypes(StrEnum):
class BotAPISystemEventTypes(StrEnum):
ADDED_TO_CHAT = "system:added_to_chat"
CHAT_CREATED = "system:chat_created"
CHAT_DELETED_BY_USER = "system:chat_deleted_by_user"
CTS_LOGIN = "system:cts_login"
CTS_LOGOUT = "system:cts_logout"
DELETED_FROM_CHAT = "system:deleted_from_chat"
Expand Down Expand Up @@ -264,7 +265,9 @@ def convert_chat_type_from_domain(chat_type: ChatTypes) -> APIChatTypes:


@overload
def convert_chat_type_to_domain(chat_type: APIChatTypes) -> ChatTypes:
def convert_chat_type_to_domain(
chat_type: APIChatTypes,
) -> ChatTypes:
... # noqa: WPS428


Expand Down Expand Up @@ -302,7 +305,9 @@ def convert_sync_source_type_to_domain(


@overload
def convert_sync_source_type_to_domain(sync_type: str) -> UNSUPPORTED:
def convert_sync_source_type_to_domain(
sync_type: str,
) -> UNSUPPORTED:
... # noqa: WPS428


Expand Down
56 changes: 56 additions & 0 deletions pybotx/models/system_events/chat_deleted_by_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from dataclasses import dataclass
from typing import Any, Dict, Literal
from uuid import UUID

from pydantic import Field

from pybotx.models.api_base import VerifiedPayloadBaseModel
from pybotx.models.base_command import (
BaseBotAPIContext,
BotAPIBaseCommand,
BotAPIBaseSystemEventPayload,
BotCommandBase,
)
from pybotx.models.bot_account import BotAccount
from pybotx.models.enums import BotAPISystemEventTypes


@dataclass
class ChatDeletedByUserEvent(BotCommandBase):
"""Event `system:chat_deleted_by_user`.
Attributes:
chat_id: Deleted chat id.
huid: huid of the deleter.
"""

sync_id: UUID
chat_id: UUID
huid: UUID


class BotAPIChatDeletedByUserData(VerifiedPayloadBaseModel):
user_huid: UUID
group_chat_id: UUID


class BotAPIChatDeletedByUserPayload(BotAPIBaseSystemEventPayload):
body: Literal[BotAPISystemEventTypes.CHAT_DELETED_BY_USER]
data: BotAPIChatDeletedByUserData


class BotAPIChatDeletedByUser(BotAPIBaseCommand):
payload: BotAPIChatDeletedByUserPayload = Field(..., alias="command")
sender: BaseBotAPIContext = Field(..., alias="from")

def to_domain(self, raw_command: Dict[str, Any]) -> ChatDeletedByUserEvent:
return ChatDeletedByUserEvent(
sync_id=self.sync_id,
bot=BotAccount(
id=self.bot_id,
host=self.sender.host,
),
chat_id=self.payload.data.group_chat_id,
huid=self.payload.data.user_huid,
raw_command=raw_command,
)
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pybotx"
version = "0.68.1"
version = "0.69.0"
description = "A python library for interacting with eXpress BotX API"
authors = [
"Sidnev Nikolay <[email protected]>",
Expand All @@ -24,7 +24,7 @@ httpx = "^0.25.0"
httpcore = ">=1.0.0,<1.0.3"
loguru = ">=0.6.0,<0.7.0"
pydantic = ">=1.6.0,<1.11.0"
aiocsv = ">=1.2.3,<1.3.0"
aiocsv = "^1.3.2"
pyjwt = ">=2.0.0,<3.0.0"
mypy-extensions = ">=0.2.0,<0.5.0"

Expand Down
90 changes: 90 additions & 0 deletions tests/system_events/test_chat_deleted_by_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from typing import Optional
from uuid import UUID

import pytest

from pybotx import (
Bot,
BotAccount,
BotAccountWithSecret,
HandlerCollector,
lifespan_wrapper,
)
from pybotx.models.system_events.chat_deleted_by_user import ChatDeletedByUserEvent

pytestmark = [
pytest.mark.asyncio,
pytest.mark.mock_authorization,
pytest.mark.usefixtures("respx_mock"),
]


async def test__chat_deleted_by_user__succeed(
bot_account: BotAccountWithSecret,
) -> None:
# - Arrange -
payload = {
"sync_id": "a465f0f3-1354-491c-8f11-f400164295cb",
"command": {
"body": "system:chat_deleted_by_user",
"data": {
"group_chat_id": "6fa5f1e9-1453-0ad7-2d6d-b791467e382a",
"user_huid": "37b821f5-a2be-5dc1-b107-87807ce97e56",
},
"command_type": "system",
"metadata": {},
},
"async_files": [],
"attachments": [],
"entities": [],
"from": {
"user_huid": None,
"group_chat_id": "6fa5f1e9-1453-0ad7-2d6d-b791467e382a",
"ad_login": None,
"ad_domain": None,
"username": None,
"chat_type": None,
"manufacturer": None,
"device": None,
"device_software": None,
"device_meta": {},
"platform": None,
"platform_package_id": None,
"is_admin": None,
"is_creator": None,
"app_version": None,
"locale": "en",
"host": "cts.example.com",
},
"bot_id": "24348246-6791-4ac0-9d86-b948cd6a0e46",
"proto_version": 4,
"source_sync_id": None,
}

collector = HandlerCollector()
chat_deleted: Optional[ChatDeletedByUserEvent] = None

@collector.chat_deleted_by_user
async def chat_deleted_handler(event: ChatDeletedByUserEvent, bot: Bot) -> None:
nonlocal chat_deleted
chat_deleted = event
# Drop `raw_command` from asserting
chat_deleted.raw_command = None

built_bot = Bot(collectors=[collector], bot_accounts=[bot_account])

# - Act -
async with lifespan_wrapper(built_bot) as bot:
bot.async_execute_raw_bot_command(payload, verify_request=False)

# - Assert -
assert chat_deleted == ChatDeletedByUserEvent(
sync_id=UUID("a465f0f3-1354-491c-8f11-f400164295cb"),
bot=BotAccount(
id=UUID("24348246-6791-4ac0-9d86-b948cd6a0e46"),
host="cts.example.com",
),
chat_id=UUID("6fa5f1e9-1453-0ad7-2d6d-b791467e382a"),
huid=UUID("37b821f5-a2be-5dc1-b107-87807ce97e56"),
raw_command=None,
)

0 comments on commit b865af4

Please sign in to comment.