This commit is contained in:
Bibo-Joshi 2019-09-06 19:41:43 +00:00 committed by Noam Meltzer
parent d5399de99b
commit 965ad17af8
18 changed files with 344 additions and 77 deletions

View file

@ -0,0 +1,6 @@
telegram.ChatPermissions
========================
.. autoclass:: telegram.ChatPermissions
:members:
:show-inheritance:

View file

@ -13,6 +13,7 @@ telegram package
telegram.chat
telegram.chataction
telegram.chatmember
telegram.chatpermissions
telegram.chatphoto
telegram.constants
telegram.contact

View file

@ -23,6 +23,7 @@ from .user import User
from .files.chatphoto import ChatPhoto
from .chat import Chat
from .chatmember import ChatMember
from .chatpermissions import ChatPermissions
from .files.photosize import PhotoSize
from .files.audio import Audio
from .files.voice import Voice
@ -125,8 +126,8 @@ from .version import __version__ # noqa: F401
__author__ = 'devs@python-telegram-bot.org'
__all__ = [
'Audio', 'Bot', 'Chat', 'ChatMember', 'ChatAction', 'ChosenInlineResult', 'CallbackQuery',
'Contact', 'Document', 'File', 'ForceReply', 'InlineKeyboardButton',
'Audio', 'Bot', 'Chat', 'ChatMember', 'ChatPermissions', 'ChatAction', 'ChosenInlineResult',
'CallbackQuery', 'Contact', 'Document', 'File', 'ForceReply', 'InlineKeyboardButton',
'InlineKeyboardMarkup', 'InlineQuery', 'InlineQueryResult', 'InlineQueryResult',
'InlineQueryResultArticle', 'InlineQueryResultAudio', 'InlineQueryResultCachedAudio',
'InlineQueryResultCachedDocument', 'InlineQueryResultCachedGif',

View file

@ -2685,14 +2685,18 @@ class Bot(TelegramObject):
return result
@log
def restrict_chat_member(self, chat_id, user_id, until_date=None, can_send_messages=None,
can_send_media_messages=None, can_send_other_messages=None,
can_add_web_page_previews=None, timeout=None, **kwargs):
def restrict_chat_member(self, chat_id, user_id, permissions, until_date=None,
timeout=None, **kwargs):
"""
Use this method to restrict a user in a supergroup. The bot must be an administrator in
the supergroup for this to work and must have the appropriate admin rights. Pass True for
all boolean parameters to lift restrictions from a user.
Note:
Since Bot API 4.4, :attr:`restrict_chat_member` takes the new user permissions in a
single argument of type :class:`telegram.ChatPermissions`. The old way of passing
parameters will not keep working forever.
Args:
chat_id (:obj:`int` | :obj:`str`): Unique identifier for the target chat or username
of the target supergroup (in the format @supergroupusername).
@ -2701,15 +2705,7 @@ class Bot(TelegramObject):
will be lifted for the user, unix time. If user is restricted for more than 366
days or less than 30 seconds from the current time, they are considered to be
restricted forever.
can_send_messages (:obj:`bool`, optional): Pass True, if the user can send text
messages, contacts, locations and venues.
can_send_media_messages (:obj:`bool`, optional): Pass True, if the user can send
audios, documents, photos, videos, video notes and voice notes, implies
can_send_messages.
can_send_other_messages (:obj:`bool`, optional): Pass True, if the user can send
animations, games, stickers and use inline bots, implies can_send_media_messages.
can_add_web_page_previews (:obj:`bool`, optional): Pass True, if the user may add
web page previews to their messages, implies can_send_media_messages.
permissions (:class:`telegram.ChatPermissions`): New user permissions.
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
the read timeout from the server (instead of the one specified during creation of
the connection pool).
@ -2720,24 +2716,15 @@ class Bot(TelegramObject):
Raises:
:class:`telegram.TelegramError`
"""
url = '{0}/restrictChatMember'.format(self.base_url)
data = {'chat_id': chat_id, 'user_id': user_id}
data = {'chat_id': chat_id, 'user_id': user_id, 'permissions': permissions.to_dict()}
if until_date is not None:
if isinstance(until_date, datetime):
until_date = to_timestamp(until_date)
data['until_date'] = until_date
if can_send_messages is not None:
data['can_send_messages'] = can_send_messages
if can_send_media_messages is not None:
data['can_send_media_messages'] = can_send_media_messages
if can_send_other_messages is not None:
data['can_send_other_messages'] = can_send_other_messages
if can_add_web_page_previews is not None:
data['can_add_web_page_previews'] = can_add_web_page_previews
data.update(kwargs)
result = self._request.post(url, data, timeout=timeout)
@ -2815,6 +2802,38 @@ class Bot(TelegramObject):
return result
@log
def set_chat_permissions(self, chat_id, permissions, timeout=None, **kwargs):
"""
Use this method to set default chat permissions for all members. The bot must be an
administrator in the group or a supergroup for this to work and must have the
:attr:`can_restrict_members` admin rights. Returns True on success.
Args:
chat_id (:obj:`int` | :obj:`str`): Unique identifier for the target chat or username of
the target supergroup (in the format `@supergroupusername`).
permissions (:class:`telegram.ChatPermissions`): New default chat permissions.
timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as
the read timeout from the server (instead of the one specified during creation of
the connection pool).
**kwargs (:obj:`dict`): Arbitrary keyword arguments
Returns:
:obj:`bool`: Returns True on success.
Raises:
:class:`telegram.TelegramError`
"""
url = '{0}/setChatPermissions'.format(self.base_url)
data = {'chat_id': chat_id, 'permissions': permissions.to_dict()}
data.update(kwargs)
result = self._request.post(url, data, timeout=timeout)
return result
@log
def export_chat_invite_link(self, chat_id, timeout=None, **kwargs):
"""
@ -2958,8 +2977,9 @@ class Bot(TelegramObject):
@log
def set_chat_description(self, chat_id, description, timeout=None, **kwargs):
"""
Use this method to change the description of a supergroup or a channel. The bot must be an
administrator in the chat for this to work and must have the appropriate admin rights.
Use this method to change the description of a group, a supergroup or a channel. The bot
must be an administrator in the chat for this to work and must have the appropriate admin
rights.
Args:
chat_id (:obj:`int` | :obj:`str`): Unique identifier for the target chat or username
@ -3526,6 +3546,8 @@ class Bot(TelegramObject):
"""Alias for :attr:`restrict_chat_member`"""
promoteChatMember = promote_chat_member
"""Alias for :attr:`promote_chat_member`"""
setChatPermissions = set_chat_permissions
"""Alias for :attr:`set_chat_permissions`"""
exportChatInviteLink = export_chat_invite_link
"""Alias for :attr:`export_chat_invite_link`"""
setChatPhoto = set_chat_photo

View file

@ -20,6 +20,7 @@
"""This module contains an object that represents a Telegram Chat."""
from telegram import TelegramObject, ChatPhoto
from .chatpermissions import ChatPermissions
class Chat(TelegramObject):
@ -32,12 +33,13 @@ class Chat(TelegramObject):
username (:obj:`str`): Optional. Username.
first_name (:obj:`str`): Optional. First name of the other party in a private chat.
last_name (:obj:`str`): Optional. Last name of the other party in a private chat.
all_members_are_administrators (:obj:`bool`): Optional.
photo (:class:`telegram.ChatPhoto`): Optional. Chat photo.
description (:obj:`str`): Optional. Description, for supergroups and channel chats.
description (:obj:`str`): Optional. Description, for groups, supergroups and channel chats.
invite_link (:obj:`str`): Optional. Chat invite link, for supergroups and channel chats.
pinned_message (:class:`telegram.Message`): Optional. Pinned message, for supergroups.
Returned only in get_chat.
permissions (:class:`telegram.ChatPermission`): Optional. Default chat member permissions,
for groups and supergroups. Returned only in getChat.
sticker_set_name (:obj:`str`): Optional. For supergroups, name of Group sticker set.
can_set_sticker_set (:obj:`bool`): Optional. ``True``, if the bot can change group the
sticker set.
@ -54,15 +56,15 @@ class Chat(TelegramObject):
available.
first_name(:obj:`str`, optional): First name of the other party in a private chat.
last_name(:obj:`str`, optional): Last name of the other party in a private chat.
all_members_are_administrators (:obj:`bool`, optional): True if a group has `All Members
Are Admins` enabled.
photo (:class:`telegram.ChatPhoto`, optional): Chat photo. Returned only in getChat.
description (:obj:`str`, optional): Description, for supergroups and channel chats.
description (:obj:`str`, optional): Description, for groups, supergroups and channel chats.
Returned only in get_chat.
invite_link (:obj:`str`, optional): Chat invite link, for supergroups and channel chats.
Returned only in get_chat.
pinned_message (:class:`telegram.Message`, optional): Pinned message, for supergroups.
Returned only in get_chat.
permissions (:class:`telegram.ChatPermission`): Optional. Default chat member permissions,
for groups and supergroups. Returned only in getChat.
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods.
sticker_set_name (:obj:`str`, optional): For supergroups, name of Group sticker set.
Returned only in get_chat.
@ -94,6 +96,7 @@ class Chat(TelegramObject):
description=None,
invite_link=None,
pinned_message=None,
permissions=None,
sticker_set_name=None,
can_set_sticker_set=None,
**kwargs):
@ -110,6 +113,7 @@ class Chat(TelegramObject):
self.description = description
self.invite_link = invite_link
self.pinned_message = pinned_message
self.permissions = permissions
self.sticker_set_name = sticker_set_name
self.can_set_sticker_set = can_set_sticker_set
@ -132,6 +136,7 @@ class Chat(TelegramObject):
data['photo'] = ChatPhoto.de_json(data.get('photo'), bot)
from telegram import Message
data['pinned_message'] = Message.de_json(data.get('pinned_message'), bot)
data['permissions'] = ChatPermissions.de_json(data.get('permissions'), bot)
return cls(bot=bot, **data)
@ -221,6 +226,16 @@ class Chat(TelegramObject):
"""
return self.bot.unban_chat_member(self.id, *args, **kwargs)
def set_permissions(self, *args, **kwargs):
"""Shortcut for::
bot.set_chat_permissions(update.message.chat.id, *args, **kwargs)
Returns:
:obj:`bool`: If the action was sent successfully.
"""
return self.bot.set_chat_permissions(self.id, *args, **kwargs)
def send_message(self, *args, **kwargs):
"""Shortcut for::

