Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions telegram/bot.py

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions telegram/ext/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class Defaults:
receive a notification with no sound.
disable_web_page_preview (:obj:`bool`): Optional. Disables link previews for links in this
message.
allow_sending_without_reply (:obj:`bool`): Optional. Pass :obj:`True`, if the message
should be sent even if the specified replied-to message is not found.
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).
Expand All @@ -51,6 +53,8 @@ class Defaults:
receive a notification with no sound.
disable_web_page_preview (:obj:`bool`, optional): Disables link previews for links in this
message.
allow_sending_without_reply (:obj:`bool`, optional): Pass :obj:`True`, if the message
should be sent even if the specified replied-to message is not found.
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).
Expand All @@ -73,10 +77,12 @@ def __init__(
timeout: Union[float, DefaultValue] = DEFAULT_NONE,
quote: bool = None,
tzinfo: pytz.BaseTzInfo = pytz.utc,
allow_sending_without_reply: bool = None,
):
self._parse_mode = parse_mode
self._disable_notification = disable_notification
self._disable_web_page_preview = disable_web_page_preview
self._allow_sending_without_reply = allow_sending_without_reply
self._timeout = timeout
self._quote = quote
self._tzinfo = tzinfo
Expand Down Expand Up @@ -114,6 +120,17 @@ def disable_web_page_preview(self, value: Any) -> NoReturn:
"not have any effect."
)

@property
def allow_sending_without_reply(self) -> Optional[bool]:
return self._allow_sending_without_reply

@allow_sending_without_reply.setter
def allow_sending_without_reply(self, value: Any) -> NoReturn:
raise AttributeError(
"You can not assign a new value to defaults after because it would "
"not have any effect."
)

@property
def timeout(self) -> Union[float, DefaultValue]:
return self._timeout
Expand Down Expand Up @@ -153,6 +170,7 @@ def __hash__(self) -> int:
self._parse_mode,
self._disable_notification,
self._disable_web_page_preview,
self._allow_sending_without_reply,
self._timeout,
self._quote,
self._tzinfo,
Expand Down
36 changes: 36 additions & 0 deletions tests/test_animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from flaky import flaky

from telegram import PhotoSize, Animation, Voice, TelegramError
from telegram.error import BadRequest
from telegram.utils.helpers import escape_markdown


