mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-03-13 11:18:20 +01:00
API 4.5 (#1508)
* Allow for nested MessageEntities in Message._parse_markdown/html, adjust tests
* remove testing relict
* Use MessageEntitys new equality check (#1465)
* Remove unused variable
* Update to custom_title feature and slow_mode_delay option
Changes:
- custom_title for ChatMember
- new method setChatAdministratorCustomTitle for Bot
- new slow_mode_delay for Chat
Update due to new API future `custom_title` from API 4.5 (https://core.telegram.org/bots/api#december-31-2019)
* Minor typo fix
* Comply with Flake8
* Add new MessageEntities and MarkdownV2
* Added file_unique_id attrs from API 4.5 and updated tests for it
* Fixed test and checked using flake8
* Fixed ChatPhoto documentation
* Fix Flake8
* Add setChatAdminCstmTitle to Bot
* Rename MDV2 methods
* Change files id attrs to unique id
* correct id_attrs for chat_photo
* Revert "temporarily skip tests failing b/c missing api 4.5 (#1738)"
This reverts commit 7cde6ca268
.
* Fix text_markdown_v2 for monospace and text_links
* closing remarks from pieter
* Minor fix in escape_markdown, improve tests for it
* Fix offset bug in Message._parse_*
* Add test_chatphoto.py
* remove debug print from test_message.py
* try making codecov happy
* Update readme
* all hail codecov
* Improve Link handling for MarkdownV1 and adjust tests. Closes #1654
* Dont use beginning of pre-entity as language in _parse_markdown
* Remove debug print
* Dummy commit to try fix codecov
Co-authored-by: Hoi Dmytro <dmytro.hoi@gmail.com>
Co-authored-by: Dmytro Hoi <code@dmytrohoi.com>
Co-authored-by: poolitzer <25934244+poolitzer@users.noreply.github.com>
This commit is contained in:
parent
e86ae25a62
commit
8d2c7af1f3
45 changed files with 1223 additions and 265 deletions
|
@ -93,7 +93,7 @@ make the development of bots easy and straightforward. These classes are contain
|
|||
Telegram API support
|
||||
====================
|
||||
|
||||
All types and methods of the Telegram Bot API **4.1** are supported.
|
||||
All types and methods of the Telegram Bot API **4.5** are supported.
|
||||
|
||||
==========
|
||||
Installing
|
||||
|
|
|
@ -2941,6 +2941,44 @@ class Bot(TelegramObject):
|
|||
|
||||
return result
|
||||
|
||||
@log
|
||||
def set_chat_administrator_custom_title(self,
|
||||
chat_id,
|
||||
user_id,
|
||||
custom_title,
|
||||
timeout=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Use this method to set a custom title for administrators promoted by the bot in a
|
||||
supergroup. The bot must be an administrator for this to work. 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`).
|
||||
user_id (:obj:`int`): Unique identifier of the target administrator.
|
||||
custom_title (:obj:`str`) New custom title for the administrator. It must be a string
|
||||
with len 0-16 characters, emoji are not allowed.
|
||||
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}/setChatAdministratorCustomTitle'.format(self.base_url)
|
||||
|
||||
data = {'chat_id': chat_id, 'user_id': user_id, 'custom_title': custom_title}
|
||||
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):
|
||||
"""
|
||||
|
@ -3655,6 +3693,8 @@ class Bot(TelegramObject):
|
|||
"""Alias for :attr:`promote_chat_member`"""
|
||||
setChatPermissions = set_chat_permissions
|
||||
"""Alias for :attr:`set_chat_permissions`"""
|
||||
setChatAdministratorCustomTitle = set_chat_administrator_custom_title
|
||||
"""Alias for :attr:`set_chat_administrator_custom_title`"""
|
||||
exportChatInviteLink = export_chat_invite_link
|
||||
"""Alias for :attr:`export_chat_invite_link`"""
|
||||
setChatPhoto = set_chat_photo
|
||||
|
|
|
@ -40,6 +40,8 @@ class Chat(TelegramObject):
|
|||
Returned only in get_chat.
|
||||
permissions (:class:`telegram.ChatPermission`): Optional. Default chat member permissions,
|
||||
for groups and supergroups. Returned only in getChat.
|
||||
slow_mode_delay (:obj:`int`): Optional. For supergroups, the minimum allowed delay between
|
||||
consecutive messages sent by each unpriviledged user. 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.
|
||||
|
@ -65,6 +67,8 @@ class Chat(TelegramObject):
|
|||
Returned only in get_chat.
|
||||
permissions (:class:`telegram.ChatPermission`): Optional. Default chat member permissions,
|
||||
for groups and supergroups. Returned only in getChat.
|
||||
slow_mode_delay (:obj:`int`, optional): For supergroups, the minimum allowed delay between
|
||||
consecutive messages sent by each unpriviledged user. 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.
|
||||
|
@ -98,6 +102,7 @@ class Chat(TelegramObject):
|
|||
permissions=None,
|
||||
sticker_set_name=None,
|
||||
can_set_sticker_set=None,
|
||||
slow_mode_delay=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.id = int(id)
|
||||
|
@ -114,6 +119,7 @@ class Chat(TelegramObject):
|
|||
self.invite_link = invite_link
|
||||
self.pinned_message = pinned_message
|
||||
self.permissions = permissions
|
||||
self.slow_mode_delay = slow_mode_delay
|
||||
self.sticker_set_name = sticker_set_name
|
||||
self.can_set_sticker_set = can_set_sticker_set
|
||||
|
||||
|
@ -240,6 +246,17 @@ class Chat(TelegramObject):
|
|||
"""
|
||||
return self.bot.set_chat_permissions(self.id, *args, **kwargs)
|
||||
|
||||
def set_administrator_custom_title(self, *args, **kwargs):
|
||||
"""Shortcut for::
|
||||
|
||||
bot.set_chat_administrator_custom_title(update.message.chat.id, *args, **kwargs)
|
||||
|
||||
Returns:
|
||||
:obj:`bool`: If the action was sent successfully.
|
||||
|
||||
"""
|
||||
return self.bot.set_chat_administrator_custom_title(self.id, *args, **kwargs)
|
||||
|
||||
def send_message(self, *args, **kwargs):
|
||||
"""Shortcut for::
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ class ChatMember(TelegramObject):
|
|||
Attributes:
|
||||
user (:class:`telegram.User`): Information about the user.
|
||||
status (:obj:`str`): The member's status in the chat.
|
||||
custom_title (:obj:`str`): Optional. Custom title for owner and administrators.
|
||||
until_date (:class:`datetime.datetime`): Optional. Date when restrictions will be lifted
|
||||
for this user.
|
||||
can_be_edited (:obj:`bool`): Optional. If the bot is allowed to edit administrator
|
||||
|
@ -62,6 +63,8 @@ class ChatMember(TelegramObject):
|
|||
user (:class:`telegram.User`): Information about the user.
|
||||
status (:obj:`str`): The member's status in the chat. Can be 'creator', 'administrator',
|
||||
'member', 'restricted', 'left' or 'kicked'.
|
||||
custom_title (:obj:`str`, optional): Owner and administrators only.
|
||||
Custom title for this user.
|
||||
until_date (:class:`datetime.datetime`, optional): Restricted and kicked only. Date when
|
||||
restrictions will be lifted for this user.
|
||||
can_be_edited (:obj:`bool`, optional): Administrators only. True, if the bot is allowed to
|
||||
|
@ -118,10 +121,11 @@ class ChatMember(TelegramObject):
|
|||
can_restrict_members=None, can_pin_messages=None,
|
||||
can_promote_members=None, can_send_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):
|
||||
can_add_web_page_previews=None, is_member=None, custom_title=None, **kwargs):
|
||||
# Required
|
||||
self.user = user
|
||||
self.status = status
|
||||
self.custom_title = custom_title
|
||||
self.until_date = until_date
|
||||
self.can_be_edited = can_be_edited
|
||||
self.can_change_info = can_change_info
|
||||
|
|
|
@ -25,7 +25,10 @@ class Animation(TelegramObject):
|
|||
"""This object represents an animation file to be displayed in the message containing a game.
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Unique file identifier.
|
||||
file_id (:obj:`str`): File identifier.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Video width as defined by sender.
|
||||
height (:obj:`int`): Video height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
|
@ -37,7 +40,10 @@ class Animation(TelegramObject):
|
|||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Unique file identifier.
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique and the same over time and
|
||||
for different bots file identifier.
|
||||
width (:obj:`int`): Video width as defined by sender.
|
||||
height (:obj:`int`): Video height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
|
@ -52,6 +58,7 @@ class Animation(TelegramObject):
|
|||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
file_unique_id,
|
||||
width,
|
||||
height,
|
||||
duration,
|
||||
|
@ -63,6 +70,7 @@ class Animation(TelegramObject):
|
|||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.file_unique_id = str(file_unique_id)
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
self.duration = duration
|
||||
|
@ -73,7 +81,7 @@ class Animation(TelegramObject):
|
|||
self.file_size = file_size
|
||||
self.bot = bot
|
||||
|
||||
self._id_attrs = (self.file_id,)
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -26,6 +26,9 @@ class Audio(TelegramObject):
|
|||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
duration (:obj:`int`): Duration of the audio in seconds.
|
||||
performer (:obj:`str`): Optional. Performer of the audio as defined by sender or by audio
|
||||
tags.
|
||||
|
@ -37,7 +40,10 @@ class Audio(TelegramObject):
|
|||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique and the same over time and
|
||||
for different bots file identifier.
|
||||
duration (:obj:`int`): Duration of the audio in seconds as defined by sender.
|
||||
performer (:obj:`str`, optional): Performer of the audio as defined by sender or by audio
|
||||
tags.
|
||||
|
@ -53,6 +59,7 @@ class Audio(TelegramObject):
|
|||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
file_unique_id,
|
||||
duration,
|
||||
performer=None,
|
||||
title=None,
|
||||
|
@ -63,6 +70,7 @@ class Audio(TelegramObject):
|
|||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.file_unique_id = str(file_unique_id)
|
||||
self.duration = int(duration)
|
||||
# Optionals
|
||||
self.performer = performer
|
||||
|
@ -72,7 +80,7 @@ class Audio(TelegramObject):
|
|||
self.thumb = thumb
|
||||
self.bot = bot
|
||||
|
||||
self._id_attrs = (self.file_id,)
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -25,24 +25,48 @@ class ChatPhoto(TelegramObject):
|
|||
|
||||
Attributes:
|
||||
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.
|
||||
small_file_unique_id (:obj:`str`): Unique file identifier of small (160x160) chat photo,
|
||||
which is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
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.
|
||||
big_file_unique_id (:obj:`str`): Unique file identifier of big (640x640) chat photo,
|
||||
which is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
Args:
|
||||
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.
|
||||
small_file_id (:obj:`str`): Unique 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.
|
||||
small_file_unique_id (:obj:`str`): Unique file identifier of small (160x160) chat photo,
|
||||
which is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
big_file_id (:obj:`str`): Unique 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.
|
||||
big_file_unique_id (:obj:`str`): Unique file identifier of big (640x640) chat photo,
|
||||
which is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods
|
||||
**kwargs (:obj:`dict`): Arbitrary keyword arguments.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, small_file_id, big_file_id, bot=None, **kwargs):
|
||||
def __init__(self,
|
||||
small_file_id,
|
||||
small_file_unique_id,
|
||||
big_file_id,
|
||||
big_file_unique_id,
|
||||
bot=None, **kwargs):
|
||||
self.small_file_id = small_file_id
|
||||
self.small_file_unique_id = small_file_unique_id
|
||||
self.big_file_id = big_file_id
|
||||
self.big_file_unique_id = big_file_unique_id
|
||||
|
||||
self.bot = bot
|
||||
|
||||
self._id_attrs = (self.small_file_id, self.big_file_id)
|
||||
self._id_attrs = (self.small_file_unique_id, self.big_file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -26,6 +26,9 @@ class Document(TelegramObject):
|
|||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Unique file identifier.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
thumb (:class:`telegram.PhotoSize`): Optional. Document thumbnail.
|
||||
file_name (:obj:`str`): Original filename.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file.
|
||||
|
@ -33,7 +36,10 @@ class Document(TelegramObject):
|
|||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Unique file identifier
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique and the same over time and
|
||||
for different bots file identifier.
|
||||
thumb (:class:`telegram.PhotoSize`, optional): Document thumbnail as defined by sender.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by sender.
|
||||
|
@ -46,6 +52,7 @@ class Document(TelegramObject):
|
|||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
file_unique_id,
|
||||
thumb=None,
|
||||
file_name=None,
|
||||
mime_type=None,
|
||||
|
@ -54,6 +61,7 @@ class Document(TelegramObject):
|
|||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.file_unique_id = str(file_unique_id)
|
||||
# Optionals
|
||||
self.thumb = thumb
|
||||
self.file_name = file_name
|
||||
|
@ -61,7 +69,7 @@ class Document(TelegramObject):
|
|||
self.file_size = file_size
|
||||
self.bot = bot
|
||||
|
||||
self._id_attrs = (self.file_id,)
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -38,11 +38,17 @@ class File(TelegramObject):
|
|||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`str`): Optional. File size.
|
||||
file_path (:obj:`str`): Optional. File path. Use :attr:`download` to get the file.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique and the same over time and
|
||||
for different bots file identifier.
|
||||
file_size (:obj:`int`, optional): Optional. File size, if known.
|
||||
file_path (:obj:`str`, optional): File path. Use :attr:`download` to get the file.
|
||||
bot (:obj:`telegram.Bot`, optional): Bot to use with shortcut method.
|
||||
|
@ -54,18 +60,23 @@ class File(TelegramObject):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, bot=None, file_size=None, file_path=None, **kwargs):
|
||||
def __init__(self,
|
||||
file_id,
|
||||
file_unique_id,
|
||||
bot=None,
|
||||
file_size=None,
|
||||
file_path=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
|
||||
self.file_unique_id = str(file_unique_id)
|
||||
# Optionals
|
||||
self.file_size = file_size
|
||||
self.file_path = file_path
|
||||
|
||||
self.bot = bot
|
||||
self._credentials = None
|
||||
|
||||
self._id_attrs = (self.file_id,)
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -26,13 +26,19 @@ class PhotoSize(TelegramObject):
|
|||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Photo width.
|
||||
height (:obj:`int`): Photo height.
|
||||
file_size (:obj:`int`): Optional. File size.
|
||||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique and the same over time and
|
||||
for different bots file identifier.
|
||||
width (:obj:`int`): Photo width.
|
||||
height (:obj:`int`): Photo height.
|
||||
file_size (:obj:`int`, optional): File size.
|
||||
|
@ -41,16 +47,24 @@ class PhotoSize(TelegramObject):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, width, height, file_size=None, bot=None, **kwargs):
|
||||
def __init__(self,
|
||||
file_id,
|
||||
file_unique_id,
|
||||
width,
|
||||
height,
|
||||
file_size=None,
|
||||
bot=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.file_unique_id = str(file_unique_id)
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
# Optionals
|
||||
self.file_size = file_size
|
||||
self.bot = bot
|
||||
|
||||
self._id_attrs = (self.file_id,)
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -26,6 +26,9 @@ class Sticker(TelegramObject):
|
|||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Sticker width.
|
||||
height (:obj:`int`): Sticker height.
|
||||
is_animated (:obj:`bool`): True, if the sticker is animated.
|
||||
|
@ -39,7 +42,10 @@ class Sticker(TelegramObject):
|
|||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique and the same over time and
|
||||
for different bots file identifier.
|
||||
width (:obj:`int`): Sticker width.
|
||||
height (:obj:`int`): Sticker height.
|
||||
is_animated (:obj:`bool`): True, if the sticker is animated.
|
||||
|
@ -58,6 +64,7 @@ class Sticker(TelegramObject):
|
|||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
file_unique_id,
|
||||
width,
|
||||
height,
|
||||
is_animated,
|
||||
|
@ -70,6 +77,7 @@ class Sticker(TelegramObject):
|
|||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.file_unique_id = str(file_unique_id)
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
self.is_animated = is_animated
|
||||
|
@ -81,7 +89,7 @@ class Sticker(TelegramObject):
|
|||
self.mask_position = mask_position
|
||||
self.bot = bot
|
||||
|
||||
self._id_attrs = (self.file_id,)
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -26,6 +26,9 @@ class Video(TelegramObject):
|
|||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Video width as defined by sender.
|
||||
height (:obj:`int`): Video height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
|
@ -35,7 +38,10 @@ class Video(TelegramObject):
|
|||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique and the same over time and
|
||||
for different bots file identifier.
|
||||
width (:obj:`int`): Video width as defined by sender.
|
||||
height (:obj:`int`): Video height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
|
@ -49,6 +55,7 @@ class Video(TelegramObject):
|
|||
|
||||
def __init__(self,
|
||||
file_id,
|
||||
file_unique_id,
|
||||
width,
|
||||
height,
|
||||
duration,
|
||||
|
@ -59,6 +66,7 @@ class Video(TelegramObject):
|
|||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.file_unique_id = str(file_unique_id)
|
||||
self.width = int(width)
|
||||
self.height = int(height)
|
||||
self.duration = int(duration)
|
||||
|
@ -68,7 +76,7 @@ class Video(TelegramObject):
|
|||
self.file_size = file_size
|
||||
self.bot = bot
|
||||
|
||||
self._id_attrs = (self.file_id,)
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -26,6 +26,9 @@ class VideoNote(TelegramObject):
|
|||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
length (:obj:`int`): Video width and height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
thumb (:class:`telegram.PhotoSize`): Optional. Video thumbnail.
|
||||
|
@ -33,7 +36,10 @@ class VideoNote(TelegramObject):
|
|||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique and the same over time and
|
||||
for different bots file identifier.
|
||||
length (:obj:`int`): Video width and height as defined by sender.
|
||||
duration (:obj:`int`): Duration of the video in seconds as defined by sender.
|
||||
thumb (:class:`telegram.PhotoSize`, optional): Video thumbnail.
|
||||
|
@ -43,9 +49,18 @@ class VideoNote(TelegramObject):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, length, duration, thumb=None, file_size=None, bot=None, **kwargs):
|
||||
def __init__(self,
|
||||
file_id,
|
||||
file_unique_id,
|
||||
length,
|
||||
duration,
|
||||
thumb=None,
|
||||
file_size=None,
|
||||
bot=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.file_unique_id = str(file_unique_id)
|
||||
self.length = int(length)
|
||||
self.duration = int(duration)
|
||||
# Optionals
|
||||
|
@ -53,7 +68,7 @@ class VideoNote(TelegramObject):
|
|||
self.file_size = file_size
|
||||
self.bot = bot
|
||||
|
||||
self._id_attrs = (self.file_id,)
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -26,13 +26,19 @@ class Voice(TelegramObject):
|
|||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
duration (:obj:`int`): Duration of the audio in seconds as defined by sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by sender.
|
||||
file_size (:obj:`int`): Optional. File size.
|
||||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique and the same over time and
|
||||
for different bots file identifier.
|
||||
duration (:obj:`int`, optional): Duration of the audio in seconds as defined by sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by sender.
|
||||
file_size (:obj:`int`, optional): File size.
|
||||
|
@ -41,16 +47,24 @@ class Voice(TelegramObject):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, duration, mime_type=None, file_size=None, bot=None, **kwargs):
|
||||
def __init__(self,
|
||||
file_id,
|
||||
file_unique_id,
|
||||
duration,
|
||||
mime_type=None,
|
||||
file_size=None,
|
||||
bot=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.file_id = str(file_id)
|
||||
self.file_unique_id = str(file_unique_id)
|
||||
self.duration = int(duration)
|
||||
# Optionals
|
||||
self.mime_type = mime_type
|
||||
self.file_size = file_size
|
||||
self.bot = bot
|
||||
|
||||
self._id_attrs = (self.file_id,)
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -510,7 +510,7 @@ class Message(TelegramObject):
|
|||
bot.send_message(update.message.chat_id, parse_mode=ParseMode.MARKDOWN, *args,
|
||||
**kwargs)
|
||||
|
||||
Sends a message with markdown formatting.
|
||||
Sends a message with markdown version 1 formatting.
|
||||
|
||||
Keyword Args:
|
||||
quote (:obj:`bool`, optional): If set to ``True``, the message is sent as an actual
|
||||
|
@ -528,6 +528,30 @@ class Message(TelegramObject):
|
|||
|
||||
return self.bot.send_message(self.chat_id, *args, **kwargs)
|
||||
|
||||
def reply_markdown_v2(self, *args, **kwargs):
|
||||
"""Shortcut for::
|
||||
|
||||
bot.send_message(update.message.chat_id, parse_mode=ParseMode.MARKDOWN_V2, *args,
|
||||
**kwargs)
|
||||
|
||||
Sends a message with markdown version 2 formatting.
|
||||
|
||||
Keyword Args:
|
||||
quote (:obj:`bool`, optional): If set to ``True``, the message is sent as an actual
|
||||
reply to this message. If ``reply_to_message_id`` is passed in ``kwargs``, this
|
||||
parameter will be ignored. Default: ``True`` in group chats and ``False`` in
|
||||
private chats.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.Message`: On success, instance representing the message posted.
|
||||
"""
|
||||
|
||||
kwargs['parse_mode'] = ParseMode.MARKDOWN_V2
|
||||
|
||||
self._quote(kwargs)
|
||||
|
||||
return self.bot.send_message(self.chat_id, *args, **kwargs)
|
||||
|
||||
def reply_html(self, *args, **kwargs):
|
||||
"""Shortcut for::
|
||||
|
||||
|
@ -1012,7 +1036,7 @@ class Message(TelegramObject):
|
|||
}
|
||||
|
||||
@staticmethod
|
||||
def _parse_html(message_text, entities, urled=False):
|
||||
def _parse_html(message_text, entities, urled=False, offset=0):
|
||||
if message_text is None:
|
||||
return None
|
||||
|
||||
|
@ -1022,38 +1046,74 @@ class Message(TelegramObject):
|
|||
html_text = ''
|
||||
last_offset = 0
|
||||
|
||||
for entity, text in sorted(entities.items(), key=(lambda item: item[0].offset)):
|
||||
text = escape(text)
|
||||
sorted_entities = sorted(entities.items(), key=(lambda item: item[0].offset))
|
||||
parsed_entities = []
|
||||
|
||||
if entity.type == MessageEntity.TEXT_LINK:
|
||||
insert = '<a href="{}">{}</a>'.format(entity.url, text)
|
||||
elif entity.type == MessageEntity.TEXT_MENTION and entity.user:
|
||||
insert = '<a href="tg://user?id={}">{}</a>'.format(entity.user.id, text)
|
||||
elif entity.type == MessageEntity.URL and urled:
|
||||
insert = '<a href="{0}">{0}</a>'.format(text)
|
||||
elif entity.type == MessageEntity.BOLD:
|
||||
insert = '<b>' + text + '</b>'
|
||||
elif entity.type == MessageEntity.ITALIC:
|
||||
insert = '<i>' + text + '</i>'
|
||||
elif entity.type == MessageEntity.CODE:
|
||||
insert = '<code>' + text + '</code>'
|
||||
elif entity.type == MessageEntity.PRE:
|
||||
insert = '<pre>' + text + '</pre>'
|
||||
else:
|
||||
insert = text
|
||||
for (entity, text) in sorted_entities:
|
||||
if entity not in parsed_entities:
|
||||
nested_entities = {
|
||||
e: t
|
||||
for (e, t) in sorted_entities if e.offset >= entity.offset
|
||||
and e.offset + e.length <= entity.offset + entity.length
|
||||
and e != entity
|
||||
}
|
||||
parsed_entities.extend([e for e in nested_entities.keys()])
|
||||
|
||||
text = escape(text)
|
||||
|
||||
if nested_entities:
|
||||
text = Message._parse_html(text, nested_entities,
|
||||
urled=urled, offset=entity.offset)
|
||||
|
||||
if entity.type == MessageEntity.TEXT_LINK:
|
||||
insert = '<a href="{}">{}</a>'.format(entity.url, text)
|
||||
elif entity.type == MessageEntity.TEXT_MENTION and entity.user:
|
||||
insert = '<a href="tg://user?id={}">{}</a>'.format(entity.user.id, text)
|
||||
elif entity.type == MessageEntity.URL and urled:
|
||||
insert = '<a href="{0}">{0}</a>'.format(text)
|
||||
elif entity.type == MessageEntity.BOLD:
|
||||
insert = '<b>' + text + '</b>'
|
||||
elif entity.type == MessageEntity.ITALIC:
|
||||
insert = '<i>' + text + '</i>'
|
||||
elif entity.type == MessageEntity.CODE:
|
||||
insert = '<code>' + text + '</code>'
|
||||
elif entity.type == MessageEntity.PRE:
|
||||
insert = '<pre>' + text + '</pre>'
|
||||
elif entity.type == MessageEntity.UNDERLINE:
|
||||
insert = '<u>' + text + '</u>'
|
||||
elif entity.type == MessageEntity.STRIKETHROUGH:
|
||||
insert = '<s>' + text + '</s>'
|
||||
else:
|
||||
insert = text
|
||||
|
||||
if offset == 0:
|
||||
if sys.maxunicode == 0xffff:
|
||||
html_text += escape(message_text[last_offset:entity.offset
|
||||
- offset]) + insert
|
||||
else:
|
||||
html_text += escape(message_text[last_offset * 2:(entity.offset
|
||||
- offset) * 2]
|
||||
.decode('utf-16-le')) + insert
|
||||
else:
|
||||
if sys.maxunicode == 0xffff:
|
||||
html_text += message_text[last_offset:entity.offset - offset] + insert
|
||||
else:
|
||||
html_text += message_text[last_offset * 2:(entity.offset
|
||||
- offset) * 2].decode('utf-16-le') + insert
|
||||
|
||||
last_offset = entity.offset - offset + entity.length
|
||||
|
||||
if offset == 0:
|
||||
if sys.maxunicode == 0xffff:
|
||||
html_text += escape(message_text[last_offset:entity.offset]) + insert
|
||||
html_text += escape(message_text[last_offset:])
|
||||
else:
|
||||
html_text += escape(message_text[last_offset * 2:entity.offset * 2]
|
||||
.decode('utf-16-le')) + insert
|
||||
|
||||
last_offset = entity.offset + entity.length
|
||||
|
||||
if sys.maxunicode == 0xffff:
|
||||
html_text += escape(message_text[last_offset:])
|
||||
html_text += escape(message_text[last_offset * 2:].decode('utf-16-le'))
|
||||
else:
|
||||
html_text += escape(message_text[last_offset * 2:].decode('utf-16-le'))
|
||||
if sys.maxunicode == 0xffff:
|
||||
html_text += message_text[last_offset:]
|
||||
else:
|
||||
html_text += message_text[last_offset * 2:].decode('utf-16-le')
|
||||
|
||||
return html_text
|
||||
|
||||
@property
|
||||
|
@ -1111,7 +1171,9 @@ class Message(TelegramObject):
|
|||
return self._parse_html(self.caption, self.parse_caption_entities(), urled=True)
|
||||
|
||||
@staticmethod
|
||||
def _parse_markdown(message_text, entities, urled=False):
|
||||
def _parse_markdown(message_text, entities, urled=False, version=1, offset=0):
|
||||
version = int(version)
|
||||
|
||||
if message_text is None:
|
||||
return None
|
||||
|
||||
|
@ -1121,42 +1183,114 @@ class Message(TelegramObject):
|
|||
markdown_text = ''
|
||||
last_offset = 0
|
||||
|
||||
for entity, text in sorted(entities.items(), key=(lambda item: item[0].offset)):
|
||||
text = escape_markdown(text)
|
||||
sorted_entities = sorted(entities.items(), key=(lambda item: item[0].offset))
|
||||
parsed_entities = []
|
||||
|
||||
if entity.type == MessageEntity.TEXT_LINK:
|
||||
insert = '[{}]({})'.format(text, entity.url)
|
||||
elif entity.type == MessageEntity.TEXT_MENTION and entity.user:
|
||||
insert = '[{}](tg://user?id={})'.format(text, entity.user.id)
|
||||
elif entity.type == MessageEntity.URL and urled:
|
||||
insert = '[{0}]({0})'.format(text)
|
||||
elif entity.type == MessageEntity.BOLD:
|
||||
insert = '*' + text + '*'
|
||||
elif entity.type == MessageEntity.ITALIC:
|
||||
insert = '_' + text + '_'
|
||||
elif entity.type == MessageEntity.CODE:
|
||||
insert = '`' + text + '`'
|
||||
elif entity.type == MessageEntity.PRE:
|
||||
insert = '```' + text + '```'
|
||||
else:
|
||||
insert = text
|
||||
for (entity, text) in sorted_entities:
|
||||
if entity not in parsed_entities:
|
||||
nested_entities = {
|
||||
e: t
|
||||
for (e, t) in sorted_entities if e.offset >= entity.offset
|
||||
and e.offset + e.length <= entity.offset + entity.length
|
||||
and e != entity
|
||||
}
|
||||
parsed_entities.extend([e for e in nested_entities.keys()])
|
||||
|
||||
orig_text = text
|
||||
text = escape_markdown(text, version=version)
|
||||
|
||||
if nested_entities:
|
||||
if version < 2:
|
||||
raise ValueError('Nested entities are not supported for Markdown '
|
||||
'version 1')
|
||||
|
||||
text = Message._parse_markdown(text, nested_entities,
|
||||
urled=urled, offset=entity.offset,
|
||||
version=version)
|
||||
|
||||
if entity.type == MessageEntity.TEXT_LINK:
|
||||
if version == 1:
|
||||
url = entity.url
|
||||
else:
|
||||
# Links need special escaping. Also can't have entities nested within
|
||||
url = escape_markdown(entity.url, version=version,
|
||||
entity_type=MessageEntity.TEXT_LINK)
|
||||
insert = '[{}]({})'.format(text, url)
|
||||
elif entity.type == MessageEntity.TEXT_MENTION and entity.user:
|
||||
insert = '[{}](tg://user?id={})'.format(text, entity.user.id)
|
||||
elif entity.type == MessageEntity.URL and urled:
|
||||
if version == 1:
|
||||
link = orig_text
|
||||
else:
|
||||
link = text
|
||||
insert = '[{}]({})'.format(link, orig_text)
|
||||
elif entity.type == MessageEntity.BOLD:
|
||||
insert = '*' + text + '*'
|
||||
elif entity.type == MessageEntity.ITALIC:
|
||||
insert = '_' + text + '_'
|
||||
elif entity.type == MessageEntity.CODE:
|
||||
# Monospace needs special escaping. Also can't have entities nested within
|
||||
insert = '`' + escape_markdown(orig_text, version=version,
|
||||
entity_type=MessageEntity.CODE) + '`'
|
||||
elif entity.type == MessageEntity.PRE:
|
||||
# Monospace needs special escaping. Also can't have entities nested within
|
||||
code = escape_markdown(orig_text, version=version,
|
||||
entity_type=MessageEntity.PRE)
|
||||
if code.startswith('\\'):
|
||||
prefix = '```'
|
||||
else:
|
||||
prefix = '```\n'
|
||||
insert = prefix + code + '```'
|
||||
elif entity.type == MessageEntity.UNDERLINE:
|
||||
if version == 1:
|
||||
raise ValueError('Underline entities are not supported for Markdown '
|
||||
'version 1')
|
||||
insert = '__' + text + '__'
|
||||
elif entity.type == MessageEntity.STRIKETHROUGH:
|
||||
if version == 1:
|
||||
raise ValueError('Strikethrough entities are not supported for Markdown '
|
||||
'version 1')
|
||||
insert = '~' + text + '~'
|
||||
else:
|
||||
insert = text
|
||||
|
||||
if offset == 0:
|
||||
if sys.maxunicode == 0xffff:
|
||||
markdown_text += escape_markdown(message_text[last_offset:entity.offset
|
||||
- offset],
|
||||
version=version) + insert
|
||||
else:
|
||||
markdown_text += escape_markdown(message_text[last_offset * 2:
|
||||
(entity.offset - offset) * 2]
|
||||
.decode('utf-16-le'),
|
||||
version=version) + insert
|
||||
else:
|
||||
if sys.maxunicode == 0xffff:
|
||||
markdown_text += message_text[last_offset:entity.offset - offset] + insert
|
||||
else:
|
||||
markdown_text += message_text[last_offset * 2:(entity.offset
|
||||
- offset) * 2].decode('utf-16-le') + insert
|
||||
|
||||
last_offset = entity.offset - offset + entity.length
|
||||
|
||||
if offset == 0:
|
||||
if sys.maxunicode == 0xffff:
|
||||
markdown_text += escape_markdown(message_text[last_offset:entity.offset]) + insert
|
||||
markdown_text += escape_markdown(message_text[last_offset:], version=version)
|
||||
else:
|
||||
markdown_text += escape_markdown(message_text[last_offset * 2:entity.offset * 2]
|
||||
.decode('utf-16-le')) + insert
|
||||
|
||||
last_offset = entity.offset + entity.length
|
||||
|
||||
if sys.maxunicode == 0xffff:
|
||||
markdown_text += escape_markdown(message_text[last_offset:])
|
||||
markdown_text += escape_markdown(message_text[last_offset * 2:]
|
||||
.decode('utf-16-le'), version=version)
|
||||
else:
|
||||
markdown_text += escape_markdown(message_text[last_offset * 2:].decode('utf-16-le'))
|
||||
if sys.maxunicode == 0xffff:
|
||||
markdown_text += message_text[last_offset:]
|
||||
else:
|
||||
markdown_text += message_text[last_offset * 2:].decode('utf-16-le')
|
||||
|
||||
return markdown_text
|
||||
|
||||
@property
|
||||
def text_markdown(self):
|
||||
"""Creates an Markdown-formatted string from the markup entities found in the message.
|
||||
"""Creates an Markdown-formatted string from the markup entities found in the message
|
||||
using :class:`telegram.ParseMode.MARKDOWN`.
|
||||
|
||||
Use this if you want to retrieve the message text with the entities formatted as Markdown
|
||||
in the same way the original message was formatted.
|
||||
|
@ -1167,9 +1301,24 @@ class Message(TelegramObject):
|
|||
"""
|
||||
return self._parse_markdown(self.text, self.parse_entities(), urled=False)
|
||||
|
||||
@property
|
||||
def text_markdown_v2(self):
|
||||
"""Creates an Markdown-formatted string from the markup entities found in the message
|
||||
using :class:`telegram.ParseMode.MARKDOWN_V2`.
|
||||
|
||||
Use this if you want to retrieve the message text with the entities formatted as Markdown
|
||||
in the same way the original message was formatted.
|
||||
|
||||
Returns:
|
||||
:obj:`str`: Message text with entities formatted as Markdown.
|
||||
|
||||
"""
|
||||
return self._parse_markdown(self.text, self.parse_entities(), urled=False, version=2)
|
||||
|
||||
@property
|
||||
def text_markdown_urled(self):
|
||||
"""Creates an Markdown-formatted string from the markup entities found in the message.
|
||||
"""Creates an Markdown-formatted string from the markup entities found in the message
|
||||
using :class:`telegram.ParseMode.MARKDOWN`.
|
||||
|
||||
Use this if you want to retrieve the message text with the entities formatted as Markdown.
|
||||
This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
||||
|
@ -1180,10 +1329,24 @@ class Message(TelegramObject):
|
|||
"""
|
||||
return self._parse_markdown(self.text, self.parse_entities(), urled=True)
|
||||
|
||||
@property
|
||||
def text_markdown_v2_urled(self):
|
||||
"""Creates an Markdown-formatted string from the markup entities found in the message
|
||||
using :class:`telegram.ParseMode.MARKDOWN_V2`.
|
||||
|
||||
Use this if you want to retrieve the message text with the entities formatted as Markdown.
|
||||
This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
||||
|
||||
Returns:
|
||||
:obj:`str`: Message text with entities formatted as Markdown.
|
||||
|
||||
"""
|
||||
return self._parse_markdown(self.text, self.parse_entities(), urled=True, version=2)
|
||||
|
||||
@property
|
||||
def caption_markdown(self):
|
||||
"""Creates an Markdown-formatted string from the markup entities found in the message's
|
||||
caption.
|
||||
caption using :class:`telegram.ParseMode.MARKDOWN`.
|
||||
|
||||
Use this if you want to retrieve the message caption with the caption entities formatted as
|
||||
Markdown in the same way the original message was formatted.
|
||||
|
@ -1194,10 +1357,25 @@ class Message(TelegramObject):
|
|||
"""
|
||||
return self._parse_markdown(self.caption, self.parse_caption_entities(), urled=False)
|
||||
|
||||
@property
|
||||
def caption_markdown_v2(self):
|
||||
"""Creates an Markdown-formatted string from the markup entities found in the message's
|
||||
caption using :class:`telegram.ParseMode.MARKDOWN_V2`.
|
||||
|
||||
Use this if you want to retrieve the message caption with the caption entities formatted as
|
||||
Markdown in the same way the original message was formatted.
|
||||
|
||||
Returns:
|
||||
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
||||
|
||||
"""
|
||||
return self._parse_markdown(self.caption, self.parse_caption_entities(),
|
||||
urled=False, version=2)
|
||||
|
||||
@property
|
||||
def caption_markdown_urled(self):
|
||||
"""Creates an Markdown-formatted string from the markup entities found in the message's
|
||||
caption.
|
||||
caption using :class:`telegram.ParseMode.MARKDOWN`.
|
||||
|
||||
Use this if you want to retrieve the message caption with the caption entities formatted as
|
||||
Markdown. This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
||||
|
@ -1207,3 +1385,18 @@ class Message(TelegramObject):
|
|||
|
||||
"""
|
||||
return self._parse_markdown(self.caption, self.parse_caption_entities(), urled=True)
|
||||
|
||||
@property
|
||||
def caption_markdown_v2_urled(self):
|
||||
"""Creates an Markdown-formatted string from the markup entities found in the message's
|
||||
caption using :class:`telegram.ParseMode.MARKDOWN_V2`.
|
||||
|
||||
Use this if you want to retrieve the message caption with the caption entities formatted as
|
||||
Markdown. This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
||||
|
||||
Returns:
|
||||
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
||||
|
||||
"""
|
||||
return self._parse_markdown(self.caption, self.parse_caption_entities(),
|
||||
urled=True, version=2)
|
||||
|
|
|
@ -105,8 +105,12 @@ class MessageEntity(TelegramObject):
|
|||
""":obj:`str`: 'text_link'"""
|
||||
TEXT_MENTION = 'text_mention'
|
||||
""":obj:`str`: 'text_mention'"""
|
||||
UNDERLINE = 'underline'
|
||||
""":obj:`str`: 'underline'"""
|
||||
STRIKETHROUGH = 'strikethrough'
|
||||
""":obj:`str`: 'strikethrough'"""
|
||||
ALL_TYPES = [
|
||||
MENTION, HASHTAG, CASHTAG, PHONE_NUMBER, BOT_COMMAND, URL,
|
||||
EMAIL, BOLD, ITALIC, CODE, PRE, TEXT_LINK, TEXT_MENTION
|
||||
EMAIL, BOLD, ITALIC, CODE, PRE, TEXT_LINK, TEXT_MENTION, UNDERLINE, STRIKETHROUGH
|
||||
]
|
||||
"""List[:obj:`str`]: List of all the types."""
|
||||
|
|
|
@ -25,5 +25,7 @@ class ParseMode(object):
|
|||
|
||||
MARKDOWN = 'Markdown'
|
||||
""":obj:`str`: 'Markdown'"""
|
||||
MARKDOWN_V2 = 'MarkdownV2'
|
||||
""":obj:`str`: 'MarkdownV2'"""
|
||||
HTML = 'HTML'
|
||||
""":obj:`str`: 'HTML'"""
|
||||
|
|
|
@ -28,12 +28,18 @@ class PassportFile(TelegramObject):
|
|||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`int`): File size.
|
||||
file_date (:obj:`int`): Unix time when the file was uploaded.
|
||||
bot (:class:`telegram.Bot`): Optional. The Bot to use for instance methods.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Unique identifier for this file.
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique and the same over time and
|
||||
for different bots file identifier.
|
||||
file_size (:obj:`int`): File size.
|
||||
file_date (:obj:`int`): Unix time when the file was uploaded.
|
||||
bot (:class:`telegram.Bot`, optional): The Bot to use for instance methods.
|
||||
|
@ -41,16 +47,24 @@ class PassportFile(TelegramObject):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, file_id, file_date, file_size=None, bot=None, credentials=None, **kwargs):
|
||||
def __init__(self,
|
||||
file_id,
|
||||
file_unique_id,
|
||||
file_date,
|
||||
file_size=None,
|
||||
bot=None,
|
||||
credentials=None,
|
||||
**kwargs):
|
||||
# Required
|
||||
self.file_id = file_id
|
||||
self.file_unique_id = file_unique_id
|
||||
self.file_size = file_size
|
||||
self.file_date = file_date
|
||||
# Optionals
|
||||
self.bot = bot
|
||||
self._credentials = credentials
|
||||
|
||||
self._id_attrs = (self.file_id,)
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, bot):
|
||||
|
|
|
@ -131,13 +131,26 @@ class User(TelegramObject):
|
|||
name (:obj:`str`): The name used as a link for the user. Defaults to :attr:`full_name`.
|
||||
|
||||
Returns:
|
||||
:obj:`str`: The inline mention for the user as markdown.
|
||||
:obj:`str`: The inline mention for the user as markdown (version 1).
|
||||
|
||||
"""
|
||||
if name:
|
||||
return util_mention_markdown(self.id, name)
|
||||
return util_mention_markdown(self.id, self.full_name)
|
||||
|
||||
def mention_markdown_v2(self, name=None):
|
||||
"""
|
||||
Args:
|
||||
name (:obj:`str`): The name used as a link for the user. Defaults to :attr:`full_name`.
|
||||
|
||||
Returns:
|
||||
:obj:`str`: The inline mention for the user as markdown (version 2).
|
||||
|
||||
"""
|
||||
if name:
|
||||
return util_mention_markdown(self.id, name, version=2)
|
||||
return util_mention_markdown(self.id, self.full_name, version=2)
|
||||
|
||||
def mention_html(self, name=None):
|
||||
"""
|
||||
Args:
|
||||
|
|
|
@ -44,9 +44,31 @@ def get_signal_name(signum):
|
|||
return _signames[signum]
|
||||
|
||||
|
||||
def escape_markdown(text):
|
||||
"""Helper function to escape telegram markup symbols."""
|
||||
escape_chars = '\*_`\['
|
||||
def escape_markdown(text, version=1, entity_type=None):
|
||||
"""
|
||||
Helper function to escape telegram markup symbols.
|
||||
|
||||
Args:
|
||||
text (:obj:`str`): The text.
|
||||
version (:obj:`int` | :obj:`str`): Use to specify the version of telegrams Markdown.
|
||||
Either ``1`` or ``2``. Defaults to ``1``.
|
||||
entity_type (:obj:`str`, optional): For the entity types ``PRE``, ``CODE`` and the link
|
||||
part of ``TEXT_LINKS``, only certain characters need to be escaped in ``MarkdownV2``.
|
||||
See the official API documentation for details. Only valid in combination with
|
||||
``version=2``, will be ignored else.
|
||||
"""
|
||||
if int(version) == 1:
|
||||
escape_chars = '\*_`\['
|
||||
elif int(version) == 2:
|
||||
if entity_type == 'pre' or entity_type == 'code':
|
||||
escape_chars = '`\\\\'
|
||||
elif entity_type == 'text_link':
|
||||
escape_chars = ')\\\\'
|
||||
else:
|
||||
escape_chars = '_*\[\]()~`>\#\+\-=|{}\.!'
|
||||
else:
|
||||
raise ValueError('Markdown version musst be either 1 or 2!')
|
||||
|
||||
return re.sub(r'([%s])' % escape_chars, r'\\\1', text)
|
||||
|
||||
|
||||
|
@ -207,17 +229,19 @@ def mention_html(user_id, name):
|
|||
return u'<a href="tg://user?id={}">{}</a>'.format(user_id, escape(name))
|
||||
|
||||
|
||||
def mention_markdown(user_id, name):
|
||||
def mention_markdown(user_id, name, version=1):
|
||||
"""
|
||||
Args:
|
||||
user_id (:obj:`int`) The user's id which you want to mention.
|
||||
name (:obj:`str`) The name the mention is showing.
|
||||
version (:obj:`int` | :obj:`str`): Use to specify the version of telegrams Markdown.
|
||||
Either ``1`` or ``2``. Defaults to ``1``
|
||||
|
||||
Returns:
|
||||
:obj:`str`: The inline mention for the user as markdown.
|
||||
"""
|
||||
if isinstance(user_id, int):
|
||||
return u'[{}](tg://user?id={})'.format(escape_markdown(name), user_id)
|
||||
return u'[{}](tg://user?id={})'.format(escape_markdown(name, version=version), user_id)
|
||||
|
||||
|
||||
def effective_message_type(entity):
|
||||
|
|
|
@ -41,6 +41,7 @@ def animation(bot, chat_id):
|
|||
|
||||
class TestAnimation(object):
|
||||
animation_file_id = 'CgADAQADngIAAuyVeEez0xRovKi9VAI'
|
||||
animation_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
|
||||
width = 320
|
||||
height = 180
|
||||
duration = 1
|
||||
|
@ -55,7 +56,9 @@ class TestAnimation(object):
|
|||
def test_creation(self, animation):
|
||||
assert isinstance(animation, Animation)
|
||||
assert isinstance(animation.file_id, str)
|
||||
assert isinstance(animation.file_unique_id, str)
|
||||
assert animation.file_id != ''
|
||||
assert animation.file_unique_id != ''
|
||||
|
||||
def test_expected_values(self, animation):
|
||||
assert animation.file_size == self.file_size
|
||||
|
@ -73,7 +76,9 @@ class TestAnimation(object):
|
|||
|
||||
assert isinstance(message.animation, Animation)
|
||||
assert isinstance(message.animation.file_id, str)
|
||||
assert isinstance(message.animation.file_unique_id, str)
|
||||
assert message.animation.file_id != ''
|
||||
assert message.animation.file_unique_id != ''
|
||||
assert message.animation.file_name == animation.file_name
|
||||
assert message.animation.mime_type == animation.mime_type
|
||||
assert message.animation.file_size == animation.file_size
|
||||
|
@ -103,8 +108,12 @@ class TestAnimation(object):
|
|||
|
||||
assert isinstance(message.animation, Animation)
|
||||
assert isinstance(message.animation.file_id, str)
|
||||
assert message.animation.file_id is not None
|
||||
assert isinstance(message.animation.file_unique_id, str)
|
||||
assert message.animation.file_id != ''
|
||||
assert message.animation.file_unique_id != ''
|
||||
|
||||
assert message.animation.duration == animation.duration
|
||||
assert message.animation.file_name == animation.file_name
|
||||
assert message.animation.mime_type == animation.mime_type
|
||||
assert message.animation.file_size == animation.file_size
|
||||
|
||||
|
@ -143,7 +152,6 @@ class TestAnimation(object):
|
|||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
@pytest.mark.skip(reason='Doesnt work without API 4.5')
|
||||
def test_resend(self, bot, chat_id, animation):
|
||||
message = bot.send_animation(chat_id, animation.file_id)
|
||||
|
||||
|
@ -160,6 +168,7 @@ class TestAnimation(object):
|
|||
def test_de_json(self, bot, animation):
|
||||
json_dict = {
|
||||
'file_id': self.animation_file_id,
|
||||
'file_unique_id': self.animation_file_unique_id,
|
||||
'width': self.width,
|
||||
'height': self.height,
|
||||
'duration': self.duration,
|
||||
|
@ -170,6 +179,7 @@ class TestAnimation(object):
|
|||
}
|
||||
animation = Animation.de_json(json_dict, bot)
|
||||
assert animation.file_id == self.animation_file_id
|
||||
assert animation.file_unique_id == self.animation_file_unique_id
|
||||
assert animation.thumb == animation.thumb
|
||||
assert animation.file_name == self.file_name
|
||||
assert animation.mime_type == self.mime_type
|
||||
|
@ -180,6 +190,7 @@ class TestAnimation(object):
|
|||
|
||||
assert isinstance(animation_dict, dict)
|
||||
assert animation_dict['file_id'] == animation.file_id
|
||||
assert animation_dict['file_unique_id'] == animation.file_unique_id
|
||||
assert animation_dict['width'] == animation.width
|
||||
assert animation_dict['height'] == animation.height
|
||||
assert animation_dict['duration'] == animation.duration
|
||||
|
@ -214,10 +225,12 @@ class TestAnimation(object):
|
|||
assert animation.get_file()
|
||||
|
||||
def test_equality(self):
|
||||
a = Animation(self.animation_file_id, self.height, self.width, self.duration)
|
||||
b = Animation(self.animation_file_id, self.height, self.width, self.duration)
|
||||
d = Animation('', 0, 0, 0)
|
||||
e = Voice(self.animation_file_id, 0)
|
||||
a = Animation(self.animation_file_id, self.animation_file_unique_id,
|
||||
self.height, self.width, self.duration)
|
||||
b = Animation('', self.animation_file_unique_id,
|
||||
self.height, self.width, self.duration)
|
||||
d = Animation('', '', 0, 0, 0)
|
||||
e = Voice(self.animation_file_id, self.animation_file_unique_id, 0)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -52,12 +52,16 @@ class TestAudio(object):
|
|||
thumb_file_size = 1427
|
||||
thumb_width = 50
|
||||
thumb_height = 50
|
||||
audio_file_id = '5a3128a4d2a04750b5b58397f3b5e812'
|
||||
audio_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
|
||||
|
||||
def test_creation(self, audio):
|
||||
# Make sure file has been uploaded.
|
||||
assert isinstance(audio, Audio)
|
||||
assert isinstance(audio.file_id, str)
|
||||
assert isinstance(audio.file_unique_id, str)
|
||||
assert audio.file_id != ''
|
||||
assert audio.file_unique_id != ''
|
||||
|
||||
def test_expected_values(self, audio):
|
||||
assert audio.duration == self.duration
|
||||
|
@ -81,6 +85,8 @@ class TestAudio(object):
|
|||
|
||||
assert isinstance(message.audio, Audio)
|
||||
assert isinstance(message.audio.file_id, str)
|
||||
assert isinstance(message.audio.file_unique_id, str)
|
||||
assert message.audio.file_unique_id is not None
|
||||
assert message.audio.file_id is not None
|
||||
assert message.audio.duration == self.duration
|
||||
assert message.audio.performer == self.performer
|
||||
|
@ -98,6 +104,7 @@ class TestAudio(object):
|
|||
|
||||
assert new_file.file_size == self.file_size
|
||||
assert new_file.file_id == audio.file_id
|
||||
assert new_file.file_unique_id == audio.file_unique_id
|
||||
assert new_file.file_path.startswith('https://')
|
||||
|
||||
new_file.download('telegram.mp3')
|
||||
|
@ -113,6 +120,8 @@ class TestAudio(object):
|
|||
|
||||
assert isinstance(message.audio, Audio)
|
||||
assert isinstance(message.audio.file_id, str)
|
||||
assert isinstance(message.audio.file_unique_id, str)
|
||||
assert message.audio.file_unique_id is not None
|
||||
assert message.audio.file_id is not None
|
||||
assert message.audio.duration == audio.duration
|
||||
assert message.audio.mime_type == audio.mime_type
|
||||
|
@ -120,7 +129,6 @@ class TestAudio(object):
|
|||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
@pytest.mark.skip(reason='Doesnt work without API 4.5')
|
||||
def test_resend(self, bot, chat_id, audio):
|
||||
message = bot.send_audio(chat_id=chat_id, audio=audio.file_id)
|
||||
|
||||
|
@ -168,17 +176,21 @@ class TestAudio(object):
|
|||
assert message.caption_markdown == escape_markdown(test_markdown_string)
|
||||
|
||||
def test_de_json(self, bot, audio):
|
||||
json_dict = {'file_id': 'not a file id',
|
||||
'duration': self.duration,
|
||||
'performer': self.performer,
|
||||
'title': self.title,
|
||||
'caption': self.caption,
|
||||
'mime_type': self.mime_type,
|
||||
'file_size': self.file_size,
|
||||
'thumb': audio.thumb.to_dict()}
|
||||
json_dict = {
|
||||
'file_id': self.audio_file_id,
|
||||
'file_unique_id': self.audio_file_unique_id,
|
||||
'duration': self.duration,
|
||||
'performer': self.performer,
|
||||
'title': self.title,
|
||||
'caption': self.caption,
|
||||
'mime_type': self.mime_type,
|
||||
'file_size': self.file_size,
|
||||
'thumb': audio.thumb.to_dict()
|
||||
}
|
||||
json_audio = Audio.de_json(json_dict, bot)
|
||||
|
||||
assert json_audio.file_id == 'not a file id'
|
||||
assert json_audio.file_id == self.audio_file_id
|
||||
assert json_audio.file_unique_id == self.audio_file_unique_id
|
||||
assert json_audio.duration == self.duration
|
||||
assert json_audio.performer == self.performer
|
||||
assert json_audio.title == self.title
|
||||
|
@ -191,6 +203,7 @@ class TestAudio(object):
|
|||
|
||||
assert isinstance(audio_dict, dict)
|
||||
assert audio_dict['file_id'] == audio.file_id
|
||||
assert audio_dict['file_unique_id'] == audio.file_unique_id
|
||||
assert audio_dict['duration'] == audio.duration
|
||||
assert audio_dict['mime_type'] == audio.mime_type
|
||||
assert audio_dict['file_size'] == audio.file_size
|
||||
|
@ -221,11 +234,11 @@ class TestAudio(object):
|
|||
assert audio.get_file()
|
||||
|
||||
def test_equality(self, audio):
|
||||
a = Audio(audio.file_id, audio.duration)
|
||||
b = Audio(audio.file_id, audio.duration)
|
||||
c = Audio(audio.file_id, 0)
|
||||
d = Audio('', audio.duration)
|
||||
e = Voice(audio.file_id, audio.duration)
|
||||
a = Audio(audio.file_id, audio.file_unique_id, audio.duration)
|
||||
b = Audio('', audio.file_unique_id, audio.duration)
|
||||
c = Audio(audio.file_id, audio.file_unique_id, 0)
|
||||
d = Audio('', '', audio.duration)
|
||||
e = Voice(audio.file_id, audio.file_unique_id, audio.duration)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -349,6 +349,16 @@ class TestBot(object):
|
|||
|
||||
assert bot.set_chat_permissions(2, chat_permissions)
|
||||
|
||||
def test_set_chat_administrator_custom_title(self, monkeypatch, bot):
|
||||
def test(_, url, data, *args, **kwargs):
|
||||
chat_id = data['chat_id'] == 2
|
||||
user_id = data['user_id'] == 32
|
||||
custom_title = data['custom_title'] == 'custom_title'
|
||||
return chat_id and user_id and custom_title
|
||||
|
||||
monkeypatch.setattr('telegram.utils.request.Request.post', test)
|
||||
assert bot.set_chat_administrator_custom_title(2, 32, 'custom_title')
|
||||
|
||||
# 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
|
||||
|
|
|
@ -138,7 +138,7 @@ class TestCallbackQuery(object):
|
|||
b = CallbackQuery(self.id_, self.from_user, 'chat')
|
||||
c = CallbackQuery(self.id_, None, '')
|
||||
d = CallbackQuery('', None, 'chat')
|
||||
e = Audio(self.id_, 1)
|
||||
e = Audio(self.id_, 'unique_id', 1)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -29,7 +29,8 @@ def chat(bot):
|
|||
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,
|
||||
permissions=TestChat.permissions)
|
||||
permissions=TestChat.permissions,
|
||||
slow_mode_delay=TestChat.slow_mode_delay)
|
||||
|
||||
|
||||
class TestChat(object):
|
||||
|
@ -45,6 +46,7 @@ class TestChat(object):
|
|||
can_change_info=False,
|
||||
can_invite_users=True,
|
||||
)
|
||||
slow_mode_delay = 30
|
||||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
|
@ -55,7 +57,8 @@ class TestChat(object):
|
|||
'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,
|
||||
'permissions': self.permissions.to_dict()
|
||||
'permissions': self.permissions.to_dict(),
|
||||
'slow_mode_delay': self.slow_mode_delay
|
||||
}
|
||||
chat = Chat.de_json(json_dict, bot)
|
||||
|
||||
|
@ -67,6 +70,7 @@ class TestChat(object):
|
|||
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
|
||||
assert chat.slow_mode_delay == self.slow_mode_delay
|
||||
|
||||
def test_de_json_default_quote(self, bot):
|
||||
json_dict = {
|
||||
|
@ -94,6 +98,7 @@ class TestChat(object):
|
|||
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()
|
||||
assert chat_dict['slow_mode_delay'] == chat.slow_mode_delay
|
||||
|
||||
def test_link(self, chat):
|
||||
assert chat.link == 'https://t.me/{}'.format(chat.username)
|
||||
|
@ -167,6 +172,16 @@ class TestChat(object):
|
|||
monkeypatch.setattr(chat.bot, 'set_chat_permissions', test)
|
||||
assert chat.set_permissions(self.permissions)
|
||||
|
||||
def test_set_administrator_custom_title(self, monkeypatch, chat):
|
||||
def test(*args, **kwargs):
|
||||
chat_id = args[1] == chat.id
|
||||
user_id = args[2] == 42
|
||||
custom_title = args[3] == 'custom_title'
|
||||
return chat_id and user_id and custom_title
|
||||
|
||||
monkeypatch.setattr('telegram.Bot.set_chat_administrator_custom_title', test)
|
||||
assert chat.set_administrator_custom_title(42, 'custom_title')
|
||||
|
||||
def test_instance_method_send_message(self, monkeypatch, chat):
|
||||
def test(*args, **kwargs):
|
||||
return args[0] == chat.id and args[1] == 'test'
|
||||
|
|
|
@ -47,8 +47,11 @@ class TestChatMember(object):
|
|||
|
||||
def test_de_json_all_args(self, bot, user):
|
||||
time = datetime.datetime.utcnow()
|
||||
custom_title = 'custom_title'
|
||||
|
||||
json_dict = {'user': user.to_dict(),
|
||||
'status': self.status,
|
||||
'custom_title': custom_title,
|
||||
'until_date': to_timestamp(time),
|
||||
'can_be_edited': False,
|
||||
'can_change_info': True,
|
||||
|
@ -69,6 +72,7 @@ class TestChatMember(object):
|
|||
|
||||
assert chat_member.user == user
|
||||
assert chat_member.status == self.status
|
||||
assert chat_member.custom_title == custom_title
|
||||
assert chat_member.can_be_edited is False
|
||||
assert chat_member.can_change_info is True
|
||||
assert chat_member.can_post_messages is False
|
||||
|
|
155
tests/test_chatphoto.py
Normal file
155
tests/test_chatphoto.py
Normal file
|
@ -0,0 +1,155 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2020
|
||||
# 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 os
|
||||
import pytest
|
||||
from flaky import flaky
|
||||
|
||||
from telegram import ChatPhoto, Voice, TelegramError
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def chatphoto_file():
|
||||
f = open('tests/data/telegram.jpg', 'rb')
|
||||
yield f
|
||||
f.close()
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def chat_photo(bot, super_group_id):
|
||||
return bot.get_chat(super_group_id, timeout=50).photo
|
||||
|
||||
|
||||
class TestChatPhoto(object):
|
||||
chatphoto_small_file_id = 'smallCgADAQADngIAAuyVeEez0xRovKi9VAI'
|
||||
chatphoto_big_file_id = 'bigCgADAQADngIAAuyVeEez0xRovKi9VAI'
|
||||
chatphoto_small_file_unique_id = 'smalladc3145fd2e84d95b64d68eaa22aa33e'
|
||||
chatphoto_big_file_unique_id = 'bigadc3145fd2e84d95b64d68eaa22aa33e'
|
||||
chatphoto_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.jpg'
|
||||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
def test_send_all_args(self, bot, super_group_id, chatphoto_file, chat_photo, thumb_file):
|
||||
assert bot.set_chat_photo(super_group_id, chatphoto_file)
|
||||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
def test_get_and_download(self, bot, chat_photo):
|
||||
new_file = bot.get_file(chat_photo.small_file_id)
|
||||
|
||||
assert new_file.file_id == chat_photo.small_file_id
|
||||
assert new_file.file_path.startswith('https://')
|
||||
|
||||
new_file.download('telegram.jpg')
|
||||
|
||||
assert os.path.isfile('telegram.jpg')
|
||||
|
||||
new_file = bot.get_file(chat_photo.big_file_id)
|
||||
|
||||
assert new_file.file_id == chat_photo.big_file_id
|
||||
assert new_file.file_path.startswith('https://')
|
||||
|
||||
new_file.download('telegram.jpg')
|
||||
|
||||
assert os.path.isfile('telegram.jpg')
|
||||
|
||||
def test_send_with_chat_photo(self, monkeypatch, bot, super_group_id, chat_photo):
|
||||
def test(_, url, data, **kwargs):
|
||||
return data['photo'] == chat_photo
|
||||
|
||||
monkeypatch.setattr('telegram.utils.request.Request.post', test)
|
||||
message = bot.set_chat_photo(photo=chat_photo, chat_id=super_group_id)
|
||||
assert message
|
||||
|
||||
def test_de_json(self, bot, chat_photo):
|
||||
json_dict = {
|
||||
'small_file_id': self.chatphoto_small_file_id,
|
||||
'big_file_id': self.chatphoto_big_file_id,
|
||||
'small_file_unique_id': self.chatphoto_small_file_unique_id,
|
||||
'big_file_unique_id': self.chatphoto_big_file_unique_id,
|
||||
}
|
||||
chat_photo = ChatPhoto.de_json(json_dict, bot)
|
||||
assert chat_photo.small_file_id == self.chatphoto_small_file_id
|
||||
assert chat_photo.big_file_id == self.chatphoto_big_file_id
|
||||
assert chat_photo.small_file_unique_id == self.chatphoto_small_file_unique_id
|
||||
assert chat_photo.big_file_unique_id == self.chatphoto_big_file_unique_id
|
||||
|
||||
def test_to_dict(self, chat_photo):
|
||||
chat_photo_dict = chat_photo.to_dict()
|
||||
|
||||
assert isinstance(chat_photo_dict, dict)
|
||||
assert chat_photo_dict['small_file_id'] == chat_photo.small_file_id
|
||||
assert chat_photo_dict['big_file_id'] == chat_photo.big_file_id
|
||||
assert chat_photo_dict['small_file_unique_id'] == chat_photo.small_file_unique_id
|
||||
assert chat_photo_dict['big_file_unique_id'] == chat_photo.big_file_unique_id
|
||||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
def test_error_send_empty_file(self, bot, super_group_id):
|
||||
chatphoto_file = open(os.devnull, 'rb')
|
||||
|
||||
with pytest.raises(TelegramError):
|
||||
bot.set_chat_photo(chat_id=super_group_id, photo=chatphoto_file)
|
||||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
def test_error_send_empty_file_id(self, bot, super_group_id):
|
||||
with pytest.raises(TelegramError):
|
||||
bot.set_chat_photo(chat_id=super_group_id, photo='')
|
||||
|
||||
def test_error_send_without_required_args(self, bot, super_group_id):
|
||||
with pytest.raises(TypeError):
|
||||
bot.set_chat_photo(chat_id=super_group_id)
|
||||
|
||||
def test_get_small_file_instance_method(self, monkeypatch, chat_photo):
|
||||
def test(*args, **kwargs):
|
||||
return args[1] == chat_photo.small_file_id
|
||||
|
||||
monkeypatch.setattr('telegram.Bot.get_file', test)
|
||||
assert chat_photo.get_small_file()
|
||||
|
||||
def test_get_big_file_instance_method(self, monkeypatch, chat_photo):
|
||||
def test(*args, **kwargs):
|
||||
return args[1] == chat_photo.big_file_id
|
||||
|
||||
monkeypatch.setattr('telegram.Bot.get_file', test)
|
||||
assert chat_photo.get_big_file()
|
||||
|
||||
def test_equality(self):
|
||||
a = ChatPhoto(self.chatphoto_small_file_id, self.chatphoto_big_file_id,
|
||||
self.chatphoto_small_file_unique_id, self.chatphoto_big_file_unique_id)
|
||||
b = ChatPhoto(self.chatphoto_small_file_id, self.chatphoto_big_file_id,
|
||||
self.chatphoto_small_file_unique_id, self.chatphoto_big_file_unique_id)
|
||||
c = ChatPhoto('', '', self.chatphoto_small_file_unique_id,
|
||||
self.chatphoto_big_file_unique_id)
|
||||
d = ChatPhoto('', '', 0, 0)
|
||||
e = Voice(self.chatphoto_small_file_id, self.chatphoto_small_file_unique_id, 0)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
assert a is not b
|
||||
|
||||
assert a != c
|
||||
assert hash(a) != hash(c)
|
||||
|
||||
assert a != d
|
||||
assert hash(a) != hash(d)
|
||||
|
||||
assert a != e
|
||||
assert hash(a) != hash(e)
|
|
@ -74,7 +74,7 @@ class TestChosenInlineResult(object):
|
|||
b = ChosenInlineResult(self.result_id, user, 'Query', '')
|
||||
c = ChosenInlineResult(self.result_id, user, '', '')
|
||||
d = ChosenInlineResult('', user, 'Query', '')
|
||||
e = Voice(self.result_id, 0)
|
||||
e = Voice(self.result_id, 'unique_id', 0)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -80,7 +80,7 @@ class TestContact(object):
|
|||
b = Contact(self.phone_number, self.first_name)
|
||||
c = Contact(self.phone_number, '')
|
||||
d = Contact('', self.first_name)
|
||||
e = Voice('', 0)
|
||||
e = Voice('', 'unique_id', 0)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -47,11 +47,15 @@ class TestDocument(object):
|
|||
thumb_file_size = 8090
|
||||
thumb_width = 300
|
||||
thumb_height = 300
|
||||
document_file_id = '5a3128a4d2a04750b5b58397f3b5e812'
|
||||
document_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
|
||||
|
||||
def test_creation(self, document):
|
||||
assert isinstance(document, Document)
|
||||
assert isinstance(document.file_id, str)
|
||||
assert isinstance(document.file_unique_id, str)
|
||||
assert document.file_id != ''
|
||||
assert document.file_unique_id != ''
|
||||
|
||||
def test_expected_values(self, document):
|
||||
assert document.file_size == self.file_size
|
||||
|
@ -71,6 +75,8 @@ class TestDocument(object):
|
|||
assert isinstance(message.document, Document)
|
||||
assert isinstance(message.document.file_id, str)
|
||||
assert message.document.file_id != ''
|
||||
assert isinstance(message.document.file_unique_id, str)
|
||||
assert message.document.file_unique_id != ''
|
||||
assert isinstance(message.document.thumb, PhotoSize)
|
||||
assert message.document.file_name == 'telegram_custom.png'
|
||||
assert message.document.mime_type == document.mime_type
|
||||
|
@ -86,6 +92,7 @@ class TestDocument(object):
|
|||
|
||||
assert new_file.file_size == document.file_size
|
||||
assert new_file.file_id == document.file_id
|
||||
assert new_file.file_unique_id == document.file_unique_id
|
||||
assert new_file.file_path.startswith('https://')
|
||||
|
||||
new_file.download('telegram.png')
|
||||
|
@ -102,6 +109,8 @@ class TestDocument(object):
|
|||
assert isinstance(document, Document)
|
||||
assert isinstance(document.file_id, str)
|
||||
assert document.file_id != ''
|
||||
assert isinstance(message.document.file_unique_id, str)
|
||||
assert message.document.file_unique_id != ''
|
||||
assert isinstance(document.thumb, PhotoSize)
|
||||
assert document.file_name == 'telegram.gif'
|
||||
assert document.mime_type == 'image/gif'
|
||||
|
@ -109,7 +118,6 @@ class TestDocument(object):
|
|||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
@pytest.mark.skip(reason='Doesnt work without API 4.5')
|
||||
def test_send_resend(self, bot, chat_id, document):
|
||||
message = bot.send_document(chat_id=chat_id, document=document.file_id)
|
||||
|
||||
|
@ -159,15 +167,18 @@ class TestDocument(object):
|
|||
assert message.caption_markdown == escape_markdown(test_markdown_string)
|
||||
|
||||
def test_de_json(self, bot, document):
|
||||
json_dict = {'file_id': 'not a file id',
|
||||
'thumb': document.thumb.to_dict(),
|
||||
'file_name': self.file_name,
|
||||
'mime_type': self.mime_type,
|
||||
'file_size': self.file_size
|
||||
}
|
||||
json_dict = {
|
||||
'file_id': self.document_file_id,
|
||||
'file_unique_id': self.document_file_unique_id,
|
||||
'thumb': document.thumb.to_dict(),
|
||||
'file_name': self.file_name,
|
||||
'mime_type': self.mime_type,
|
||||
'file_size': self.file_size
|
||||
}
|
||||
test_document = Document.de_json(json_dict, bot)
|
||||
|
||||
assert test_document.file_id == 'not a file id'
|
||||
assert test_document.file_id == self.document_file_id
|
||||
assert test_document.file_unique_id == self.document_file_unique_id
|
||||
assert test_document.thumb == document.thumb
|
||||
assert test_document.file_name == self.file_name
|
||||
assert test_document.mime_type == self.mime_type
|
||||
|
@ -178,6 +189,7 @@ class TestDocument(object):
|
|||
|
||||
assert isinstance(document_dict, dict)
|
||||
assert document_dict['file_id'] == document.file_id
|
||||
assert document_dict['file_unique_id'] == document.file_unique_id
|
||||
assert document_dict['file_name'] == document.file_name
|
||||
assert document_dict['mime_type'] == document.mime_type
|
||||
assert document_dict['file_size'] == document.file_size
|
||||
|
@ -207,10 +219,10 @@ class TestDocument(object):
|
|||
assert document.get_file()
|
||||
|
||||
def test_equality(self, document):
|
||||
a = Document(document.file_id)
|
||||
b = Document(document.file_id)
|
||||
d = Document('')
|
||||
e = Voice(document.file_id, 0)
|
||||
a = Document(document.file_id, document.file_unique_id)
|
||||
b = Document('', document.file_unique_id)
|
||||
d = Document('', '')
|
||||
e = Voice(document.file_id, document.file_unique_id, 0)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -29,6 +29,7 @@ from telegram import File, TelegramError, Voice
|
|||
@pytest.fixture(scope='class')
|
||||
def file(bot):
|
||||
return File(TestFile.file_id,
|
||||
TestFile.file_unique_id,
|
||||
file_path=TestFile.file_path,
|
||||
file_size=TestFile.file_size,
|
||||
bot=bot)
|
||||
|
@ -36,6 +37,7 @@ def file(bot):
|
|||
|
||||
class TestFile(object):
|
||||
file_id = 'NOTVALIDDOESNOTMATTER'
|
||||
file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
|
||||
file_path = (
|
||||
u'https://api.org/file/bot133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0/document/file_3')
|
||||
file_size = 28232
|
||||
|
@ -44,12 +46,14 @@ class TestFile(object):
|
|||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
'file_id': self.file_id,
|
||||
'file_unique_id': self.file_unique_id,
|
||||
'file_path': self.file_path,
|
||||
'file_size': self.file_size
|
||||
}
|
||||
new_file = File.de_json(json_dict, bot)
|
||||
|
||||
assert new_file.file_id == self.file_id
|
||||
assert new_file.file_unique_id == self.file_unique_id
|
||||
assert new_file.file_path == self.file_path
|
||||
assert new_file.file_size == self.file_size
|
||||
|
||||
|
@ -58,6 +62,7 @@ class TestFile(object):
|
|||
|
||||
assert isinstance(file_dict, dict)
|
||||
assert file_dict['file_id'] == file.file_id
|
||||
assert file_dict['file_unique_id'] == file.file_unique_id
|
||||
assert file_dict['file_path'] == file.file_path
|
||||
assert file_dict['file_size'] == file.file_size
|
||||
|
||||
|
@ -142,11 +147,11 @@ class TestFile(object):
|
|||
assert buf2[:len(buf)] == buf
|
||||
|
||||
def test_equality(self, bot):
|
||||
a = File(self.file_id, bot)
|
||||
b = File(self.file_id, bot)
|
||||
c = File(self.file_id, None)
|
||||
d = File('', bot)
|
||||
e = Voice(self.file_id, 0)
|
||||
a = File(self.file_id, self.file_unique_id, bot)
|
||||
b = File('', self.file_unique_id, bot)
|
||||
c = File(self.file_id, self.file_unique_id, None)
|
||||
d = File('', '', bot)
|
||||
e = Voice(self.file_id, self.file_unique_id, 0)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -300,7 +300,7 @@ class TestFilters(object):
|
|||
assert Filters.document(update)
|
||||
|
||||
def test_filters_document_type(self, update):
|
||||
update.message.document = Document("file_id",
|
||||
update.message.document = Document("file_id", 'unique_id',
|
||||
mime_type="application/vnd.android.package-archive")
|
||||
assert Filters.document.apk(update)
|
||||
assert Filters.document.application(update)
|
||||
|
|
|
@ -35,11 +35,11 @@ def game():
|
|||
class TestGame(object):
|
||||
title = 'Python-telegram-bot Test Game'
|
||||
description = 'description'
|
||||
photo = [PhotoSize('Blah', 640, 360, file_size=0)]
|
||||
photo = [PhotoSize('Blah', 'ElseBlah', 640, 360, file_size=0)]
|
||||
text = (b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467'
|
||||
b'\\u200d\\U0001f467\\U0001f431http://google.com').decode('unicode-escape')
|
||||
text_entities = [MessageEntity(13, 17, MessageEntity.URL)]
|
||||
animation = Animation('blah', 320, 180, 1)
|
||||
animation = Animation('blah', 'unique_id', 320, 180, 1)
|
||||
|
||||
def test_de_json_required(self, bot):
|
||||
json_dict = {
|
||||
|
|
|
@ -24,6 +24,7 @@ import pytest
|
|||
from telegram import Sticker
|
||||
from telegram import Update
|
||||
from telegram import User
|
||||
from telegram import MessageEntity
|
||||
from telegram.message import Message
|
||||
from telegram.utils import helpers
|
||||
from telegram.utils.helpers import _UtcOffsetTimezone, _datetime_to_float_timestamp
|
||||
|
@ -46,6 +47,34 @@ class TestHelpers(object):
|
|||
|
||||
assert expected_str == helpers.escape_markdown(test_str)
|
||||
|
||||
def test_escape_markdown_v2(self):
|
||||
test_str = 'a_b*c[d]e (fg) h~I`>JK#L+MN -O=|p{qr}s.t! u'
|
||||
expected_str = 'a\_b\*c\[d\]e \(fg\) h\~I\`\>JK\#L\+MN \-O\=\|p\{qr\}s\.t\! u'
|
||||
|
||||
assert expected_str == helpers.escape_markdown(test_str, version=2)
|
||||
|
||||
def test_escape_markdown_v2_monospaced(self):
|
||||
|
||||
test_str = 'mono/pre: `abc` \int (`\some \`stuff)'
|
||||
expected_str = 'mono/pre: \`abc\` \\\\int (\`\\\\some \\\\\`stuff)'
|
||||
|
||||
assert expected_str == helpers.escape_markdown(test_str, version=2,
|
||||
entity_type=MessageEntity.PRE)
|
||||
assert expected_str == helpers.escape_markdown(test_str, version=2,
|
||||
entity_type=MessageEntity.CODE)
|
||||
|
||||
def test_escape_markdown_v2_text_link(self):
|
||||
|
||||
test_str = 'https://url.containing/funny)cha)\\ra\)cter\s'
|
||||
expected_str = 'https://url.containing/funny\)cha\)\\\\ra\\\\\)cter\\\\s'
|
||||
|
||||
assert expected_str == helpers.escape_markdown(test_str, version=2,
|
||||
entity_type=MessageEntity.TEXT_LINK)
|
||||
|
||||
def test_markdown_invalid_version(self):
|
||||
with pytest.raises(ValueError):
|
||||
helpers.escape_markdown('abc', version=-1)
|
||||
|
||||
def test_to_float_timestamp_absolute_naive(self):
|
||||
"""Conversion from timezone-naive datetime to timestamp.
|
||||
Naive datetimes should be assumed to be in UTC.
|
||||
|
@ -161,7 +190,8 @@ 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, False))
|
||||
test_message = build_test_message(sticker=Sticker('sticker_id', 'unique_id',
|
||||
50, 50, False))
|
||||
assert helpers.effective_message_type(test_message) == 'sticker'
|
||||
test_message.sticker = None
|
||||
|
||||
|
@ -188,3 +218,8 @@ class TestHelpers(object):
|
|||
expected = '[the name](tg://user?id=1)'
|
||||
|
||||
assert expected == helpers.mention_markdown(1, 'the name')
|
||||
|
||||
def test_mention_markdown_2(self):
|
||||
expected = r'[the\_name](tg://user?id=1)'
|
||||
|
||||
assert expected == helpers.mention_markdown(1, 'the_name')
|
||||
|
|
|
@ -47,21 +47,21 @@ def message(bot):
|
|||
{'caption': 'A message caption',
|
||||
'caption_entities': [MessageEntity('bold', 1, 1),
|
||||
MessageEntity('text_link', 4, 3)]},
|
||||
{'audio': Audio('audio_id', 12),
|
||||
{'audio': Audio('audio_id', 'unique_id', 12),
|
||||
'caption': 'audio_file'},
|
||||
{'document': Document('document_id'),
|
||||
{'document': Document('document_id', 'unique_id'),
|
||||
'caption': 'document_file'},
|
||||
{'animation': Animation('animation_id', 30, 30, 1),
|
||||
{'animation': Animation('animation_id', 'unique_id', 30, 30, 1),
|
||||
'caption': 'animation_file'},
|
||||
{'game': Game('my_game', 'just my game',
|
||||
[PhotoSize('game_photo_id', 30, 30), ])},
|
||||
{'photo': [PhotoSize('photo_id', 50, 50)],
|
||||
[PhotoSize('game_photo_id', 'unique_id', 30, 30), ])},
|
||||
{'photo': [PhotoSize('photo_id', 'unique_id', 50, 50)],
|
||||
'caption': 'photo_file'},
|
||||
{'sticker': Sticker('sticker_id', 50, 50, True)},
|
||||
{'video': Video('video_id', 12, 12, 12),
|
||||
{'sticker': Sticker('sticker_id', 'unique_id', 50, 50, True)},
|
||||
{'video': Video('video_id', 'unique_id', 12, 12, 12),
|
||||
'caption': 'video_file'},
|
||||
{'voice': Voice('voice_id', 5)},
|
||||
{'video_note': VideoNote('video_note_id', 20, 12)},
|
||||
{'voice': Voice('voice_id', 'unique_id', 5)},
|
||||
{'video_note': VideoNote('video_note_id', 'unique_id', 20, 12)},
|
||||
{'new_chat_members': [User(55, 'new_user', False)]},
|
||||
{'contact': Contact('phone_numner', 'contact_name')},
|
||||
{'location': Location(-23.691288, 46.788279)},
|
||||
|
@ -69,7 +69,7 @@ def message(bot):
|
|||
'some place', 'right here')},
|
||||
{'left_chat_member': User(33, 'kicked', False)},
|
||||
{'new_chat_title': 'new title'},
|
||||
{'new_chat_photo': [PhotoSize('photo_id', 50, 50)]},
|
||||
{'new_chat_photo': [PhotoSize('photo_id', 'unique_id', 50, 50)]},
|
||||
{'delete_chat_photo': True},
|
||||
{'group_chat_created': True},
|
||||
{'supergroup_chat_created': True},
|
||||
|
@ -84,7 +84,7 @@ def message(bot):
|
|||
{'connected_website': 'http://example.com/'},
|
||||
{'forward_signature': 'some_forward_sign'},
|
||||
{'author_signature': 'some_author_sign'},
|
||||
{'photo': [PhotoSize('photo_id', 50, 50)],
|
||||
{'photo': [PhotoSize('photo_id', 'unique_id', 50, 50)],
|
||||
'caption': 'photo_file',
|
||||
'media_group_id': 1234443322222},
|
||||
{'passport_data': PassportData.de_json(RAW_PASSPORT_DATA, None)},
|
||||
|
@ -119,14 +119,31 @@ class TestMessage(object):
|
|||
date = datetime.utcnow()
|
||||
chat = Chat(3, 'private')
|
||||
test_entities = [{'length': 4, 'offset': 10, 'type': 'bold'},
|
||||
{'length': 7, 'offset': 16, 'type': 'italic'},
|
||||
{'length': 3, 'offset': 16, 'type': 'italic'},
|
||||
{'length': 3, 'offset': 20, 'type': 'italic'},
|
||||
{'length': 4, 'offset': 25, 'type': 'code'},
|
||||
{'length': 5, 'offset': 31, 'type': 'text_link', 'url': 'http://github.com/'},
|
||||
{'length': 5, 'offset': 31, 'type': 'text_link',
|
||||
'url': 'http://github.com/ab_'},
|
||||
{'length': 12, 'offset': 38, 'type': 'text_mention',
|
||||
'user': User(123456789, 'mentioned user', False)},
|
||||
{'length': 3, 'offset': 55, 'type': 'pre'},
|
||||
{'length': 17, 'offset': 60, 'type': 'url'}]
|
||||
test_text = 'Test for <bold, ita_lic, code, links, text-mention and pre. http://google.com'
|
||||
{'length': 21, 'offset': 60, 'type': 'url'}]
|
||||
test_text = 'Test for <bold, ita_lic, code, links, text-mention and pre. http://google.com/ab_'
|
||||
test_entities_v2 = [{'length': 4, 'offset': 0, 'type': 'underline'},
|
||||
{'length': 4, 'offset': 10, 'type': 'bold'},
|
||||
{'length': 7, 'offset': 16, 'type': 'italic'},
|
||||
{'length': 6, 'offset': 25, 'type': 'code'},
|
||||
{'length': 5, 'offset': 33, 'type': 'text_link',
|
||||
'url': 'http://github.com/abc\)def'},
|
||||
{'length': 12, 'offset': 40, 'type': 'text_mention',
|
||||
'user': User(123456789, 'mentioned user', False)},
|
||||
{'length': 5, 'offset': 57, 'type': 'pre'},
|
||||
{'length': 17, 'offset': 64, 'type': 'url'},
|
||||
{'length': 36, 'offset': 86, 'type': 'italic'},
|
||||
{'length': 24, 'offset': 91, 'type': 'bold'},
|
||||
{'length': 4, 'offset': 101, 'type': 'strikethrough'}]
|
||||
test_text_v2 = ('Test for <bold, ita_lic, \`code, links, text-mention and `\pre. '
|
||||
'http://google.com and bold nested in strk nested in italic.')
|
||||
test_message = Message(message_id=1,
|
||||
from_user=None,
|
||||
date=None,
|
||||
|
@ -135,6 +152,16 @@ class TestMessage(object):
|
|||
entities=[MessageEntity(**e) for e in test_entities],
|
||||
caption=test_text,
|
||||
caption_entities=[MessageEntity(**e) for e in test_entities])
|
||||
test_message_v2 = Message(message_id=1,
|
||||
from_user=None,
|
||||
date=None,
|
||||
chat=None,
|
||||
text=test_text_v2,
|
||||
entities=[MessageEntity(**e) for e in test_entities_v2],
|
||||
caption=test_text_v2,
|
||||
caption_entities=[
|
||||
MessageEntity(**e) for e in test_entities_v2
|
||||
])
|
||||
|
||||
def test_all_posibilities_de_json_and_to_dict(self, bot, message_params):
|
||||
new = Message.de_json(message_params.to_dict(), bot)
|
||||
|
@ -182,11 +209,12 @@ class TestMessage(object):
|
|||
assert message.parse_caption_entities() == {entity: 'http://google.com', entity_2: 'h'}
|
||||
|
||||
def test_text_html_simple(self):
|
||||
test_html_string = ('Test for <<b>bold</b>, <i>ita_lic</i>, <code>code</code>, '
|
||||
'<a href="http://github.com/">links</a>, '
|
||||
test_html_string = ('<u>Test</u> for <<b>bold</b>, <i>ita_lic</i>, <code>\`code</code>,'
|
||||
' <a href="http://github.com/abc\)def">links</a>, '
|
||||
'<a href="tg://user?id=123456789">text-mention</a> and '
|
||||
'<pre>pre</pre>. http://google.com')
|
||||
text_html = self.test_message.text_html
|
||||
'<pre>`\pre</pre>. http://google.com '
|
||||
'and <i>bold <b>nested in <s>strk</s> nested in</b> italic</i>.')
|
||||
text_html = self.test_message_v2.text_html
|
||||
assert text_html == test_html_string
|
||||
|
||||
def test_text_html_empty(self, message):
|
||||
|
@ -195,32 +223,68 @@ class TestMessage(object):
|
|||
assert message.text_html is None
|
||||
|
||||
def test_text_html_urled(self):
|
||||
test_html_string = ('Test for <<b>bold</b>, <i>ita_lic</i>, <code>code</code>, '
|
||||
'<a href="http://github.com/">links</a>, '
|
||||
test_html_string = ('<u>Test</u> for <<b>bold</b>, <i>ita_lic</i>, <code>\`code</code>,'
|
||||
' <a href="http://github.com/abc\)def">links</a>, '
|
||||
'<a href="tg://user?id=123456789">text-mention</a> and '
|
||||
'<pre>pre</pre>. <a href="http://google.com">http://google.com</a>')
|
||||
text_html = self.test_message.text_html_urled
|
||||
'<pre>`\pre</pre>. <a href="http://google.com">http://google.com</a> '
|
||||
'and <i>bold <b>nested in <s>strk</s> nested in</b> italic</i>.')
|
||||
text_html = self.test_message_v2.text_html_urled
|
||||
assert text_html == test_html_string
|
||||
|
||||
def test_text_markdown_simple(self):
|
||||
test_md_string = (r'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/), '
|
||||
'[text-mention](tg://user?id=123456789) and ```pre```. '
|
||||
'http://google.com')
|
||||
test_md_string = ('Test for <*bold*, _ita_\__lic_, `code`, [links](http://github.com/ab_),'
|
||||
' [text-mention](tg://user?id=123456789) and ```\npre```. '
|
||||
'http://google.com/ab\_')
|
||||
text_markdown = self.test_message.text_markdown
|
||||
assert text_markdown == test_md_string
|
||||
|
||||
def test_text_markdown_v2_simple(self):
|
||||
test_md_string = (r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, '
|
||||
'[links](http://github.com/abc\\\\\)def), '
|
||||
'[text\-mention](tg://user?id=123456789) and ```\`\\\\pre```\. '
|
||||
'http://google\.com and _bold *nested in ~strk~ nested in* italic_\.')
|
||||
text_markdown = self.test_message_v2.text_markdown_v2
|
||||
assert text_markdown == test_md_string
|
||||
|
||||
def test_text_markdown_new_in_v2(self, message):
|
||||
message.text = 'test'
|
||||
message.entities = [MessageEntity(MessageEntity.BOLD, offset=0, length=4),
|
||||
MessageEntity(MessageEntity.ITALIC, offset=0, length=4)]
|
||||
with pytest.raises(ValueError):
|
||||
assert message.text_markdown
|
||||
|
||||
message.entities = [MessageEntity(MessageEntity.UNDERLINE, offset=0, length=4)]
|
||||
with pytest.raises(ValueError):
|
||||
message.text_markdown
|
||||
|
||||
message.entities = [MessageEntity(MessageEntity.STRIKETHROUGH, offset=0, length=4)]
|
||||
with pytest.raises(ValueError):
|
||||
message.text_markdown
|
||||
|
||||
message.entities = []
|
||||
|
||||
def test_text_markdown_empty(self, message):
|
||||
message.text = None
|
||||
message.caption = "test"
|
||||
assert message.text_markdown is None
|
||||
assert message.text_markdown_v2 is None
|
||||
|
||||
def test_text_markdown_urled(self):
|
||||
test_md_string = (r'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/), '
|
||||
'[text-mention](tg://user?id=123456789) and ```pre```. '
|
||||
'[http://google.com](http://google.com)')
|
||||
test_md_string = ('Test for <*bold*, _ita_\__lic_, `code`, [links](http://github.com/ab_),'
|
||||
' [text-mention](tg://user?id=123456789) and ```\npre```. '
|
||||
'[http://google.com/ab_](http://google.com/ab_)')
|
||||
text_markdown = self.test_message.text_markdown_urled
|
||||
assert text_markdown == test_md_string
|
||||
|
||||
def test_text_markdown_v2_urled(self):
|
||||
test_md_string = (r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, '
|
||||
'[links](http://github.com/abc\\\\\)def), '
|
||||
'[text\-mention](tg://user?id=123456789) and ```\`\\\\pre```\. '
|
||||
'[http://google\.com](http://google.com) and _bold *nested in ~strk~ '
|
||||
'nested in* italic_\.')
|
||||
text_markdown = self.test_message_v2.text_markdown_v2_urled
|
||||
assert text_markdown == test_md_string
|
||||
|
||||
def test_text_html_emoji(self):
|
||||
text = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape')
|
||||
expected = b'\\U0001f469\\u200d\\U0001f469\\u200d <b>ABC</b>'.decode('unicode-escape')
|
||||
|
@ -238,11 +302,12 @@ class TestMessage(object):
|
|||
assert expected == message.text_markdown
|
||||
|
||||
def test_caption_html_simple(self):
|
||||
test_html_string = ('Test for <<b>bold</b>, <i>ita_lic</i>, <code>code</code>, '
|
||||
'<a href="http://github.com/">links</a>, '
|
||||
test_html_string = ('<u>Test</u> for <<b>bold</b>, <i>ita_lic</i>, <code>\`code</code>,'
|
||||
' <a href="http://github.com/abc\)def">links</a>, '
|
||||
'<a href="tg://user?id=123456789">text-mention</a> and '
|
||||
'<pre>pre</pre>. http://google.com')
|
||||
caption_html = self.test_message.caption_html
|
||||
'<pre>`\pre</pre>. http://google.com '
|
||||
'and <i>bold <b>nested in <s>strk</s> nested in</b> italic</i>.')
|
||||
caption_html = self.test_message_v2.caption_html
|
||||
assert caption_html == test_html_string
|
||||
|
||||
def test_caption_html_empty(self, message):
|
||||
|
@ -251,32 +316,51 @@ class TestMessage(object):
|
|||
assert message.caption_html is None
|
||||
|
||||
def test_caption_html_urled(self):
|
||||
test_html_string = ('Test for <<b>bold</b>, <i>ita_lic</i>, <code>code</code>, '
|
||||
'<a href="http://github.com/">links</a>, '
|
||||
test_html_string = ('<u>Test</u> for <<b>bold</b>, <i>ita_lic</i>, <code>\`code</code>,'
|
||||
' <a href="http://github.com/abc\)def">links</a>, '
|
||||
'<a href="tg://user?id=123456789">text-mention</a> and '
|
||||
'<pre>pre</pre>. <a href="http://google.com">http://google.com</a>')
|
||||
caption_html = self.test_message.caption_html_urled
|
||||
'<pre>`\pre</pre>. <a href="http://google.com">http://google.com</a> '
|
||||
'and <i>bold <b>nested in <s>strk</s> nested in</b> italic</i>.')
|
||||
caption_html = self.test_message_v2.caption_html_urled
|
||||
assert caption_html == test_html_string
|
||||
|
||||
def test_caption_markdown_simple(self):
|
||||
test_md_string = (r'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/), '
|
||||
'[text-mention](tg://user?id=123456789) and ```pre```. '
|
||||
'http://google.com')
|
||||
test_md_string = ('Test for <*bold*, _ita_\__lic_, `code`, [links](http://github.com/ab_),'
|
||||
' [text-mention](tg://user?id=123456789) and ```\npre```. '
|
||||
'http://google.com/ab\_')
|
||||
caption_markdown = self.test_message.caption_markdown
|
||||
assert caption_markdown == test_md_string
|
||||
|
||||
def test_caption_markdown_v2_simple(self):
|
||||
test_md_string = (r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, '
|
||||
'[links](http://github.com/abc\\\\\\)def), '
|
||||
'[text\-mention](tg://user?id=123456789) and ```\`\\\\pre```\. '
|
||||
'http://google\.com and _bold *nested in ~strk~ nested in* italic_\.')
|
||||
caption_markdown = self.test_message_v2.caption_markdown_v2
|
||||
assert caption_markdown == test_md_string
|
||||
|
||||
def test_caption_markdown_empty(self, message):
|
||||
message.text = "test"
|
||||
message.caption = None
|
||||
assert message.caption_markdown is None
|
||||
assert message.caption_markdown_v2 is None
|
||||
|
||||
def test_caption_markdown_urled(self):
|
||||
test_md_string = (r'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/), '
|
||||
'[text-mention](tg://user?id=123456789) and ```pre```. '
|
||||
'[http://google.com](http://google.com)')
|
||||
test_md_string = ('Test for <*bold*, _ita_\__lic_, `code`, [links](http://github.com/ab_),'
|
||||
' [text-mention](tg://user?id=123456789) and ```\npre```. '
|
||||
'[http://google.com/ab_](http://google.com/ab_)')
|
||||
caption_markdown = self.test_message.caption_markdown_urled
|
||||
assert caption_markdown == test_md_string
|
||||
|
||||
def test_caption_markdown_v2_urled(self):
|
||||
test_md_string = (r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, '
|
||||
'[links](http://github.com/abc\\\\\\)def), '
|
||||
'[text\-mention](tg://user?id=123456789) and ```\`\\\\pre```\. '
|
||||
'[http://google\.com](http://google.com) and _bold *nested in ~strk~ '
|
||||
'nested in* italic_\.')
|
||||
caption_markdown = self.test_message_v2.caption_markdown_v2_urled
|
||||
assert caption_markdown == test_md_string
|
||||
|
||||
def test_caption_html_emoji(self):
|
||||
caption = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape')
|
||||
expected = b'\\U0001f469\\u200d\\U0001f469\\u200d <b>ABC</b>'.decode('unicode-escape')
|
||||
|
@ -359,9 +443,9 @@ class TestMessage(object):
|
|||
assert message.reply_text('test', reply_to_message_id=message.message_id, quote=True)
|
||||
|
||||
def test_reply_markdown(self, monkeypatch, message):
|
||||
test_md_string = (r'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/), '
|
||||
'[text-mention](tg://user?id=123456789) and ```pre```. '
|
||||
'http://google.com')
|
||||
test_md_string = ('Test for <*bold*, _ita_\__lic_, `code`, [links](http://github.com/ab_),'
|
||||
' [text-mention](tg://user?id=123456789) and ```\npre```. '
|
||||
'http://google.com/ab\_')
|
||||
|
||||
def test(*args, **kwargs):
|
||||
cid = args[0] == message.chat_id
|
||||
|
@ -383,11 +467,38 @@ class TestMessage(object):
|
|||
reply_to_message_id=message.message_id,
|
||||
quote=True)
|
||||
|
||||
def test_reply_markdown_v2(self, monkeypatch, message):
|
||||
test_md_string = (r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, '
|
||||
'[links](http://github.com/abc\\\\\)def), '
|
||||
'[text\-mention](tg://user?id=123456789) and ```\`\\\\pre```\. '
|
||||
'http://google\.com and _bold *nested in ~strk~ nested in* italic_\.')
|
||||
|
||||
def test(*args, **kwargs):
|
||||
cid = args[0] == message.chat_id
|
||||
markdown_text = args[1] == test_md_string
|
||||
markdown_enabled = kwargs['parse_mode'] == ParseMode.MARKDOWN_V2
|
||||
if kwargs.get('reply_to_message_id'):
|
||||
reply = kwargs['reply_to_message_id'] == message.message_id
|
||||
else:
|
||||
reply = True
|
||||
return all([cid, markdown_text, reply, markdown_enabled])
|
||||
|
||||
text_markdown = self.test_message_v2.text_markdown_v2
|
||||
assert text_markdown == test_md_string
|
||||
|
||||
monkeypatch.setattr(message.bot, 'send_message', test)
|
||||
assert message.reply_markdown_v2(self.test_message_v2.text_markdown_v2)
|
||||
assert message.reply_markdown_v2(self.test_message_v2.text_markdown_v2, quote=True)
|
||||
assert message.reply_markdown_v2(self.test_message_v2.text_markdown_v2,
|
||||
reply_to_message_id=message.message_id,
|
||||
quote=True)
|
||||
|
||||
def test_reply_html(self, monkeypatch, message):
|
||||
test_html_string = ('Test for <<b>bold</b>, <i>ita_lic</i>, <code>code</code>, '
|
||||
'<a href="http://github.com/">links</a>, '
|
||||
test_html_string = ('<u>Test</u> for <<b>bold</b>, <i>ita_lic</i>, <code>\`code</code>,'
|
||||
' <a href="http://github.com/abc\)def">links</a>, '
|
||||
'<a href="tg://user?id=123456789">text-mention</a> and '
|
||||
'<pre>pre</pre>. http://google.com')
|
||||
'<pre>`\pre</pre>. http://google.com '
|
||||
'and <i>bold <b>nested in <s>strk</s> nested in</b> italic</i>.')
|
||||
|
||||
def test(*args, **kwargs):
|
||||
cid = args[0] == message.chat_id
|
||||
|
@ -399,13 +510,13 @@ class TestMessage(object):
|
|||
reply = True
|
||||
return all([cid, html_text, reply, html_enabled])
|
||||
|
||||
text_html = self.test_message.text_html
|
||||
text_html = self.test_message_v2.text_html
|
||||
assert text_html == test_html_string
|
||||
|
||||
monkeypatch.setattr(message.bot, 'send_message', test)
|
||||
assert message.reply_html(self.test_message.text_html)
|
||||
assert message.reply_html(self.test_message.text_html, quote=True)
|
||||
assert message.reply_html(self.test_message.text_html,
|
||||
assert message.reply_html(self.test_message_v2.text_html)
|
||||
assert message.reply_html(self.test_message_v2.text_html, quote=True)
|
||||
assert message.reply_html(self.test_message_v2.text_html,
|
||||
reply_to_message_id=message.message_id,
|
||||
quote=True)
|
||||
|
||||
|
|
|
@ -53,26 +53,35 @@ RAW_PASSPORT_DATA = {'credentials': {'hash': 'qB4hz2LMcXYhglwz6EvXMMyI3PURisWLXl
|
|||
'type': 'personal_details'
|
||||
}, {
|
||||
'reverse_side': {'file_date': 1534074942,
|
||||
'file_id': 'DgADBAADNQQAAtoagFPf4wwmFZdmyQI'},
|
||||
'file_id': 'DgADBAADNQQAAtoagFPf4wwmFZdmyQI',
|
||||
'file_unique_id': 'adc3145fd2e84d95b64d68eaa22aa33e'},
|
||||
'translation': [{'file_size': 28640, 'file_date': 1535630933,
|
||||
'file_id': 'DgADBAADswMAAisqQVAmooP-kVgLgAI'},
|
||||
'file_id': 'DgADBAADswMAAisqQVAmooP-kVgLgAI',
|
||||
'file_unique_id': '52a90d53d6064bb58feb582acdc3a324'},
|
||||
{'file_size': 28672, 'file_date': 1535630933,
|
||||
'file_id': 'DgADBAAD1QMAAnrpQFBMZsT3HysjwwI'}],
|
||||
'file_id': 'DgADBAAD1QMAAnrpQFBMZsT3HysjwwI',
|
||||
'file_unique_id': '7285f864d168441ba1f7d02146250432'}],
|
||||
'front_side': {'file_size': 28624, 'file_date': 1534074942,
|
||||
'file_id': 'DgADBAADxwMAApnQgVPK2-ckL2eXVAI'},
|
||||
'file_id': 'DgADBAADxwMAApnQgVPK2-ckL2eXVAI',
|
||||
'file_unique_id': 'd9d52a700cbb4a189a80104aa5978133'},
|
||||
'type': 'driver_license',
|
||||
'selfie': {'file_size': 28592, 'file_date': 1534074942,
|
||||
'file_id': 'DgADBAADEQQAAkopgFNr6oi-wISRtAI'},
|
||||
'file_id': 'DgADBAADEQQAAkopgFNr6oi-wISRtAI',
|
||||
'file_unique_id': 'd4e390cca57b4da5a65322b304762a12'},
|
||||
'data': 'eJUOFuY53QKmGqmBgVWlLBAQCUQJ79n405SX6M5aGFIIodOPQqnLYvMNqTwTrXGDlW+mVLZcbu+y8luLVO8WsJB/0SB7q5WaXn/IMt1G9lz5G/KMLIZG/x9zlnimsaQLg7u8srG6L4KZzv+xkbbHjZdETrxU8j0N/DoS4HvLMRSJAgeFUrY6v2YW9vSRg+fSxIqQy1jR2VKpzAT8OhOz7A=='
|
||||
}, {
|
||||
'translation': [{'file_size': 28480, 'file_date': 1535630939,
|
||||
'file_id': 'DgADBAADyQUAAqyqQVC_eoX_KwNjJwI'},
|
||||
'file_id': 'DgADBAADyQUAAqyqQVC_eoX_KwNjJwI',
|
||||
'file_unique_id': '38b2877b443542cbaf520c6e36a33ac4'},
|
||||
{'file_size': 28528, 'file_date': 1535630939,
|
||||
'file_id': 'DgADBAADsQQAAubTQVDRO_FN3lOwWwI'}],
|
||||
'file_id': 'DgADBAADsQQAAubTQVDRO_FN3lOwWwI',
|
||||
'file_unique_id': 'f008ca48c44b4a47895ddbcd2f76741e'}],
|
||||
'files': [{'file_size': 28640, 'file_date': 1534074988,
|
||||
'file_id': 'DgADBAADLAMAAhwfgVMyfGa5Nr0LvAI'},
|
||||
'file_id': 'DgADBAADLAMAAhwfgVMyfGa5Nr0LvAI',
|
||||
'file_unique_id': 'b170748794834644baaa3ec57ee4ce7a'},
|
||||
{'file_size': 28480, 'file_date': 1534074988,
|
||||
'file_id': 'DgADBAADaQQAAsFxgVNVfLZuT-_3ZQI'}],
|
||||
'file_id': 'DgADBAADaQQAAsFxgVNVfLZuT-_3ZQI',
|
||||
'file_unique_id': '19a12ae34dca424b85e0308f706cee75'}],
|
||||
'type': 'utility_bill'
|
||||
}, {
|
||||
'data': 'j9SksVkSj128DBtZA+3aNjSFNirzv+R97guZaMgae4Gi0oDVNAF7twPR7j9VSmPedfJrEwL3O889Ei+a5F1xyLLyEI/qEBljvL70GFIhYGitS0JmNabHPHSZrjOl8b4s/0Z0Px2GpLO5siusTLQonimdUvu4UPjKquYISmlKEKhtmGATy+h+JDjNCYuOkhakeNw0Rk0BHgj0C3fCb7WZNQSyVb+2GTu6caR6eXf/AFwFp0TV3sRz3h0WIVPW8bna',
|
||||
|
@ -138,14 +147,23 @@ def passport_data(bot):
|
|||
|
||||
class TestPassport(object):
|
||||
driver_license_selfie_file_id = 'DgADBAADEQQAAkopgFNr6oi-wISRtAI'
|
||||
driver_license_selfie_file_unique_id = 'd4e390cca57b4da5a65322b304762a12'
|
||||
driver_license_front_side_file_id = 'DgADBAADxwMAApnQgVPK2-ckL2eXVAI'
|
||||
driver_license_front_side_file_unique_id = 'd9d52a700cbb4a189a80104aa5978133'
|
||||
driver_license_reverse_side_file_id = 'DgADBAADNQQAAtoagFPf4wwmFZdmyQI'
|
||||
driver_license_reverse_side_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
|
||||
driver_license_translation_1_file_id = 'DgADBAADswMAAisqQVAmooP-kVgLgAI'
|
||||
driver_license_translation_1_file_unique_id = '52a90d53d6064bb58feb582acdc3a324'
|
||||
driver_license_translation_2_file_id = 'DgADBAAD1QMAAnrpQFBMZsT3HysjwwI'
|
||||
driver_license_translation_2_file_unique_id = '7285f864d168441ba1f7d02146250432'
|
||||
utility_bill_1_file_id = 'DgADBAADLAMAAhwfgVMyfGa5Nr0LvAI'
|
||||
utility_bill_1_file_unique_id = 'b170748794834644baaa3ec57ee4ce7a'
|
||||
utility_bill_2_file_id = 'DgADBAADaQQAAsFxgVNVfLZuT-_3ZQI'
|
||||
utility_bill_2_file_unique_id = '19a12ae34dca424b85e0308f706cee75'
|
||||
utility_bill_translation_1_file_id = 'DgADBAADyQUAAqyqQVC_eoX_KwNjJwI'
|
||||
utility_bill_translation_1_file_unique_id = '38b2877b443542cbaf520c6e36a33ac4'
|
||||
utility_bill_translation_2_file_id = 'DgADBAADsQQAAubTQVDRO_FN3lOwWwI'
|
||||
utility_bill_translation_2_file_unique_id = 'f008ca48c44b4a47895ddbcd2f76741e'
|
||||
driver_license_selfie_credentials_file_hash = 'Cila/qLXSBH7DpZFbb5bRZIRxeFW2uv/ulL0u0JNsYI='
|
||||
driver_license_selfie_credentials_secret = 'tivdId6RNYNsvXYPppdzrbxOBuBOr9wXRPDcCvnXU7E='
|
||||
|
||||
|
@ -162,24 +180,40 @@ class TestPassport(object):
|
|||
assert driver_license.data == RAW_PASSPORT_DATA['data'][1]['data']
|
||||
assert isinstance(driver_license.selfie, PassportFile)
|
||||
assert driver_license.selfie.file_id == self.driver_license_selfie_file_id
|
||||
assert driver_license.selfie.file_unique_id == self.driver_license_selfie_file_unique_id
|
||||
|
||||
assert isinstance(driver_license.front_side, PassportFile)
|
||||
assert driver_license.front_side.file_id == self.driver_license_front_side_file_id
|
||||
assert driver_license.front_side.file_unique_id == self.driver_license_front_side_file_unique_id
|
||||
|
||||
assert isinstance(driver_license.reverse_side, PassportFile)
|
||||
assert driver_license.reverse_side.file_id == self.driver_license_reverse_side_file_id
|
||||
assert driver_license.reverse_side.file_unique_id == self.driver_license_reverse_side_file_unique_id
|
||||
|
||||
assert isinstance(driver_license.translation[0], PassportFile)
|
||||
assert driver_license.translation[0].file_id == self.driver_license_translation_1_file_id
|
||||
assert driver_license.translation[0].file_unique_id == self.driver_license_translation_1_file_unique_id
|
||||
|
||||
assert isinstance(driver_license.translation[1], PassportFile)
|
||||
assert driver_license.translation[1].file_id == self.driver_license_translation_2_file_id
|
||||
assert driver_license.translation[1].file_unique_id == self.driver_license_translation_2_file_unique_id
|
||||
|
||||
assert utility_bill.type == 'utility_bill'
|
||||
assert isinstance(utility_bill.files[0], PassportFile)
|
||||
assert utility_bill.files[0].file_id == self.utility_bill_1_file_id
|
||||
assert utility_bill.files[0].file_unique_id == self.utility_bill_1_file_unique_id
|
||||
|
||||
assert isinstance(utility_bill.files[1], PassportFile)
|
||||
assert utility_bill.files[1].file_id == self.utility_bill_2_file_id
|
||||
assert utility_bill.files[1].file_unique_id == self.utility_bill_2_file_unique_id
|
||||
|
||||
assert isinstance(utility_bill.translation[0], PassportFile)
|
||||
assert utility_bill.translation[0].file_id == self.utility_bill_translation_1_file_id
|
||||
assert utility_bill.translation[0].file_unique_id == self.utility_bill_translation_1_file_unique_id
|
||||
|
||||
assert isinstance(utility_bill.translation[1], PassportFile)
|
||||
assert utility_bill.translation[1].file_id == self.utility_bill_translation_2_file_id
|
||||
assert utility_bill.translation[1].file_unique_id == self.utility_bill_translation_2_file_unique_id
|
||||
|
||||
assert address.type == 'address'
|
||||
assert address.data == RAW_PASSPORT_DATA['data'][3]['data']
|
||||
|
@ -208,10 +242,15 @@ class TestPassport(object):
|
|||
'document_no': 'DOCUMENT_NO'}
|
||||
assert isinstance(driver_license.selfie, PassportFile)
|
||||
assert driver_license.selfie.file_id == self.driver_license_selfie_file_id
|
||||
assert driver_license.selfie.file_unique_id == self.driver_license_selfie_file_unique_id
|
||||
|
||||
assert isinstance(driver_license.front_side, PassportFile)
|
||||
assert driver_license.front_side.file_id == self.driver_license_front_side_file_id
|
||||
assert driver_license.front_side.file_unique_id == self.driver_license_front_side_file_unique_id
|
||||
|
||||
assert isinstance(driver_license.reverse_side, PassportFile)
|
||||
assert driver_license.reverse_side.file_id == self.driver_license_reverse_side_file_id
|
||||
assert driver_license.reverse_side.file_unique_id == self.driver_license_reverse_side_file_unique_id
|
||||
|
||||
assert address.type == 'address'
|
||||
assert address.data.to_dict() == {'city': 'CITY', 'street_line2': 'STREET_LINE2',
|
||||
|
@ -221,8 +260,11 @@ class TestPassport(object):
|
|||
assert utility_bill.type == 'utility_bill'
|
||||
assert isinstance(utility_bill.files[0], PassportFile)
|
||||
assert utility_bill.files[0].file_id == self.utility_bill_1_file_id
|
||||
assert utility_bill.files[0].file_unique_id == self.utility_bill_1_file_unique_id
|
||||
|
||||
assert isinstance(utility_bill.files[1], PassportFile)
|
||||
assert utility_bill.files[1].file_id == self.utility_bill_2_file_id
|
||||
assert utility_bill.files[1].file_unique_id == self.utility_bill_2_file_unique_id
|
||||
|
||||
assert email.type == 'email'
|
||||
assert email.email == 'fb3e3i47zt@dispostable.com'
|
||||
|
@ -295,12 +337,14 @@ class TestPassport(object):
|
|||
# TODO: Actually download a passport file in a test
|
||||
selfie = passport_data.decrypted_data[1].selfie
|
||||
|
||||
# NOTE: file_unique_id is not used in the get_file method, so it is passed directly
|
||||
def get_file(*args, **kwargs):
|
||||
return File(args[0])
|
||||
return File(args[0], selfie.file_unique_id)
|
||||
|
||||
monkeypatch.setattr(passport_data.bot, 'get_file', get_file)
|
||||
file = selfie.get_file()
|
||||
assert file.file_id == selfie.file_id
|
||||
assert file.file_unique_id == selfie.file_unique_id
|
||||
assert file._credentials.file_hash == self.driver_license_selfie_credentials_file_hash
|
||||
assert file._credentials.secret == self.driver_license_selfie_credentials_secret
|
||||
|
||||
|
|
|
@ -25,17 +25,20 @@ from telegram import PassportFile, PassportElementError
|
|||
@pytest.fixture(scope='class')
|
||||
def passport_file():
|
||||
return PassportFile(file_id=TestPassportFile.file_id,
|
||||
file_unique_id=TestPassportFile.file_unique_id,
|
||||
file_size=TestPassportFile.file_size,
|
||||
file_date=TestPassportFile.file_date)
|
||||
|
||||
|
||||
class TestPassportFile(object):
|
||||
file_id = 'data'
|
||||
file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
|
||||
file_size = 50
|
||||
file_date = 1532879128
|
||||
|
||||
def test_expected_values(self, passport_file):
|
||||
assert passport_file.file_id == self.file_id
|
||||
assert passport_file.file_unique_id == self.file_unique_id
|
||||
assert passport_file.file_size == self.file_size
|
||||
assert passport_file.file_date == self.file_date
|
||||
|
||||
|
@ -45,16 +48,18 @@ class TestPassportFile(object):
|
|||
assert isinstance(passport_file_dict, dict)
|
||||
assert (passport_file_dict['file_id']
|
||||
== passport_file.file_id)
|
||||
assert (passport_file_dict['file_unique_id']
|
||||
== passport_file.file_unique_id)
|
||||
assert (passport_file_dict['file_size']
|
||||
== passport_file.file_size)
|
||||
assert (passport_file_dict['file_date']
|
||||
== passport_file.file_date)
|
||||
|
||||
def test_equality(self):
|
||||
a = PassportFile(self.file_id, self.file_size, self.file_date)
|
||||
b = PassportFile(self.file_id, self.file_size, self.file_date)
|
||||
c = PassportFile(self.file_id, '', '')
|
||||
d = PassportFile('', self.file_size, self.file_date)
|
||||
a = PassportFile(self.file_id, self.file_unique_id, self.file_size, self.file_date)
|
||||
b = PassportFile('', self.file_unique_id, self.file_size, self.file_date)
|
||||
c = PassportFile(self.file_id, self.file_unique_id, '', '')
|
||||
d = PassportFile('', '', self.file_size, self.file_date)
|
||||
e = PassportElementError('source', 'type', 'message')
|
||||
|
||||
assert a == b
|
||||
|
|
|
@ -60,11 +60,15 @@ class TestPhoto(object):
|
|||
# Make sure file has been uploaded.
|
||||
assert isinstance(photo, PhotoSize)
|
||||
assert isinstance(photo.file_id, str)
|
||||
assert isinstance(photo.file_unique_id, str)
|
||||
assert photo.file_id != ''
|
||||
assert photo.file_unique_id != ''
|
||||
|
||||
assert isinstance(thumb, PhotoSize)
|
||||
assert isinstance(thumb.file_id, str)
|
||||
assert isinstance(thumb.file_unique_id, str)
|
||||
assert thumb.file_id != ''
|
||||
assert thumb.file_unique_id != ''
|
||||
|
||||
def test_expected_values(self, photo, thumb):
|
||||
assert photo.width == self.width
|
||||
|
@ -82,14 +86,18 @@ class TestPhoto(object):
|
|||
|
||||
assert isinstance(message.photo[0], PhotoSize)
|
||||
assert isinstance(message.photo[0].file_id, str)
|
||||
assert isinstance(message.photo[0].file_unique_id, str)
|
||||
assert message.photo[0].file_id != ''
|
||||
assert message.photo[0].file_unique_id != ''
|
||||
assert message.photo[0].width == thumb.width
|
||||
assert message.photo[0].height == thumb.height
|
||||
assert message.photo[0].file_size == thumb.file_size
|
||||
|
||||
assert isinstance(message.photo[1], PhotoSize)
|
||||
assert isinstance(message.photo[1].file_id, str)
|
||||
assert isinstance(message.photo[1].file_unique_id, str)
|
||||
assert message.photo[1].file_id != ''
|
||||
assert message.photo[1].file_unique_id != ''
|
||||
assert message.photo[1].width == photo.width
|
||||
assert message.photo[1].height == photo.height
|
||||
assert message.photo[1].file_size == photo.file_size
|
||||
|
@ -103,14 +111,18 @@ class TestPhoto(object):
|
|||
parse_mode='Markdown')
|
||||
assert isinstance(message.photo[0], PhotoSize)
|
||||
assert isinstance(message.photo[0].file_id, str)
|
||||
assert isinstance(message.photo[0].file_unique_id, str)
|
||||
assert message.photo[0].file_id != ''
|
||||
assert message.photo[0].file_unique_id != ''
|
||||
assert message.photo[0].width == thumb.width
|
||||
assert message.photo[0].height == thumb.height
|
||||
assert message.photo[0].file_size == thumb.file_size
|
||||
|
||||
assert isinstance(message.photo[1], PhotoSize)
|
||||
assert isinstance(message.photo[1].file_id, str)
|
||||
assert isinstance(message.photo[1].file_unique_id, str)
|
||||
assert message.photo[1].file_id != ''
|
||||
assert message.photo[1].file_unique_id != ''
|
||||
assert message.photo[1].width == photo.width
|
||||
assert message.photo[1].height == photo.height
|
||||
assert message.photo[1].file_size == photo.file_size
|
||||
|
@ -125,14 +137,18 @@ class TestPhoto(object):
|
|||
parse_mode='HTML')
|
||||
assert isinstance(message.photo[0], PhotoSize)
|
||||
assert isinstance(message.photo[0].file_id, str)
|
||||
assert isinstance(message.photo[0].file_unique_id, str)
|
||||
assert message.photo[0].file_id != ''
|
||||
assert message.photo[0].file_unique_id != ''
|
||||
assert message.photo[0].width == thumb.width
|
||||
assert message.photo[0].height == thumb.height
|
||||
assert message.photo[0].file_size == thumb.file_size
|
||||
|
||||
assert isinstance(message.photo[1], PhotoSize)
|
||||
assert isinstance(message.photo[1].file_id, str)
|
||||
assert isinstance(message.photo[1].file_unique_id, str)
|
||||
assert message.photo[1].file_id != ''
|
||||
assert message.photo[1].file_unique_id != ''
|
||||
assert message.photo[1].width == photo.width
|
||||
assert message.photo[1].height == photo.height
|
||||
assert message.photo[1].file_size == photo.file_size
|
||||
|
@ -175,12 +191,11 @@ class TestPhoto(object):
|
|||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
@pytest.mark.skip(reason='Doesnt work without API 4.5')
|
||||
def test_get_and_download(self, bot, photo):
|
||||
new_file = bot.getFile(photo.file_id)
|
||||
|
||||
assert new_file.file_size == photo.file_size
|
||||
assert new_file.file_id == photo.file_id
|
||||
assert new_file.file_unique_id == photo.file_unique_id
|
||||
assert new_file.file_path.startswith('https://') is True
|
||||
|
||||
new_file.download('telegram.jpg')
|
||||
|
@ -194,14 +209,18 @@ class TestPhoto(object):
|
|||
|
||||
assert isinstance(message.photo[0], PhotoSize)
|
||||
assert isinstance(message.photo[0].file_id, str)
|
||||
assert isinstance(message.photo[0].file_unique_id, str)
|
||||
assert message.photo[0].file_id != ''
|
||||
assert message.photo[0].file_unique_id != ''
|
||||
assert message.photo[0].width == thumb.width
|
||||
assert message.photo[0].height == thumb.height
|
||||
assert message.photo[0].file_size == thumb.file_size
|
||||
|
||||
assert isinstance(message.photo[1], PhotoSize)
|
||||
assert isinstance(message.photo[1].file_id, str)
|
||||
assert isinstance(message.photo[1].file_unique_id, str)
|
||||
assert message.photo[1].file_id != ''
|
||||
assert message.photo[1].file_unique_id != ''
|
||||
assert message.photo[1].width == photo.width
|
||||
assert message.photo[1].height == photo.height
|
||||
assert message.photo[1].file_size == photo.file_size
|
||||
|
@ -216,7 +235,9 @@ class TestPhoto(object):
|
|||
|
||||
assert isinstance(photo, PhotoSize)
|
||||
assert isinstance(photo.file_id, str)
|
||||
assert isinstance(photo.file_unique_id, str)
|
||||
assert photo.file_id != ''
|
||||
assert photo.file_unique_id != ''
|
||||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
|
@ -228,7 +249,9 @@ class TestPhoto(object):
|
|||
|
||||
assert isinstance(photo, PhotoSize)
|
||||
assert isinstance(photo.file_id, str)
|
||||
assert isinstance(photo.file_unique_id, str)
|
||||
assert photo.file_id != ''
|
||||
assert photo.file_unique_id != ''
|
||||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
|
@ -243,7 +266,9 @@ class TestPhoto(object):
|
|||
|
||||
assert isinstance(photo, PhotoSize)
|
||||
assert isinstance(photo.file_id, str)
|
||||
assert isinstance(photo.file_unique_id, str)
|
||||
assert photo.file_id != ''
|
||||
assert photo.file_unique_id != ''
|
||||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
|
@ -266,7 +291,9 @@ class TestPhoto(object):
|
|||
message = bot.send_photo(chat_id, photo=raw_bytes)
|
||||
photo = message.photo[-1]
|
||||
assert isinstance(photo.file_id, str)
|
||||
assert isinstance(photo.file_unique_id, str)
|
||||
assert photo.file_id != ''
|
||||
assert photo.file_unique_id != ''
|
||||
assert isinstance(photo, PhotoSize)
|
||||
assert photo.width == 1280
|
||||
assert photo.height == 720
|
||||
|
@ -289,14 +316,18 @@ class TestPhoto(object):
|
|||
|
||||
assert isinstance(message.photo[0], PhotoSize)
|
||||
assert isinstance(message.photo[0].file_id, str)
|
||||
assert isinstance(message.photo[0].file_unique_id, str)
|
||||
assert message.photo[0].file_id != ''
|
||||
assert message.photo[0].file_unique_id != ''
|
||||
assert message.photo[0].width == thumb.width
|
||||
assert message.photo[0].height == thumb.height
|
||||
assert message.photo[0].file_size == thumb.file_size
|
||||
|
||||
assert isinstance(message.photo[1], PhotoSize)
|
||||
assert isinstance(message.photo[1].file_id, str)
|
||||
assert isinstance(message.photo[1].file_unique_id, str)
|
||||
assert message.photo[1].file_id != ''
|
||||
assert message.photo[1].file_unique_id != ''
|
||||
assert message.photo[1].width == photo.width
|
||||
assert message.photo[1].height == photo.height
|
||||
assert message.photo[1].file_size == photo.file_size
|
||||
|
@ -304,6 +335,7 @@ class TestPhoto(object):
|
|||
def test_de_json(self, bot, photo):
|
||||
json_dict = {
|
||||
'file_id': photo.file_id,
|
||||
'file_unique_id': photo.file_unique_id,
|
||||
'width': self.width,
|
||||
'height': self.height,
|
||||
'file_size': self.file_size
|
||||
|
@ -311,6 +343,7 @@ class TestPhoto(object):
|
|||
json_photo = PhotoSize.de_json(json_dict, bot)
|
||||
|
||||
assert json_photo.file_id == photo.file_id
|
||||
assert json_photo.file_unique_id == photo.file_unique_id
|
||||
assert json_photo.width == self.width
|
||||
assert json_photo.height == self.height
|
||||
assert json_photo.file_size == self.file_size
|
||||
|
@ -320,6 +353,7 @@ class TestPhoto(object):
|
|||
|
||||
assert isinstance(photo_dict, dict)
|
||||
assert photo_dict['file_id'] == photo.file_id
|
||||
assert photo_dict['file_unique_id'] == photo.file_unique_id
|
||||
assert photo_dict['width'] == photo.width
|
||||
assert photo_dict['height'] == photo.height
|
||||
assert photo_dict['file_size'] == photo.file_size
|
||||
|
@ -348,11 +382,11 @@ class TestPhoto(object):
|
|||
assert photo.get_file()
|
||||
|
||||
def test_equality(self, photo):
|
||||
a = PhotoSize(photo.file_id, self.width, self.height)
|
||||
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, False)
|
||||
a = PhotoSize(photo.file_id, photo.file_unique_id, self.width, self.height)
|
||||
b = PhotoSize('', photo.file_unique_id, self.width, self.height)
|
||||
c = PhotoSize(photo.file_id, photo.file_unique_id, 0, 0)
|
||||
d = PhotoSize('', '', self.width, self.height)
|
||||
e = Sticker(photo.file_id, photo.file_unique_id, self.width, self.height, False)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -55,7 +55,7 @@ class TestShippingOption(object):
|
|||
b = ShippingOption(self.id_, self.title, self.prices)
|
||||
c = ShippingOption(self.id_, '', [])
|
||||
d = ShippingOption(0, self.title, self.prices)
|
||||
e = Voice(self.id_, 0)
|
||||
e = Voice(self.id_, 'someid', 0)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -55,14 +55,21 @@ class TestSticker(object):
|
|||
thumb_height = 320
|
||||
thumb_file_size = 21472
|
||||
|
||||
sticker_file_id = '5a3128a4d2a04750b5b58397f3b5e812'
|
||||
sticker_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
|
||||
|
||||
def test_creation(self, sticker):
|
||||
# Make sure file has been uploaded.
|
||||
assert isinstance(sticker, Sticker)
|
||||
assert isinstance(sticker.file_id, str)
|
||||
assert isinstance(sticker.file_unique_id, str)
|
||||
assert sticker.file_id != ''
|
||||
assert sticker.file_unique_id != ''
|
||||
assert isinstance(sticker.thumb, PhotoSize)
|
||||
assert isinstance(sticker.thumb.file_id, str)
|
||||
assert isinstance(sticker.thumb.file_unique_id, str)
|
||||
assert sticker.thumb.file_id != ''
|
||||
assert sticker.thumb.file_unique_id != ''
|
||||
|
||||
def test_expected_values(self, sticker):
|
||||
assert sticker.width == self.width
|
||||
|
@ -80,7 +87,9 @@ class TestSticker(object):
|
|||
|
||||
assert isinstance(message.sticker, Sticker)
|
||||
assert isinstance(message.sticker.file_id, str)
|
||||
assert isinstance(message.sticker.file_unique_id, str)
|
||||
assert message.sticker.file_id != ''
|
||||
assert message.sticker.file_unique_id != ''
|
||||
assert message.sticker.width == sticker.width
|
||||
assert message.sticker.height == sticker.height
|
||||
assert message.sticker.is_animated == sticker.is_animated
|
||||
|
@ -88,7 +97,9 @@ class TestSticker(object):
|
|||
|
||||
assert isinstance(message.sticker.thumb, PhotoSize)
|
||||
assert isinstance(message.sticker.thumb.file_id, str)
|
||||
assert isinstance(message.sticker.thumb.file_unique_id, str)
|
||||
assert message.sticker.thumb.file_id != ''
|
||||
assert message.sticker.thumb.file_unique_id != ''
|
||||
assert message.sticker.thumb.width == sticker.thumb.width
|
||||
assert message.sticker.thumb.height == sticker.thumb.height
|
||||
assert message.sticker.thumb.file_size == sticker.thumb.file_size
|
||||
|
@ -100,6 +111,7 @@ class TestSticker(object):
|
|||
|
||||
assert new_file.file_size == sticker.file_size
|
||||
assert new_file.file_id == sticker.file_id
|
||||
assert new_file.file_unique_id == sticker.file_unique_id
|
||||
assert new_file.file_path.startswith('https://')
|
||||
|
||||
new_file.download('telegram.webp')
|
||||
|
@ -108,7 +120,6 @@ class TestSticker(object):
|
|||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
@pytest.mark.skip(reason='Doesnt work without API 4.5')
|
||||
def test_resend(self, bot, chat_id, sticker):
|
||||
message = bot.send_sticker(chat_id=chat_id, sticker=sticker.file_id)
|
||||
|
||||
|
@ -133,7 +144,9 @@ class TestSticker(object):
|
|||
|
||||
assert isinstance(message.sticker, Sticker)
|
||||
assert isinstance(message.sticker.file_id, str)
|
||||
assert isinstance(message.sticker.file_unique_id, str)
|
||||
assert message.sticker.file_id != ''
|
||||
assert message.sticker.file_unique_id != ''
|
||||
assert message.sticker.width == sticker.width
|
||||
assert message.sticker.height == sticker.height
|
||||
assert message.sticker.is_animated == sticker.is_animated
|
||||
|
@ -141,14 +154,17 @@ class TestSticker(object):
|
|||
|
||||
assert isinstance(message.sticker.thumb, PhotoSize)
|
||||
assert isinstance(message.sticker.thumb.file_id, str)
|
||||
assert isinstance(message.sticker.thumb.file_unique_id, str)
|
||||
assert message.sticker.thumb.file_id != ''
|
||||
assert message.sticker.thumb.file_unique_id != ''
|
||||
assert message.sticker.thumb.width == sticker.thumb.width
|
||||
assert message.sticker.thumb.height == sticker.thumb.height
|
||||
assert message.sticker.thumb.file_size == sticker.thumb.file_size
|
||||
|
||||
def test_de_json(self, bot, sticker):
|
||||
json_dict = {
|
||||
'file_id': 'not a file id',
|
||||
'file_id': self.sticker_file_id,
|
||||
'file_unique_id': self.sticker_file_unique_id,
|
||||
'width': self.width,
|
||||
'height': self.height,
|
||||
'is_animated': self.is_animated,
|
||||
|
@ -158,7 +174,8 @@ class TestSticker(object):
|
|||
}
|
||||
json_sticker = Sticker.de_json(json_dict, bot)
|
||||
|
||||
assert json_sticker.file_id == 'not a file id'
|
||||
assert json_sticker.file_id == self.sticker_file_id
|
||||
assert json_sticker.file_unique_id == self.sticker_file_unique_id
|
||||
assert json_sticker.width == self.width
|
||||
assert json_sticker.height == self.height
|
||||
assert json_sticker.is_animated == self.is_animated
|
||||
|
@ -179,6 +196,7 @@ class TestSticker(object):
|
|||
|
||||
assert isinstance(sticker_dict, dict)
|
||||
assert sticker_dict['file_id'] == sticker.file_id
|
||||
assert sticker_dict['file_unique_id'] == sticker.file_unique_id
|
||||
assert sticker_dict['width'] == sticker.width
|
||||
assert sticker_dict['height'] == sticker.height
|
||||
assert sticker_dict['is_animated'] == sticker.is_animated
|
||||
|
@ -202,11 +220,14 @@ class TestSticker(object):
|
|||
bot.send_sticker(chat_id)
|
||||
|
||||
def test_equality(self, sticker):
|
||||
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)
|
||||
a = Sticker(sticker.file_id, sticker.file_unique_id, self.width,
|
||||
self.height, self.is_animated)
|
||||
b = Sticker('', sticker.file_unique_id, self.width,
|
||||
self.height, self.is_animated)
|
||||
c = Sticker(sticker.file_id, sticker.file_unique_id, 0, 0, False)
|
||||
d = Sticker('', '', self.width, self.height, self.is_animated)
|
||||
e = PhotoSize(sticker.file_id, sticker.file_unique_id, self.width,
|
||||
self.height, self.is_animated)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
@ -234,7 +255,7 @@ class TestStickerSet(object):
|
|||
title = 'Test stickers'
|
||||
is_animated = True
|
||||
contains_masks = False
|
||||
stickers = [Sticker('file_id', 512, 512, True)]
|
||||
stickers = [Sticker('file_id', 'file_un_id', 512, 512, True)]
|
||||
name = 'NOTAREALNAME'
|
||||
|
||||
def test_de_json(self, bot):
|
||||
|
@ -298,7 +319,7 @@ class TestStickerSet(object):
|
|||
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)
|
||||
e = Audio(self.name, '', 0, None, None)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
import pytest
|
||||
|
||||
from telegram import User, Update
|
||||
from telegram.utils.helpers import escape_markdown
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
|
@ -188,6 +189,18 @@ class TestUser(object):
|
|||
user.id)
|
||||
assert user.mention_markdown(user.username) == expected.format(user.username, user.id)
|
||||
|
||||
def test_mention_markdown_v2(self, user):
|
||||
user.first_name = 'first{name'
|
||||
user.last_name = 'last_name'
|
||||
|
||||
expected = u'[{}](tg://user?id={})'
|
||||
|
||||
assert user.mention_markdown_v2() == expected.format(escape_markdown(user.full_name,
|
||||
version=2), user.id)
|
||||
assert user.mention_markdown_v2('the{name>\u2022') == expected.format('the\{name\>\u2022',
|
||||
user.id)
|
||||
assert user.mention_markdown_v2(user.username) == expected.format(user.username, user.id)
|
||||
|
||||
def test_equality(self):
|
||||
a = User(self.id_, self.first_name, self.is_bot, self.last_name)
|
||||
b = User(self.id_, self.first_name, self.is_bot, self.last_name)
|
||||
|
|
|
@ -23,12 +23,12 @@ class TestUserProfilePhotos(object):
|
|||
total_count = 2
|
||||
photos = [
|
||||
[
|
||||
PhotoSize('file_id1', 512, 512),
|
||||
PhotoSize('file_id2', 512, 512)
|
||||
PhotoSize('file_id1', 'file_un_id1', 512, 512),
|
||||
PhotoSize('file_id2', 'file_un_id1', 512, 512)
|
||||
],
|
||||
[
|
||||
PhotoSize('file_id3', 512, 512),
|
||||
PhotoSize('file_id4', 512, 512)
|
||||
PhotoSize('file_id3', 'file_un_id3', 512, 512),
|
||||
PhotoSize('file_id4', 'file_un_id4', 512, 512)
|
||||
]
|
||||
]
|
||||
|
||||
|
|
|
@ -53,15 +53,22 @@ class TestVideo(object):
|
|||
caption = u'<b>VideoTest</b> - *Caption*'
|
||||
video_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.mp4'
|
||||
|
||||
video_file_id = '5a3128a4d2a04750b5b58397f3b5e812'
|
||||
video_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
|
||||
|
||||
def test_creation(self, video):
|
||||
# Make sure file has been uploaded.
|
||||
assert isinstance(video, Video)
|
||||
assert isinstance(video.file_id, str)
|
||||
assert isinstance(video.file_unique_id, str)
|
||||
assert video.file_id != ''
|
||||
assert video.file_unique_id != ''
|
||||
|
||||
assert isinstance(video.thumb, PhotoSize)
|
||||
assert isinstance(video.thumb.file_id, str)
|
||||
assert isinstance(video.thumb.file_unique_id, str)
|
||||
assert video.thumb.file_id != ''
|
||||
assert video.thumb.file_unique_id != ''
|
||||
|
||||
def test_expected_values(self, video):
|
||||
assert video.width == self.width
|
||||
|
@ -80,7 +87,9 @@ class TestVideo(object):
|
|||
|
||||
assert isinstance(message.video, Video)
|
||||
assert isinstance(message.video.file_id, str)
|
||||
assert isinstance(message.video.file_unique_id, str)
|
||||
assert message.video.file_id != ''
|
||||
assert message.video.file_unique_id != ''
|
||||
assert message.video.width == video.width
|
||||
assert message.video.height == video.height
|
||||
assert message.video.duration == video.duration
|
||||
|
@ -99,6 +108,7 @@ class TestVideo(object):
|
|||
|
||||
assert new_file.file_size == self.file_size
|
||||
assert new_file.file_id == video.file_id
|
||||
assert new_file.file_unique_id == video.file_unique_id
|
||||
assert new_file.file_path.startswith('https://')
|
||||
|
||||
new_file.download('telegram.mp4')
|
||||
|
@ -112,7 +122,9 @@ class TestVideo(object):
|
|||
|
||||
assert isinstance(message.video, Video)
|
||||
assert isinstance(message.video.file_id, str)
|
||||
assert isinstance(message.video.file_unique_id, str)
|
||||
assert message.video.file_id != ''
|
||||
assert message.video.file_unique_id != ''
|
||||
assert message.video.width == video.width
|
||||
assert message.video.height == video.height
|
||||
assert message.video.duration == video.duration
|
||||
|
@ -120,7 +132,9 @@ class TestVideo(object):
|
|||
|
||||
assert isinstance(message.video.thumb, PhotoSize)
|
||||
assert isinstance(message.video.thumb.file_id, str)
|
||||
assert isinstance(message.video.thumb.file_unique_id, str)
|
||||
assert message.video.thumb.file_id != ''
|
||||
assert message.video.thumb.file_unique_id != ''
|
||||
assert message.video.thumb.width == 51 # This seems odd that it's not self.thumb_width
|
||||
assert message.video.thumb.height == 90 # Ditto
|
||||
assert message.video.thumb.file_size == 645 # same
|
||||
|
@ -129,7 +143,6 @@ class TestVideo(object):
|
|||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
@pytest.mark.skip(reason='Doesnt work without API 4.5')
|
||||
def test_resend(self, bot, chat_id, video):
|
||||
message = bot.send_video(chat_id, video.file_id)
|
||||
|
||||
|
@ -178,7 +191,8 @@ class TestVideo(object):
|
|||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
'file_id': 'not a file id',
|
||||
'file_id': self.video_file_id,
|
||||
'file_unique_id': self.video_file_unique_id,
|
||||
'width': self.width,
|
||||
'height': self.height,
|
||||
'duration': self.duration,
|
||||
|
@ -187,7 +201,8 @@ class TestVideo(object):
|
|||
}
|
||||
json_video = Video.de_json(json_dict, bot)
|
||||
|
||||
assert json_video.file_id == 'not a file id'
|
||||
assert json_video.file_id == self.video_file_id
|
||||
assert json_video.file_unique_id == self.video_file_unique_id
|
||||
assert json_video.width == self.width
|
||||
assert json_video.height == self.height
|
||||
assert json_video.duration == self.duration
|
||||
|
@ -199,6 +214,7 @@ class TestVideo(object):
|
|||
|
||||
assert isinstance(video_dict, dict)
|
||||
assert video_dict['file_id'] == video.file_id
|
||||
assert video_dict['file_unique_id'] == video.file_unique_id
|
||||
assert video_dict['width'] == video.width
|
||||
assert video_dict['height'] == video.height
|
||||
assert video_dict['duration'] == video.duration
|
||||
|
@ -229,11 +245,11 @@ class TestVideo(object):
|
|||
assert video.get_file()
|
||||
|
||||
def test_equality(self, video):
|
||||
a = Video(video.file_id, self.width, self.height, self.duration)
|
||||
b = Video(video.file_id, self.width, self.height, self.duration)
|
||||
c = Video(video.file_id, 0, 0, 0)
|
||||
d = Video('', self.width, self.height, self.duration)
|
||||
e = Voice(video.file_id, self.duration)
|
||||
a = Video(video.file_id, video.file_unique_id, self.width, self.height, self.duration)
|
||||
b = Video('', video.file_unique_id, self.width, self.height, self.duration)
|
||||
c = Video(video.file_id, video.file_unique_id, 0, 0, 0)
|
||||
d = Video('', '', self.width, self.height, self.duration)
|
||||
e = Voice(video.file_id, video.file_unique_id, self.duration)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -47,16 +47,22 @@ class TestVideoNote(object):
|
|||
thumb_file_size = 11547
|
||||
|
||||
caption = u'VideoNoteTest - Caption'
|
||||
videonote_file_id = '5a3128a4d2a04750b5b58397f3b5e812'
|
||||
videonote_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
|
||||
|
||||
def test_creation(self, video_note):
|
||||
# Make sure file has been uploaded.
|
||||
assert isinstance(video_note, VideoNote)
|
||||
assert isinstance(video_note.file_id, str)
|
||||
assert isinstance(video_note.file_unique_id, str)
|
||||
assert video_note.file_id != ''
|
||||
assert video_note.file_unique_id != ''
|
||||
|
||||
assert isinstance(video_note.thumb, PhotoSize)
|
||||
assert isinstance(video_note.thumb.file_id, str)
|
||||
assert isinstance(video_note.thumb.file_unique_id, str)
|
||||
assert video_note.thumb.file_id != ''
|
||||
assert video_note.thumb.file_unique_id != ''
|
||||
|
||||
def test_expected_values(self, video_note):
|
||||
assert video_note.length == self.length
|
||||
|
@ -72,7 +78,9 @@ class TestVideoNote(object):
|
|||
|
||||
assert isinstance(message.video_note, VideoNote)
|
||||
assert isinstance(message.video_note.file_id, str)
|
||||
assert isinstance(message.video_note.file_unique_id, str)
|
||||
assert message.video_note.file_id != ''
|
||||
assert message.video_note.file_unique_id != ''
|
||||
assert message.video_note.length == video_note.length
|
||||
assert message.video_note.duration == video_note.duration
|
||||
assert message.video_note.file_size == video_note.file_size
|
||||
|
@ -88,6 +96,7 @@ class TestVideoNote(object):
|
|||
|
||||
assert new_file.file_size == self.file_size
|
||||
assert new_file.file_id == video_note.file_id
|
||||
assert new_file.file_unique_id == video_note.file_unique_id
|
||||
assert new_file.file_path.startswith('https://')
|
||||
|
||||
new_file.download('telegram2.mp4')
|
||||
|
@ -96,7 +105,6 @@ class TestVideoNote(object):
|
|||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
@pytest.mark.skip(reason='Doesnt work without API 4.5')
|
||||
def test_resend(self, bot, chat_id, video_note):
|
||||
message = bot.send_video_note(chat_id, video_note.file_id)
|
||||
|
||||
|
@ -112,14 +120,16 @@ class TestVideoNote(object):
|
|||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
'file_id': 'not a file id',
|
||||
'file_id': self.videonote_file_id,
|
||||
'file_unique_id': self.videonote_file_unique_id,
|
||||
'length': self.length,
|
||||
'duration': self.duration,
|
||||
'file_size': self.file_size
|
||||
}
|
||||
json_video_note = VideoNote.de_json(json_dict, bot)
|
||||
|
||||
assert json_video_note.file_id == 'not a file id'
|
||||
assert json_video_note.file_id == self.videonote_file_id
|
||||
assert json_video_note.file_unique_id == self.videonote_file_unique_id
|
||||
assert json_video_note.length == self.length
|
||||
assert json_video_note.duration == self.duration
|
||||
assert json_video_note.file_size == self.file_size
|
||||
|
@ -129,6 +139,7 @@ class TestVideoNote(object):
|
|||
|
||||
assert isinstance(video_note_dict, dict)
|
||||
assert video_note_dict['file_id'] == video_note.file_id
|
||||
assert video_note_dict['file_unique_id'] == video_note.file_unique_id
|
||||
assert video_note_dict['length'] == video_note.length
|
||||
assert video_note_dict['duration'] == video_note.duration
|
||||
assert video_note_dict['file_size'] == video_note.file_size
|
||||
|
@ -157,11 +168,11 @@ class TestVideoNote(object):
|
|||
assert video_note.get_file()
|
||||
|
||||
def test_equality(self, video_note):
|
||||
a = VideoNote(video_note.file_id, self.length, self.duration)
|
||||
b = VideoNote(video_note.file_id, self.length, self.duration)
|
||||
c = VideoNote(video_note.file_id, 0, 0)
|
||||
d = VideoNote('', self.length, self.duration)
|
||||
e = Voice(video_note.file_id, self.duration)
|
||||
a = VideoNote(video_note.file_id, video_note.file_unique_id, self.length, self.duration)
|
||||
b = VideoNote('', video_note.file_unique_id, self.length, self.duration)
|
||||
c = VideoNote(video_note.file_id, video_note.file_unique_id, 0, 0)
|
||||
d = VideoNote('', '', self.length, self.duration)
|
||||
e = Voice(video_note.file_id, video_note.file_unique_id, self.duration)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
|
@ -46,11 +46,16 @@ class TestVoice(object):
|
|||
caption = u'Test *voice*'
|
||||
voice_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.ogg'
|
||||
|
||||
voice_file_id = '5a3128a4d2a04750b5b58397f3b5e812'
|
||||
voice_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e'
|
||||
|
||||
def test_creation(self, voice):
|
||||
# Make sure file has been uploaded.
|
||||
assert isinstance(voice, Voice)
|
||||
assert isinstance(voice.file_id, str)
|
||||
assert isinstance(voice.file_unique_id, str)
|
||||
assert voice.file_id != ''
|
||||
assert voice.file_unique_id != ''
|
||||
|
||||
def test_expected_values(self, voice):
|
||||
assert voice.duration == self.duration
|
||||
|
@ -66,7 +71,9 @@ class TestVoice(object):
|
|||
|
||||
assert isinstance(message.voice, Voice)
|
||||
assert isinstance(message.voice.file_id, str)
|
||||
assert isinstance(message.voice.file_unique_id, str)
|
||||
assert message.voice.file_id != ''
|
||||
assert message.voice.file_unique_id != ''
|
||||
assert message.voice.duration == voice.duration
|
||||
assert message.voice.mime_type == voice.mime_type
|
||||
assert message.voice.file_size == voice.file_size
|
||||
|
@ -79,6 +86,7 @@ class TestVoice(object):
|
|||
|
||||
assert new_file.file_size == voice.file_size
|
||||
assert new_file.file_id == voice.file_id
|
||||
assert new_file.file_unique_id == voice.file_unique_id
|
||||
assert new_file.file_path.startswith('https://')
|
||||
|
||||
new_file.download('telegram.ogg')
|
||||
|
@ -92,14 +100,15 @@ class TestVoice(object):
|
|||
|
||||
assert isinstance(message.voice, Voice)
|
||||
assert isinstance(message.voice.file_id, str)
|
||||
assert isinstance(message.voice.file_unique_id, str)
|
||||
assert message.voice.file_id != ''
|
||||
assert message.voice.file_unique_id != ''
|
||||
assert message.voice.duration == voice.duration
|
||||
assert message.voice.mime_type == voice.mime_type
|
||||
assert message.voice.file_size == voice.file_size
|
||||
|
||||
@flaky(3, 1)
|
||||
@pytest.mark.timeout(10)
|
||||
@pytest.mark.skip(reason='Doesnt work without API 4.5')
|
||||
def test_resend(self, bot, chat_id, voice):
|
||||
message = bot.sendVoice(chat_id, voice.file_id)
|
||||
|
||||
|
@ -148,7 +157,8 @@ class TestVoice(object):
|
|||
|
||||
def test_de_json(self, bot):
|
||||
json_dict = {
|
||||
'file_id': 'not a file id',
|
||||
'file_id': self.voice_file_id,
|
||||
'file_unique_id': self.voice_file_unique_id,
|
||||
'duration': self.duration,
|
||||
'caption': self.caption,
|
||||
'mime_type': self.mime_type,
|
||||
|
@ -156,7 +166,8 @@ class TestVoice(object):
|
|||
}
|
||||
json_voice = Voice.de_json(json_dict, bot)
|
||||
|
||||
assert json_voice.file_id == 'not a file id'
|
||||
assert json_voice.file_id == self.voice_file_id
|
||||
assert json_voice.file_unique_id == self.voice_file_unique_id
|
||||
assert json_voice.duration == self.duration
|
||||
assert json_voice.mime_type == self.mime_type
|
||||
assert json_voice.file_size == self.file_size
|
||||
|
@ -166,6 +177,7 @@ class TestVoice(object):
|
|||
|
||||
assert isinstance(voice_dict, dict)
|
||||
assert voice_dict['file_id'] == voice.file_id
|
||||
assert voice_dict['file_unique_id'] == voice.file_unique_id
|
||||
assert voice_dict['duration'] == voice.duration
|
||||
assert voice_dict['mime_type'] == voice.mime_type
|
||||
assert voice_dict['file_size'] == voice.file_size
|
||||
|
@ -194,11 +206,11 @@ class TestVoice(object):
|
|||
assert voice.get_file()
|
||||
|
||||
def test_equality(self, voice):
|
||||
a = Voice(voice.file_id, self.duration)
|
||||
b = Voice(voice.file_id, self.duration)
|
||||
c = Voice(voice.file_id, 0)
|
||||
d = Voice('', self.duration)
|
||||
e = Audio(voice.file_id, self.duration)
|
||||
a = Voice(voice.file_id, voice.file_unique_id, self.duration)
|
||||
b = Voice('', voice.file_unique_id, self.duration)
|
||||
c = Voice(voice.file_id, voice.file_unique_id, 0)
|
||||
d = Voice('', '', self.duration)
|
||||
e = Audio(voice.file_id, voice.file_unique_id, self.duration)
|
||||
|
||||
assert a == b
|
||||
assert hash(a) == hash(b)
|
||||
|
|
Loading…
Add table
Reference in a new issue