View file

@ -32,18 +32,17 @@ class ChatMember(TelegramObject):
for this user.
can_be_edited (:obj:`bool`): Optional. If the bot is allowed to edit administrator
privileges of that user.
can_change_info (:obj:`bool`): Optional. If the administrator can change the chat title,
photo and other settings.
can_change_info (:obj:`bool`): Optional. If the user can change the chat title, photo and
other settings.
can_post_messages (:obj:`bool`): Optional. If the administrator can post in the channel.
can_edit_messages (:obj:`bool`): Optional. If the administrator can edit messages of other
users.
can_delete_messages (:obj:`bool`): Optional. If the administrator can delete messages of
other users.
can_invite_users (:obj:`bool`): Optional. If the administrator can invite new users to the
chat.
can_invite_users (:obj:`bool`): Optional. If the user can invite new users to the chat.
can_restrict_members (:obj:`bool`): Optional. If the administrator can restrict, ban or
unban chat members.
can_pin_messages (:obj:`bool`): Optional. If the administrator can pin messages.
can_pin_messages (:obj:`bool`): Optional. If the user can pin messages.
can_promote_members (:obj:`bool`): Optional. If the administrator can add new
administrators.
is_member (:obj:`bool`): Optional. Restricted only. True, if the user is a member of the
@ -52,6 +51,8 @@ class ChatMember(TelegramObject):
locations and venues.
can_send_media_messages (:obj:`bool`): Optional. If the user can send media messages,
implies can_send_messages.
can_send_polls (:obj:`bool`): Optional. True, if the user is allowed to
send polls.
can_send_other_messages (:obj:`bool`): Optional. If the user can send animations, games,
stickers and use inline bots, implies can_send_media_messages.
can_add_web_page_previews (:obj:`bool`): Optional. If user may add web page previews to his
@ -65,20 +66,20 @@ class ChatMember(TelegramObject):
restrictions will be lifted for this user.
can_be_edited (:obj:`bool`, optional): Administrators only. True, if the bot is allowed to
edit administrator privileges of that user.
can_change_info (:obj:`bool`, optional): Administrators only. True, if the administrator
can change the chat title, photo and other settings.
can_change_info (:obj:`bool`, optional): Administrators and restricted only. True, if the
user can change the chat title, photo and other settings.
can_post_messages (:obj:`bool`, optional): Administrators only. True, if the administrator
can post in the channel, channels only.
can_edit_messages (:obj:`bool`, optional): Administrators only. True, if the administrator
can edit messages of other users, channels only.
can_delete_messages (:obj:`bool`, optional): Administrators only. True, if the
administrator can delete messages of other user.
can_invite_users (:obj:`bool`, optional): Administrators only. True, if the administrator
can invite new users to the chat.
can_invite_users (:obj:`bool`, optional): Administrators and restricted only. True, if the
user can invite new users to the chat.
can_restrict_members (:obj:`bool`, optional): Administrators only. True, if the
administrator can restrict, ban or unban chat members.
can_pin_messages (:obj:`bool`, optional): Administrators only. True, if the administrator
can pin messages, supergroups only.
can_pin_messages (:obj:`bool`, optional): Administrators and restricted only. True, if the
user can pin messages, supergroups only.
can_promote_members (:obj:`bool`, optional): Administrators only. True, if the
administrator can add new administrators with a subset of his own privileges or demote
administrators that he has promoted, directly or indirectly (promoted by administrators
@ -90,6 +91,8 @@ class ChatMember(TelegramObject):
can_send_media_messages (:obj:`bool`, optional): Restricted only. True, if the user can
send audios, documents, photos, videos, video notes and voice notes, implies
can_send_messages.
can_send_polls (:obj:`bool`, optional): Restricted only. True, if the user is allowed to
send polls.
can_send_other_messages (:obj:`bool`, optional): Restricted only. True, if the user can
send animations, games, stickers and use inline bots, implies can_send_media_messages.
can_add_web_page_previews (:obj:`bool`, optional): Restricted only. True, if user may add
@ -114,7 +117,7 @@ class ChatMember(TelegramObject):
can_delete_messages=None, can_invite_users=None,
can_restrict_members=None, can_pin_messages=None,
can_promote_members=None, can_send_messages=None,
can_send_media_messages=None, can_send_other_messages=None,
can_send_media_messages=None, can_send_polls=None, can_send_other_messages=None,
can_add_web_page_previews=None, is_member=None, **kwargs):
# Required
self.user = user
@ -131,6 +134,7 @@ class ChatMember(TelegramObject):
self.can_promote_members = can_promote_members
self.can_send_messages = can_send_messages
self.can_send_media_messages = can_send_media_messages
self.can_send_polls = can_send_polls
self.can_send_other_messages = can_send_other_messages
self.can_add_web_page_previews = can_add_web_page_previews
self.is_member = is_member