Expand Down Expand Up @@ -161,6 +162,41 @@ def test_send_animation_default_parse_mode_3(self, default_bot, chat_id, animati
assert message.caption == test_markdown_string
assert message.caption_markdown == escape_markdown(test_markdown_string)

@flaky(3, 1)
@pytest.mark.timeout(10)
@pytest.mark.parametrize(
'default_bot,custom',
[
({'allow_sending_without_reply': True}, None),
({'allow_sending_without_reply': False}, None),
({'allow_sending_without_reply': False}, True),
],
indirect=['default_bot'],
)
def test_send_animation_default_allow_sending_without_reply(
self, default_bot, chat_id, animation, custom
):
reply_to_message = default_bot.send_message(chat_id, 'test')
reply_to_message.delete()
if custom is not None:
message = default_bot.send_animation(
chat_id,
animation,
allow_sending_without_reply=custom,
reply_to_message_id=reply_to_message.message_id,
)
assert message.reply_to_message is None
elif default_bot.defaults.allow_sending_without_reply:
message = default_bot.send_animation(
chat_id, animation, reply_to_message_id=reply_to_message.message_id
)
assert message.reply_to_message is None
else:
with pytest.raises(BadRequest, match='message not found'):
default_bot.send_animation(
chat_id, animation, reply_to_message_id=reply_to_message.message_id
)

@flaky(3, 1)
@pytest.mark.timeout(10)
def test_resend(self, bot, chat_id, animation):
Expand Down
142 changes: 142 additions & 0 deletions tests/test_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,48 @@ def test_send_poll_default_parse_mode(self, default_bot, super_group_id):
assert message.poll.explanation == explanation_markdown
assert message.poll.explanation_entities == []

@flaky(3, 1)
@pytest.mark.timeout(10)
@pytest.mark.parametrize(
'default_bot,custom',
[
({'allow_sending_without_reply': True}, None),
({'allow_sending_without_reply': False}, None),
({'allow_sending_without_reply': False}, True),
],
indirect=['default_bot'],
)
def test_send_poll_default_allow_sending_without_reply(self, default_bot, chat_id, custom):
question = 'Is this a test?'
answers = ['Yes', 'No', 'Maybe']
reply_to_message = default_bot.send_message(chat_id, 'test')
reply_to_message.delete()
if custom is not None:
message = default_bot.send_poll(
chat_id,
question=question,
options=answers,
allow_sending_without_reply=custom,
reply_to_message_id=reply_to_message.message_id,
)
assert message.reply_to_message is None
elif default_bot.defaults.allow_sending_without_reply:
message = default_bot.send_poll(
chat_id,
question=question,
options=answers,
reply_to_message_id=reply_to_message.message_id,
)
assert message.reply_to_message is None
else:
with pytest.raises(BadRequest, match='message not found'):
default_bot.send_poll(
chat_id,
question=question,
options=answers,
reply_to_message_id=reply_to_message.message_id,
)

@flaky(3, 1)
@pytest.mark.timeout(10)
@pytest.mark.parametrize('emoji', Dice.ALL_EMOJI + [None])
Expand All @@ -435,6 +477,37 @@ def test_send_dice(self, bot, chat_id, emoji):
else:
assert message.dice.emoji == emoji

@flaky(3, 1)
@pytest.mark.timeout(10)
@pytest.mark.parametrize(
'default_bot,custom',
[
({'allow_sending_without_reply': True}, None),
({'allow_sending_without_reply': False}, None),
({'allow_sending_without_reply': False}, True),
],
indirect=['default_bot'],
)
def test_send_dice_default_allow_sending_without_reply(self, default_bot, chat_id, custom):
reply_to_message = default_bot.send_message(chat_id, 'test')
reply_to_message.delete()
if custom is not None:
message = default_bot.send_dice(
chat_id,
allow_sending_without_reply=custom,
reply_to_message_id=reply_to_message.message_id,
)
assert message.reply_to_message is None
elif default_bot.defaults.allow_sending_without_reply:
message = default_bot.send_dice(
chat_id,
reply_to_message_id=reply_to_message.message_id,
)
assert message.reply_to_message is None
else:
with pytest.raises(BadRequest, match='message not found'):
default_bot.send_dice(chat_id, reply_to_message_id=reply_to_message.message_id)

@flaky(3, 1)
@pytest.mark.timeout(10)
def test_send_chat_action(self, bot, chat_id):
Expand Down Expand Up @@ -1018,6 +1091,42 @@ def test_send_game(self, bot, chat_id):
assert message.game.animation.file_id != ''
assert message.game.photo[0].file_size == 851

@flaky(3, 1)
@pytest.mark.timeout(10)
@pytest.mark.parametrize(
'default_bot,custom',
[
({'allow_sending_without_reply': True}, None),
({'allow_sending_without_reply': False}, None),
({'allow_sending_without_reply': False}, True),
],
indirect=['default_bot'],
)
def test_send_game_default_allow_sending_without_reply(self, default_bot, chat_id, custom):
game_short_name = 'test_game'
reply_to_message = default_bot.send_message(chat_id, 'test')
reply_to_message.delete()
if custom is not None:
message = default_bot.send_game(
chat_id,
game_short_name,
allow_sending_without_reply=custom,
reply_to_message_id=reply_to_message.message_id,
)
assert message.reply_to_message is None
elif default_bot.defaults.allow_sending_without_reply:
message = default_bot.send_game(
chat_id,
game_short_name,
reply_to_message_id=reply_to_message.message_id,
)
assert message.reply_to_message is None
else:
with pytest.raises(BadRequest, match='message not found'):
default_bot.send_game(
chat_id, game_short_name, reply_to_message_id=reply_to_message.message_id
)

@flaky(3, 1)
@pytest.mark.timeout(10)
def test_set_game_score_1(self, bot, chat_id):
Expand Down Expand Up @@ -1376,6 +1485,39 @@ def test_send_message_default_parse_mode(self, default_bot, chat_id):
assert message.text == test_markdown_string
assert message.text_markdown == escape_markdown(test_markdown_string)

@flaky(3, 1)
@pytest.mark.timeout(10)
@pytest.mark.parametrize(
'default_bot,custom',
[
({'allow_sending_without_reply': True}, None),
({'allow_sending_without_reply': False}, None),
({'allow_sending_without_reply': False}, True),
],
indirect=['default_bot'],
)
def test_send_message_default_allow_sending_without_reply(self, default_bot, chat_id, custom):
reply_to_message = default_bot.send_message(chat_id, 'test')
reply_to_message.delete()
if custom is not None:
message = default_bot.send_message(
chat_id,
'test',
allow_sending_without_reply=custom,
reply_to_message_id=reply_to_message.message_id,
)
assert message.reply_to_message is None
elif default_bot.defaults.allow_sending_without_reply:
message = default_bot.send_message(
chat_id, 'test', reply_to_message_id=reply_to_message.message_id
)
assert message.reply_to_message is None
else:
with pytest.raises(BadRequest, match='message not found'):
default_bot.send_message(
chat_id, 'test', reply_to_message_id=reply_to_message.message_id
)

@flaky(3, 1)
@pytest.mark.timeout(10)
def test_set_and_get_my_commands(self, bot):
Expand Down
37 changes: 37 additions & 0 deletions tests/test_contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].

