Skip to content

Commit

Permalink
Add Parameter chat_id to ChatMemberHandler (#4290)
Browse files Browse the repository at this point in the history
  • Loading branch information
uniquetrij committed Jun 6, 2024
1 parent cf72849 commit 9e70ac8
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 11 deletions.
37 changes: 26 additions & 11 deletions telegram/ext/_handlers/chatmemberhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@

from telegram import Update
from telegram._utils.defaultvalue import DEFAULT_TRUE
from telegram._utils.types import DVType
from telegram._utils.types import SCT, DVType
from telegram.ext._handlers.basehandler import BaseHandler
from telegram.ext._utils._update_parsing import parse_chat_id
from telegram.ext._utils.types import CCT, HandlerCallback

RT = TypeVar("RT")
Expand Down Expand Up @@ -58,6 +59,9 @@ async def callback(update: Update, context: CallbackContext)
:meth:`telegram.ext.Application.process_update`. Defaults to :obj:`True`.
.. seealso:: :wiki:`Concurrency`
chat_id (:obj:`int` | Collection[:obj:`int`], optional): Filters chat member updates from
specified chat ID(s) only.
.. versionadded:: NEXT.VERSION
Attributes:
callback (:term:`coroutine function`): The callback function for this handler.
Expand All @@ -70,7 +74,10 @@ async def callback(update: Update, context: CallbackContext)
"""

__slots__ = ("chat_member_types",)
__slots__ = (
"_chat_ids",
"chat_member_types",
)
MY_CHAT_MEMBER: Final[int] = -1
""":obj:`int`: Used as a constant to handle only :attr:`telegram.Update.my_chat_member`."""
CHAT_MEMBER: Final[int] = 0
Expand All @@ -84,10 +91,12 @@ def __init__(
callback: HandlerCallback[Update, CCT, RT],
chat_member_types: int = MY_CHAT_MEMBER,
block: DVType[bool] = DEFAULT_TRUE,
chat_id: Optional[SCT[int]] = None,
):
super().__init__(callback, block=block)

self.chat_member_types: Optional[int] = chat_member_types
self._chat_ids = parse_chat_id(chat_id)

def check_update(self, update: object) -> bool:
"""Determines whether an update should be passed to this handler's :attr:`callback`.
Expand All @@ -99,12 +108,18 @@ def check_update(self, update: object) -> bool:
:obj:`bool`
"""
if isinstance(update, Update):
if not (update.my_chat_member or update.chat_member):
return False
if self.chat_member_types == self.ANY_CHAT_MEMBER:
return True
if self.chat_member_types == self.CHAT_MEMBER:
return bool(update.chat_member)
return bool(update.my_chat_member)
return False
if not isinstance(update, Update):
return False
if not (update.my_chat_member or update.chat_member):
return False
if (
self._chat_ids
and update.effective_chat
and update.effective_chat.id not in self._chat_ids
):
return False
if self.chat_member_types == self.ANY_CHAT_MEMBER:
return True
if self.chat_member_types == self.CHAT_MEMBER:
return bool(update.chat_member)
return bool(update.my_chat_member)
60 changes: 60 additions & 0 deletions tests/ext/test_chatmemberhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,66 @@ async def test_chat_member_types(
await app.process_update(chat_member)
assert self.test_flag == result_2

@pytest.mark.parametrize(
argnames=["allowed_types", "chat_id", "expected"],
argvalues=[
(ChatMemberHandler.MY_CHAT_MEMBER, None, (True, False)),
(ChatMemberHandler.CHAT_MEMBER, None, (False, True)),
(ChatMemberHandler.ANY_CHAT_MEMBER, None, (True, True)),
(ChatMemberHandler.MY_CHAT_MEMBER, 1, (True, False)),
(ChatMemberHandler.CHAT_MEMBER, 1, (False, True)),
(ChatMemberHandler.ANY_CHAT_MEMBER, 1, (True, True)),
(ChatMemberHandler.MY_CHAT_MEMBER, [1], (True, False)),
(ChatMemberHandler.CHAT_MEMBER, [1], (False, True)),
(ChatMemberHandler.ANY_CHAT_MEMBER, [1], (True, True)),
(ChatMemberHandler.MY_CHAT_MEMBER, 2, (False, False)),
(ChatMemberHandler.CHAT_MEMBER, 2, (False, False)),
(ChatMemberHandler.ANY_CHAT_MEMBER, 2, (False, False)),
(ChatMemberHandler.MY_CHAT_MEMBER, [2], (False, False)),
(ChatMemberHandler.CHAT_MEMBER, [2], (False, False)),
(ChatMemberHandler.ANY_CHAT_MEMBER, [2], (False, False)),
],
ids=[
"MY_CHAT_MEMBER",
"CHAT_MEMBER",
"ANY_CHAT_MEMBER",
"MY_CHAT_MEMBER, CHAT=1 ",
"CHAT_MEMBER, CHAT=1",
"ANY_CHAT_MEMBER, CHAT=1",
"MY_CHAT_MEMBER, CHAT=[1] ",
"CHAT_MEMBER, CHAT=[1]",
"ANY_CHAT_MEMBER, CHAT=[1]",
"MY_CHAT_MEMBER, CHAT=2 ",
"CHAT_MEMBER, CHAT=2",
"ANY_CHAT_MEMBER, CHAT=2",
"MY_CHAT_MEMBER, CHAT=[2] ",
"CHAT_MEMBER, CHAT=[2]",
"ANY_CHAT_MEMBER, CHAT=[2]",
],
)
async def test_chat_member_types_with_chat_id(
self, app, chat_member_updated, chat_member, expected, allowed_types, chat_id
):
result_1, result_2 = expected

handler = ChatMemberHandler(
self.callback, chat_member_types=allowed_types, chat_id=chat_id
)
app.add_handler(handler)

async with app:
assert handler.check_update(chat_member) == result_1
await app.process_update(chat_member)
assert self.test_flag == result_1

self.test_flag = False
chat_member.my_chat_member = None
chat_member.chat_member = chat_member_updated

assert handler.check_update(chat_member) == result_2
await app.process_update(chat_member)
assert self.test_flag == result_2

def test_other_update_types(self, false_update):
handler = ChatMemberHandler(self.callback)
assert not handler.check_update(false_update)
Expand Down

0 comments on commit 9e70ac8

Please sign in to comment.