View file

@ -0,0 +1,87 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2018
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram ChatPermission."""
from telegram import TelegramObject
class ChatPermissions(TelegramObject):
"""Describes actions that a non-administrator user is allowed to take in a chat.
Attributes:
can_send_messages (:obj:`bool`): Optional. True, if the user is allowed to send text
messages, contacts, locations and venues.
can_send_media_messages (:obj:`bool`): Optional. True, if the user is allowed to send
audios, documents, photos, videos, video notes and voice notes, implies
:attr:`can_send_messages`.
can_send_polls (:obj:`bool`): Optional. True, if the user is allowed to send polls, implies
:attr:`can_send_messages`.
can_send_other_messages (:obj:`bool`): Optional. True, if the user is allowed to send
animations, games, stickers and use inline bots, implies
:attr:`can_send_media_messages`.
can_add_web_page_previews (:obj:`bool`): Optional. True, if the user is allowed to add web
page previews to their messages, implies :attr:`can_send_media_messages`.
can_change_info (:obj:`bool`): Optional. True, if the user is allowed to change the chat
title, photo and other settings. Ignored in public supergroups.
can_invite_users (:obj:`bool`): Optional. True, if the user is allowed to invite new users
to the chat.
can_pin_messages (:obj:`bool`): Optional. True, if the user is allowed to pin messages.
Ignored in public supergroups.
Args:
can_send_messages (:obj:`bool`, optional): True, if the user is allowed to send text
messages, contacts, locations and venues.
can_send_media_messages (:obj:`bool`, optional): True, if the user is allowed to send
audios, documents, photos, videos, video notes and voice notes, implies
:attr:`can_send_messages`.
can_send_polls (:obj:`bool`, optional): True, if the user is allowed to send polls, implies
:attr:`can_send_messages`.
can_send_other_messages (:obj:`bool`, optional): True, if the user is allowed to send
animations, games, stickers and use inline bots, implies
:attr:`can_send_media_messages`.
can_add_web_page_previews (:obj:`bool`, optional): True, if the user is allowed to add web
page previews to their messages, implies :attr:`can_send_media_messages`.
can_change_info (:obj:`bool`, optional): True, if the user is allowed to change the chat
title, photo and other settings. Ignored in public supergroups.
can_invite_users (:obj:`bool`, optional): True, if the user is allowed to invite new users
to the chat.
can_pin_messages (:obj:`bool`, optional): True, if the user is allowed to pin messages.
Ignored in public supergroups.
"""
def __init__(self, can_send_messages=None, can_send_media_messages=None, can_send_polls=None,
can_send_other_messages=None, can_add_web_page_previews=None,
can_change_info=None, can_invite_users=None, can_pin_messages=None, **kwargs):
# Required
self.can_send_messages = can_send_messages
self.can_send_media_messages = can_send_media_messages
self.can_send_polls = can_send_polls
self.can_send_other_messages = can_send_other_messages
self.can_add_web_page_previews = can_add_web_page_previews
self.can_change_info = can_change_info
self.can_invite_users = can_invite_users
self.can_pin_messages = can_pin_messages
@classmethod
def de_json(cls, data, bot):
if not data:
return None
return cls(**data)

View file

@ -27,14 +27,14 @@ class ChatPhoto(TelegramObject):
"""This object represents a chat photo.
Attributes:
small_file_id (:obj:`str`): Unique file identifier of small (160x160) chat photo.
big_file_id (:obj:`str`): Unique file identifier of big (640x640) chat photo.
small_file_id (:obj:`str`): File identifier of small (160x160) chat photo.
big_file_id (:obj:`str`): File identifier of big (640x640) chat photo.
Args:
small_file_id (:obj:`str`): Unique file identifier of small (160x160) chat photo. This
file_id can be used only for photo download.
big_file_id (:obj:`str`): Unique file identifier of big (640x640) chat photo. This file_id
can be used only for photo download.
small_file_id (:obj:`str`): File identifier of small (160x160) chat photo. This file_id can
be used only for photo download and only for as long as the photo is not changed.
big_file_id (:obj:`str`): File identifier of big (640x640) chat photo. This file_id can be
used only for photo download and only for as long as the photo is not changed.
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods
**kwargs (:obj:`dict`): Arbitrary keyword arguments.