import pytest
from flaky import flaky

from telegram import Contact, Voice
from telegram.error import BadRequest


@pytest.fixture(scope='class')
Expand Down Expand Up @@ -70,6 +72,41 @@ def test(url, data, **kwargs):
message = bot.send_contact(contact=contact, chat_id=chat_id)
assert message

@flaky(3, 1)
@pytest.mark.timeout(10)
@pytest.mark.parametrize(
'default_bot,custom',
[
({'allow_sending_without_reply': True}, None),
({'allow_sending_without_reply': False}, None),
({'allow_sending_without_reply': False}, True),
],
indirect=['default_bot'],
)
def test_send_contact_default_allow_sending_without_reply(
self, default_bot, chat_id, contact, custom
):
reply_to_message = default_bot.send_message(chat_id, 'test')
reply_to_message.delete()
if custom is not None:
message = default_bot.send_contact(
chat_id,
contact=contact,
allow_sending_without_reply=custom,
reply_to_message_id=reply_to_message.message_id,
)
assert message.reply_to_message is None
elif default_bot.defaults.allow_sending_without_reply:
message = default_bot.send_contact(
chat_id, contact=contact, reply_to_message_id=reply_to_message.message_id
)
assert message.reply_to_message is None
else:
with pytest.raises(BadRequest, match='message not found'):
default_bot.send_contact(
chat_id, contact=contact, reply_to_message_id=reply_to_message.message_id
)

def test_send_contact_without_required(self, bot, chat_id):
with pytest.raises(ValueError, match='Either contact or phone_number and first_name'):
bot.send_contact(chat_id=chat_id)
Expand Down
2 changes: 2 additions & 0 deletions tests/test_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ def test_data_assignment(self, cdp):
defaults.disable_notification = True
with pytest.raises(AttributeError):
defaults.disable_web_page_preview = True
with pytest.raises(AttributeError):
defaults.allow_sending_without_reply = True
with pytest.raises(AttributeError):
defaults.timeout = True
with pytest.raises(AttributeError):
Expand Down
36 changes: 36 additions & 0 deletions tests/test_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from flaky import flaky

from telegram import Document, PhotoSize, TelegramError, Voice
from telegram.error import BadRequest
from telegram.utils.helpers import escape_markdown


Expand Down Expand Up @@ -184,6 +185,41 @@ def test_send_document_default_parse_mode_3(self, default_bot, chat_id, document
assert message.caption == test_markdown_string
assert message.caption_markdown == escape_markdown(test_markdown_string)

@flaky(3, 1)
@pytest.mark.timeout(10)
@pytest.mark.parametrize(
'default_bot,custom',
[
({'allow_sending_without_reply': True}, None),
({'allow_sending_without_reply': False}, None),
({'allow_sending_without_reply': False}, True),
],
indirect=['default_bot'],
)
def test_send_document_default_allow_sending_without_reply(
self, default_bot, chat_id, document, custom
):
reply_to_message = default_bot.send_message(chat_id, 'test')
reply_to_message.delete()
if custom is not None:
message = default_bot.send_document(
chat_id,
document,
allow_sending_without_reply=custom,
reply_to_message_id=reply_to_message.message_id,
)
assert message.reply_to_message is None
elif default_bot.defaults.allow_sending_without_reply:
message = default_bot.send_document(
chat_id, document, reply_to_message_id=reply_to_message.message_id
)
assert message.reply_to_message is None
else:
with pytest.raises(BadRequest, match='message not found'):
default_bot.send_document(
chat_id, document, reply_to_message_id=reply_to_message.message_id
)

def test_de_json(self, bot, document):
json_dict = {
'file_id': self.document_file_id,
Expand Down
Loading