View file

@ -28,6 +28,7 @@ class Sticker(TelegramObject):
file_id (:obj:`str`): Unique identifier for this file.
width (:obj:`int`): Sticker width.
height (:obj:`int`): Sticker height.
is_animated (:obj:`bool`): True, if the sticker is animated.
thumb (:class:`telegram.PhotoSize`): Optional. Sticker thumbnail in the .webp or .jpg
format.
emoji (:obj:`str`): Optional. Emoji associated with the sticker.
@ -41,6 +42,7 @@ class Sticker(TelegramObject):
file_id (:obj:`str`): Unique identifier for this file.
width (:obj:`int`): Sticker width.
height (:obj:`int`): Sticker height.
is_animated (:obj:`bool`): True, if the sticker is animated.
thumb (:class:`telegram.PhotoSize`, optional): Sticker thumbnail in the .webp or .jpg
format.
emoji (:obj:`str`, optional): Emoji associated with the sticker
@ -58,6 +60,7 @@ class Sticker(TelegramObject):
file_id,
width,
height,
is_animated,
thumb=None,
emoji=None,
file_size=None,
@ -69,6 +72,7 @@ class Sticker(TelegramObject):
self.file_id = str(file_id)
self.width = int(width)
self.height = int(height)
self.is_animated = is_animated
# Optionals
self.thumb = thumb
self.emoji = emoji
@ -123,20 +127,23 @@ class StickerSet(TelegramObject):
Attributes:
name (:obj:`str`): Sticker set name.
title (:obj:`str`): Sticker set title.
is_animated (:obj:`bool`): True, if the sticker set contains animated stickers.
contains_masks (:obj:`bool`): True, if the sticker set contains masks.
stickers (List[:class:`telegram.Sticker`]): List of all set stickers.
Args:
name (:obj:`str`): Sticker set name.
title (:obj:`str`): Sticker set title.
is_animated (:obj:`bool`): True, if the sticker set contains animated stickers.
contains_masks (:obj:`bool`): True, if the sticker set contains masks.
stickers (List[:class:`telegram.Sticker`]): List of all set stickers.
"""
def __init__(self, name, title, contains_masks, stickers, bot=None, **kwargs):
def __init__(self, name, title, is_animated, contains_masks, stickers, bot=None, **kwargs):
self.name = name
self.title = title
self.is_animated = is_animated
self.contains_masks = contains_masks
self.stickers = stickers

View file

@ -28,7 +28,7 @@ from future.utils import string_types
from telegram import (Bot, Update, ChatAction, TelegramError, User, InlineKeyboardMarkup,
InlineKeyboardButton, InlineQueryResultArticle, InputTextMessageContent,
ShippingOption, LabeledPrice, Poll)
ShippingOption, LabeledPrice, ChatPermissions, Poll)
from telegram.error import BadRequest, InvalidToken, NetworkError, RetryAfter
from telegram.utils.helpers import from_timestamp
@ -50,6 +50,11 @@ def media_message(bot, chat_id):
return bot.send_voice(chat_id, voice=f, caption='my caption', timeout=10)
@pytest.fixture(scope='class')
def chat_permissions():
return ChatPermissions(can_send_messages=False, can_change_info=False, can_invite_users=False)
class TestBot(object):
@pytest.mark.parametrize('token', argvalues=[
'123',
@ -260,6 +265,16 @@ class TestBot(object):
assert bot.unban_chat_member(2, 32)
def test_set_chat_permissions(self, monkeypatch, bot, chat_permissions):
def test(_, url, data, *args, **kwargs):
chat_id = data['chat_id'] == 2
permissions = data['permissions'] == chat_permissions.to_dict()
return chat_id and permissions
monkeypatch.setattr('telegram.utils.request.Request.post', test)
assert bot.set_chat_permissions(2, chat_permissions)
# TODO: Needs improvement. Need an incoming callbackquery to test
def test_answer_callback_query(self, monkeypatch, bot):
# For now just test that our internals pass the correct data
@ -581,16 +596,13 @@ class TestBot(object):
@flaky(3, 1)
@pytest.mark.timeout(10)
def test_restrict_chat_member(self, bot, channel_id):
def test_restrict_chat_member(self, bot, channel_id, chat_permissions):
# TODO: Add bot to supergroup so this can be tested properly
with pytest.raises(BadRequest, match='Method is available only for supergroups'):
assert bot.restrict_chat_member(channel_id,
95205500,
until_date=datetime.now(),
can_send_messages=False,
can_send_media_messages=False,
can_send_other_messages=False,
can_add_web_page_previews=False)
chat_permissions,
until_date=datetime.now())
@flaky(3, 1)
@pytest.mark.timeout(10)

View file

@ -19,7 +19,7 @@
import pytest
from telegram import Chat, ChatAction
from telegram import Chat, ChatAction, ChatPermissions
from telegram import User
@ -28,7 +28,8 @@ def chat(bot):
return Chat(TestChat.id, TestChat.title, TestChat.type, username=TestChat.username,
all_members_are_administrators=TestChat.all_members_are_administrators,
bot=bot, sticker_set_name=TestChat.sticker_set_name,
can_set_sticker_set=TestChat.can_set_sticker_set)
can_set_sticker_set=TestChat.can_set_sticker_set,
permissions=TestChat.permissions)
class TestChat(object):
@ -39,6 +40,11 @@ class TestChat(object):
all_members_are_administrators = False
sticker_set_name = 'stickers'
can_set_sticker_set = False
permissions = ChatPermissions(
can_send_messages=True,
can_change_info=False,
can_invite_users=True,
)
def test_de_json(self, bot):
json_dict = {
@ -48,7 +54,8 @@ class TestChat(object):
'username': self.username,
'all_members_are_administrators': self.all_members_are_administrators,
'sticker_set_name': self.sticker_set_name,
'can_set_sticker_set': self.can_set_sticker_set
'can_set_sticker_set': self.can_set_sticker_set,
'permissions': self.permissions.to_dict()
}
chat = Chat.de_json(json_dict, bot)
@ -59,6 +66,7 @@ class TestChat(object):
assert chat.all_members_are_administrators == self.all_members_are_administrators
assert chat.sticker_set_name == self.sticker_set_name
assert chat.can_set_sticker_set == self.can_set_sticker_set
assert chat.permissions == self.permissions
def test_to_dict(self, chat):
chat_dict = chat.to_dict()
@ -69,6 +77,7 @@ class TestChat(object):
assert chat_dict['type'] == chat.type
assert chat_dict['username'] == chat.username
assert chat_dict['all_members_are_administrators'] == chat.all_members_are_administrators
assert chat_dict['permissions'] == chat.permissions.to_dict()
def test_link(self, chat):
assert chat.link == 'https://t.me/{}'.format(chat.username)
@ -133,6 +142,15 @@ class TestChat(object):
monkeypatch.setattr('telegram.Bot.unban_chat_member', test)
assert chat.unban_member(42)
def test_set_permissions(self, monkeypatch, chat):
def test(*args, **kwargs):
chat_id = args[1] == chat.id
permissions = args[2] == self.permissions
return chat_id and permissions
monkeypatch.setattr('telegram.Bot.set_chat_permissions', test)
assert chat.set_permissions(self.permissions)
def test_instance_method_send_message(self, monkeypatch, chat):
def test(*args, **kwargs):
return args[1] == chat.id and args[2] == 'test'

View file

@ -61,8 +61,9 @@ class TestChatMember(object):
'can_promote_members': True,
'can_send_messages': False,
'can_send_media_messages': True,
'can_send_other_messages': False,
'can_add_web_page_previews': True}
'can_send_polls': False,
'can_send_other_messages': True,
'can_add_web_page_previews': False}
chat_member = ChatMember.de_json(json_dict, bot)
@ -79,8 +80,9 @@ class TestChatMember(object):
assert chat_member.can_promote_members is True
assert chat_member.can_send_messages is False
assert chat_member.can_send_media_messages is True
assert chat_member.can_send_other_messages is False
assert chat_member.can_add_web_page_previews is True
assert chat_member.can_send_polls is False
assert chat_member.can_send_other_messages is True
assert chat_member.can_add_web_page_previews is False
def test_to_dict(self, chat_member):
chat_member_dict = chat_member.to_dict()

View file

@ -0,0 +1,79 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2018
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
import pytest
from telegram import ChatPermissions
@pytest.fixture(scope="class")
def chat_permissions():
return ChatPermissions(can_send_messages=True, can_send_media_messages=True,
can_send_polls=True, can_send_other_messages=True,
can_add_web_page_previews=True, can_change_info=True,
can_invite_users=True, can_pin_messages=True)
class TestChatPermissions(object):
can_send_messages = True
can_send_media_messages = True
can_send_polls = True
can_send_other_messages = False
can_add_web_page_previews = False
can_change_info = False
can_invite_users = None
can_pin_messages = None
def test_de_json(self, bot):
json_dict = {
'can_send_messages': self.can_send_messages,
'can_send_media_messages': self.can_send_media_messages,
'can_send_polls': self.can_send_polls,
'can_send_other_messages': self.can_send_other_messages,
'can_add_web_page_previews': self.can_add_web_page_previews,
'can_change_info': self.can_change_info,
'can_invite_users': self.can_invite_users,
'can_pin_messages': self.can_pin_messages
}
permissions = ChatPermissions.de_json(json_dict, bot)
assert permissions.can_send_messages == self.can_send_messages
assert permissions.can_send_media_messages == self.can_send_media_messages
assert permissions.can_send_polls == self.can_send_polls
assert permissions.can_send_other_messages == self.can_send_other_messages
assert permissions.can_add_web_page_previews == self.can_add_web_page_previews
assert permissions.can_change_info == self.can_change_info
assert permissions.can_invite_users == self.can_invite_users
assert permissions.can_pin_messages == self.can_pin_messages
def test_to_dict(self, chat_permissions):
permissions_dict = chat_permissions.to_dict()
assert isinstance(permissions_dict, dict)
assert permissions_dict['can_send_messages'] == chat_permissions.can_send_messages
assert (permissions_dict['can_send_media_messages']
== chat_permissions.can_send_media_messages)
assert permissions_dict['can_send_polls'] == chat_permissions.can_send_polls
assert (permissions_dict['can_send_other_messages']
== chat_permissions.can_send_other_messages)
assert (permissions_dict['can_add_web_page_previews']
== chat_permissions.can_add_web_page_previews)
assert permissions_dict['can_change_info'] == chat_permissions.can_change_info
assert permissions_dict['can_invite_users'] == chat_permissions.can_invite_users
assert permissions_dict['can_pin_messages'] == chat_permissions.can_pin_messages

View file

@ -47,7 +47,7 @@ class TestHelpers(object):
assert helpers.effective_message_type(test_message) == 'text'
test_message.text = None
test_message = build_test_message(sticker=Sticker('sticker_id', 50, 50))
test_message = build_test_message(sticker=Sticker('sticker_id', 50, 50, False))
assert helpers.effective_message_type(test_message) == 'sticker'
test_message.sticker = None

View file

@ -57,7 +57,7 @@ def message(bot):
[PhotoSize('game_photo_id', 30, 30), ])},
{'photo': [PhotoSize('photo_id', 50, 50)],
'caption': 'photo_file'},
{'sticker': Sticker('sticker_id', 50, 50)},
{'sticker': Sticker('sticker_id', 50, 50, True)},
{'video': Video('video_id', 12, 12, 12),
'caption': 'video_file'},
{'voice': Voice('voice_id', 5)},

View file

@ -120,6 +120,8 @@ def check_object(h4):
ignored |= {'credentials'}
elif name == 'PassportElementError':
ignored |= {'message', 'type', 'source'}
elif name == 'Chat':
ignored |= {'all_members_are_administrators'}
assert (sig.parameters.keys() ^ checked) - ignored == set()

View file

@ -317,7 +317,7 @@ class TestPhoto(object):
b = PhotoSize(photo.file_id, self.width, self.height)
c = PhotoSize(photo.file_id, 0, 0)
d = PhotoSize('', self.width, self.height)
e = Sticker(photo.file_id, self.width, self.height)
e = Sticker(photo.file_id, self.width, self.height, False)
assert a == b
assert hash(a) == hash(b)

View file

@ -49,6 +49,7 @@ class TestSticker(object):
emoji = '💪'
width = 510
height = 512
is_animated = False
file_size = 39518
thumb_width = 319
thumb_height = 320
@ -66,6 +67,7 @@ class TestSticker(object):
def test_expected_values(self, sticker):
assert sticker.width == self.width
assert sticker.height == self.height
assert sticker.is_animated == self.is_animated
assert sticker.file_size == self.file_size
assert sticker.thumb.width == self.thumb_width
assert sticker.thumb.height == self.thumb_height
@ -81,6 +83,7 @@ class TestSticker(object):
assert message.sticker.file_id != ''
assert message.sticker.width == sticker.width
assert message.sticker.height == sticker.height
assert message.sticker.is_animated == sticker.is_animated
assert message.sticker.file_size == sticker.file_size
assert isinstance(message.sticker.thumb, PhotoSize)
@ -132,6 +135,7 @@ class TestSticker(object):
assert message.sticker.file_id != ''
assert message.sticker.width == sticker.width
assert message.sticker.height == sticker.height
assert message.sticker.is_animated == sticker.is_animated
assert message.sticker.file_size == sticker.file_size
assert isinstance(message.sticker.thumb, PhotoSize)
@ -146,6 +150,7 @@ class TestSticker(object):
'file_id': 'not a file id',
'width': self.width,
'height': self.height,
'is_animated': self.is_animated,
'thumb': sticker.thumb.to_dict(),
'emoji': self.emoji,
'file_size': self.file_size
@ -155,6 +160,7 @@ class TestSticker(object):
assert json_sticker.file_id == 'not a file id'
assert json_sticker.width == self.width
assert json_sticker.height == self.height
assert json_sticker.is_animated == self.is_animated
assert json_sticker.emoji == self.emoji
assert json_sticker.file_size == self.file_size
assert json_sticker.thumb == sticker.thumb
@ -174,6 +180,7 @@ class TestSticker(object):
assert sticker_dict['file_id'] == sticker.file_id
assert sticker_dict['width'] == sticker.width
assert sticker_dict['height'] == sticker.height
assert sticker_dict['is_animated'] == sticker.is_animated
assert sticker_dict['file_size'] == sticker.file_size
assert sticker_dict['thumb'] == sticker.thumb.to_dict()
@ -194,11 +201,11 @@ class TestSticker(object):
bot.send_sticker(chat_id)
def test_equality(self, sticker):
a = Sticker(sticker.file_id, self.width, self.height)
b = Sticker(sticker.file_id, self.width, self.height)
c = Sticker(sticker.file_id, 0, 0)
d = Sticker('', self.width, self.height)
e = PhotoSize(sticker.file_id, self.width, self.height)
a = Sticker(sticker.file_id, self.width, self.height, self.is_animated)
b = Sticker(sticker.file_id, self.width, self.height, self.is_animated)
c = Sticker(sticker.file_id, 0, 0, False)
d = Sticker('', self.width, self.height, self.is_animated)
e = PhotoSize(sticker.file_id, self.width, self.height, self.is_animated)
assert a == b
assert hash(a) == hash(b)
@ -224,8 +231,9 @@ def sticker_set(bot):
class TestStickerSet(object):
title = 'Test stickers'
is_animated = True
contains_masks = False
stickers = [Sticker('file_id', 512, 512)]
stickers = [Sticker('file_id', 512, 512, True)]
name = 'NOTAREALNAME'
def test_de_json(self, bot):
@ -233,6 +241,7 @@ class TestStickerSet(object):
json_dict = {
'name': name,
'title': self.title,
'is_animated': self.is_animated,
'contains_masks': self.contains_masks,
'stickers': [x.to_dict() for x in self.stickers]
}
@ -240,6 +249,7 @@ class TestStickerSet(object):
assert sticker_set.name == name
assert sticker_set.title == self.title
assert sticker_set.is_animated == self.is_animated
assert sticker_set.contains_masks == self.contains_masks
assert sticker_set.stickers == self.stickers
@ -258,6 +268,7 @@ class TestStickerSet(object):
assert isinstance(sticker_set_dict, dict)
assert sticker_set_dict['name'] == sticker_set.name
assert sticker_set_dict['title'] == sticker_set.title
assert sticker_set_dict['is_animated'] == sticker_set.is_animated
assert sticker_set_dict['contains_masks'] == sticker_set.contains_masks
assert sticker_set_dict['stickers'][0] == sticker_set.stickers[0].to_dict()
@ -282,10 +293,10 @@ class TestStickerSet(object):
assert sticker.get_file()
def test_equality(self):
a = StickerSet(self.name, self.title, self.contains_masks, self.stickers)
b = StickerSet(self.name, self.title, self.contains_masks, self.stickers)
c = StickerSet(self.name, None, None, None)
d = StickerSet('blah', self.title, self.contains_masks, self.stickers)
a = StickerSet(self.name, self.title, self.is_animated, self.contains_masks, self.stickers)
b = StickerSet(self.name, self.title, self.is_animated, self.contains_masks, self.stickers)
c = StickerSet(self.name, None, None, None, None)
d = StickerSet('blah', self.title, self.is_animated, self.contains_masks, self.stickers)
e = Audio(self.name, 0, None, None)
assert a == b