Merge pull request #2211 from freqtrade/dependabot/pip/develop/python-telegram-bot-12.0.0

Bump python-telegram-bot from 11.1.0 to 12.0.0
This commit is contained in:
hroff-1902 2019-09-04 10:44:11 +03:00 committed by GitHub
commit 74578b8752
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 158 additions and 132 deletions

View File

@ -4,12 +4,12 @@
This module manage Telegram communication This module manage Telegram communication
""" """
import logging import logging
from typing import Any, Callable, Dict, List from typing import Any, Callable, Dict
from tabulate import tabulate from tabulate import tabulate
from telegram import Bot, ParseMode, ReplyKeyboardMarkup, Update from telegram import ParseMode, ReplyKeyboardMarkup, Update
from telegram.error import NetworkError, TelegramError from telegram.error import NetworkError, TelegramError
from telegram.ext import CommandHandler, Updater from telegram.ext import CommandHandler, Updater, CallbackContext
from freqtrade.__init__ import __version__ from freqtrade.__init__ import __version__
from freqtrade.rpc import RPC, RPCException, RPCMessageType from freqtrade.rpc import RPC, RPCException, RPCMessageType
@ -31,7 +31,7 @@ def authorized_only(command_handler: Callable[..., None]) -> Callable[..., Any]:
""" """
def wrapper(self, *args, **kwargs): def wrapper(self, *args, **kwargs):
""" Decorator logic """ """ Decorator logic """
update = kwargs.get('update') or args[1] update = kwargs.get('update') or args[0]
# Reject unauthorized messages # Reject unauthorized messages
chat_id = int(self._config['telegram']['chat_id']) chat_id = int(self._config['telegram']['chat_id'])
@ -79,7 +79,8 @@ class Telegram(RPC):
registers all known command handlers registers all known command handlers
and starts polling for message updates and starts polling for message updates
""" """
self._updater = Updater(token=self._config['telegram']['token'], workers=0) self._updater = Updater(token=self._config['telegram']['token'], workers=0,
use_context=True)
# Register command handler and start telegram message polling # Register command handler and start telegram message polling
handles = [ handles = [
@ -96,7 +97,7 @@ class Telegram(RPC):
CommandHandler('reload_conf', self._reload_conf), CommandHandler('reload_conf', self._reload_conf),
CommandHandler('stopbuy', self._stopbuy), CommandHandler('stopbuy', self._stopbuy),
CommandHandler('whitelist', self._whitelist), CommandHandler('whitelist', self._whitelist),
CommandHandler('blacklist', self._blacklist, pass_args=True), CommandHandler('blacklist', self._blacklist),
CommandHandler('edge', self._edge), CommandHandler('edge', self._edge),
CommandHandler('help', self._help), CommandHandler('help', self._help),
CommandHandler('version', self._version), CommandHandler('version', self._version),
@ -175,7 +176,7 @@ class Telegram(RPC):
self._send_msg(message) self._send_msg(message)
@authorized_only @authorized_only
def _status(self, bot: Bot, update: Update) -> None: def _status(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /status. Handler for /status.
Returns the current TradeThread status Returns the current TradeThread status
@ -184,11 +185,8 @@ class Telegram(RPC):
:return: None :return: None
""" """
# Check if additional parameters are passed if 'table' in context.args:
params = update.message.text.replace('/status', '').split(' ') \ self._status_table(update, context)
if update.message.text else []
if 'table' in params:
self._status_table(bot, update)
return return
try: try:
@ -221,13 +219,13 @@ class Telegram(RPC):
messages.append("\n".join([l for l in lines if l]).format(**r)) messages.append("\n".join([l for l in lines if l]).format(**r))
for msg in messages: for msg in messages:
self._send_msg(msg, bot=bot) self._send_msg(msg)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _status_table(self, bot: Bot, update: Update) -> None: def _status_table(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /status table. Handler for /status table.
Returns the current TradeThread status in table format Returns the current TradeThread status in table format
@ -240,10 +238,10 @@ class Telegram(RPC):
message = tabulate(df_statuses, headers='keys', tablefmt='simple') message = tabulate(df_statuses, headers='keys', tablefmt='simple')
self._send_msg(f"<pre>{message}</pre>", parse_mode=ParseMode.HTML) self._send_msg(f"<pre>{message}</pre>", parse_mode=ParseMode.HTML)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _daily(self, bot: Bot, update: Update) -> None: def _daily(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /daily <n> Handler for /daily <n>
Returns a daily profit (in BTC) over the last n days. Returns a daily profit (in BTC) over the last n days.
@ -254,8 +252,8 @@ class Telegram(RPC):
stake_cur = self._config['stake_currency'] stake_cur = self._config['stake_currency']
fiat_disp_cur = self._config.get('fiat_display_currency', '') fiat_disp_cur = self._config.get('fiat_display_currency', '')
try: try:
timescale = int(update.message.text.replace('/daily', '').strip()) timescale = int(context.args[0])
except (TypeError, ValueError): except (TypeError, ValueError, IndexError):
timescale = 7 timescale = 7
try: try:
stats = self._rpc_daily_profit( stats = self._rpc_daily_profit(
@ -272,12 +270,12 @@ class Telegram(RPC):
], ],
tablefmt='simple') tablefmt='simple')
message = f'<b>Daily Profit over the last {timescale} days</b>:\n<pre>{stats_tab}</pre>' message = f'<b>Daily Profit over the last {timescale} days</b>:\n<pre>{stats_tab}</pre>'
self._send_msg(message, bot=bot, parse_mode=ParseMode.HTML) self._send_msg(message, parse_mode=ParseMode.HTML)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _profit(self, bot: Bot, update: Update) -> None: def _profit(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /profit. Handler for /profit.
Returns a cumulative profit statistics. Returns a cumulative profit statistics.
@ -317,12 +315,12 @@ class Telegram(RPC):
f"*Latest Trade opened:* `{latest_trade_date}`\n" \ f"*Latest Trade opened:* `{latest_trade_date}`\n" \
f"*Avg. Duration:* `{avg_duration}`\n" \ f"*Avg. Duration:* `{avg_duration}`\n" \
f"*Best Performing:* `{best_pair}: {best_rate:.2f}%`" f"*Best Performing:* `{best_pair}: {best_rate:.2f}%`"
self._send_msg(markdown_msg, bot=bot) self._send_msg(markdown_msg)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _balance(self, bot: Bot, update: Update) -> None: def _balance(self, update: Update, context: CallbackContext) -> None:
""" Handler for /balance """ """ Handler for /balance """
try: try:
result = self._rpc_balance(self._config.get('fiat_display_currency', '')) result = self._rpc_balance(self._config.get('fiat_display_currency', ''))
@ -339,7 +337,7 @@ class Telegram(RPC):
# Handle overflowing messsage length # Handle overflowing messsage length
if len(output + curr_output) >= MAX_TELEGRAM_MESSAGE_LENGTH: if len(output + curr_output) >= MAX_TELEGRAM_MESSAGE_LENGTH:
self._send_msg(output, bot=bot) self._send_msg(output)
output = curr_output output = curr_output
else: else:
output += curr_output output += curr_output
@ -347,12 +345,12 @@ class Telegram(RPC):
output += "\n*Estimated Value*:\n" \ output += "\n*Estimated Value*:\n" \
"\t`BTC: {total: .8f}`\n" \ "\t`BTC: {total: .8f}`\n" \
"\t`{symbol}: {value: .2f}`\n".format(**result) "\t`{symbol}: {value: .2f}`\n".format(**result)
self._send_msg(output, bot=bot) self._send_msg(output)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _start(self, bot: Bot, update: Update) -> None: def _start(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /start. Handler for /start.
Starts TradeThread Starts TradeThread
@ -361,10 +359,10 @@ class Telegram(RPC):
:return: None :return: None
""" """
msg = self._rpc_start() msg = self._rpc_start()
self._send_msg('Status: `{status}`'.format(**msg), bot=bot) self._send_msg('Status: `{status}`'.format(**msg))
@authorized_only @authorized_only
def _stop(self, bot: Bot, update: Update) -> None: def _stop(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /stop. Handler for /stop.
Stops TradeThread Stops TradeThread
@ -373,10 +371,10 @@ class Telegram(RPC):
:return: None :return: None
""" """
msg = self._rpc_stop() msg = self._rpc_stop()
self._send_msg('Status: `{status}`'.format(**msg), bot=bot) self._send_msg('Status: `{status}`'.format(**msg))
@authorized_only @authorized_only
def _reload_conf(self, bot: Bot, update: Update) -> None: def _reload_conf(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /reload_conf. Handler for /reload_conf.
Triggers a config file reload Triggers a config file reload
@ -385,10 +383,10 @@ class Telegram(RPC):
:return: None :return: None
""" """
msg = self._rpc_reload_conf() msg = self._rpc_reload_conf()
self._send_msg('Status: `{status}`'.format(**msg), bot=bot) self._send_msg('Status: `{status}`'.format(**msg))
@authorized_only @authorized_only
def _stopbuy(self, bot: Bot, update: Update) -> None: def _stopbuy(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /stop_buy. Handler for /stop_buy.
Sets max_open_trades to 0 and gracefully sells all open trades Sets max_open_trades to 0 and gracefully sells all open trades
@ -397,10 +395,10 @@ class Telegram(RPC):
:return: None :return: None
""" """
msg = self._rpc_stopbuy() msg = self._rpc_stopbuy()
self._send_msg('Status: `{status}`'.format(**msg), bot=bot) self._send_msg('Status: `{status}`'.format(**msg))
@authorized_only @authorized_only
def _forcesell(self, bot: Bot, update: Update) -> None: def _forcesell(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /forcesell <id>. Handler for /forcesell <id>.
Sells the given trade at current price Sells the given trade at current price
@ -409,16 +407,16 @@ class Telegram(RPC):
:return: None :return: None
""" """
trade_id = update.message.text.replace('/forcesell', '').strip() trade_id = context.args[0] if len(context.args) > 0 else None
try: try:
msg = self._rpc_forcesell(trade_id) msg = self._rpc_forcesell(trade_id)
self._send_msg('Forcesell Result: `{result}`'.format(**msg), bot=bot) self._send_msg('Forcesell Result: `{result}`'.format(**msg))
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _forcebuy(self, bot: Bot, update: Update) -> None: def _forcebuy(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /forcebuy <asset> <price>. Handler for /forcebuy <asset> <price>.
Buys a pair trade at the given or current price Buys a pair trade at the given or current price
@ -427,16 +425,15 @@ class Telegram(RPC):
:return: None :return: None
""" """
message = update.message.text.replace('/forcebuy', '').strip().split() pair = context.args[0]
pair = message[0] price = float(context.args[1]) if len(context.args) > 1 else None
price = float(message[1]) if len(message) > 1 else None
try: try:
self._rpc_forcebuy(pair, price) self._rpc_forcebuy(pair, price)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _performance(self, bot: Bot, update: Update) -> None: def _performance(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /performance. Handler for /performance.
Shows a performance statistic from finished trades Shows a performance statistic from finished trades
@ -455,10 +452,10 @@ class Telegram(RPC):
message = '<b>Performance:</b>\n{}'.format(stats) message = '<b>Performance:</b>\n{}'.format(stats)
self._send_msg(message, parse_mode=ParseMode.HTML) self._send_msg(message, parse_mode=ParseMode.HTML)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _count(self, bot: Bot, update: Update) -> None: def _count(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /count. Handler for /count.
Returns the number of trades running Returns the number of trades running
@ -475,10 +472,10 @@ class Telegram(RPC):
logger.debug(message) logger.debug(message)
self._send_msg(message, parse_mode=ParseMode.HTML) self._send_msg(message, parse_mode=ParseMode.HTML)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _whitelist(self, bot: Bot, update: Update) -> None: def _whitelist(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /whitelist Handler for /whitelist
Shows the currently active whitelist Shows the currently active whitelist
@ -492,17 +489,17 @@ class Telegram(RPC):
logger.debug(message) logger.debug(message)
self._send_msg(message) self._send_msg(message)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _blacklist(self, bot: Bot, update: Update, args: List[str]) -> None: def _blacklist(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /blacklist Handler for /blacklist
Shows the currently active blacklist Shows the currently active blacklist
""" """
try: try:
blacklist = self._rpc_blacklist(args) blacklist = self._rpc_blacklist(context.args)
message = f"Blacklist contains {blacklist['length']} pairs\n" message = f"Blacklist contains {blacklist['length']} pairs\n"
message += f"`{', '.join(blacklist['blacklist'])}`" message += f"`{', '.join(blacklist['blacklist'])}`"
@ -510,10 +507,10 @@ class Telegram(RPC):
logger.debug(message) logger.debug(message)
self._send_msg(message) self._send_msg(message)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _edge(self, bot: Bot, update: Update) -> None: def _edge(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /edge Handler for /edge
Shows information related to Edge Shows information related to Edge
@ -522,12 +519,12 @@ class Telegram(RPC):
edge_pairs = self._rpc_edge() edge_pairs = self._rpc_edge()
edge_pairs_tab = tabulate(edge_pairs, headers='keys', tablefmt='simple') edge_pairs_tab = tabulate(edge_pairs, headers='keys', tablefmt='simple')
message = f'<b>Edge only validated following pairs:</b>\n<pre>{edge_pairs_tab}</pre>' message = f'<b>Edge only validated following pairs:</b>\n<pre>{edge_pairs_tab}</pre>'
self._send_msg(message, bot=bot, parse_mode=ParseMode.HTML) self._send_msg(message, parse_mode=ParseMode.HTML)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e))
@authorized_only @authorized_only
def _help(self, bot: Bot, update: Update) -> None: def _help(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /help. Handler for /help.
Show commands of the bot Show commands of the bot
@ -559,10 +556,10 @@ class Telegram(RPC):
"*/help:* `This help message`\n" \ "*/help:* `This help message`\n" \
"*/version:* `Show version`" "*/version:* `Show version`"
self._send_msg(message, bot=bot) self._send_msg(message)
@authorized_only @authorized_only
def _version(self, bot: Bot, update: Update) -> None: def _version(self, update: Update, context: CallbackContext) -> None:
""" """
Handler for /version. Handler for /version.
Show version information Show version information
@ -570,10 +567,9 @@ class Telegram(RPC):
:param update: message update :param update: message update
:return: None :return: None
""" """
self._send_msg('*Version:* `{}`'.format(__version__), bot=bot) self._send_msg('*Version:* `{}`'.format(__version__))
def _send_msg(self, msg: str, bot: Bot = None, def _send_msg(self, msg: str, parse_mode: ParseMode = ParseMode.MARKDOWN) -> None:
parse_mode: ParseMode = ParseMode.MARKDOWN) -> None:
""" """
Send given markdown message Send given markdown message
:param msg: message :param msg: message
@ -581,7 +577,6 @@ class Telegram(RPC):
:param parse_mode: telegram parse mode :param parse_mode: telegram parse mode
:return: None :return: None
""" """
bot = bot or self._updater.bot
keyboard = [['/daily', '/profit', '/balance'], keyboard = [['/daily', '/profit', '/balance'],
['/status', '/status table', '/performance'], ['/status', '/status table', '/performance'],
@ -591,7 +586,7 @@ class Telegram(RPC):
try: try:
try: try:
bot.send_message( self._updater.bot.send_message(
self._config['telegram']['chat_id'], self._config['telegram']['chat_id'],
text=msg, text=msg,
parse_mode=parse_mode, parse_mode=parse_mode,
@ -604,7 +599,7 @@ class Telegram(RPC):
'Telegram NetworkError: %s! Trying one more time.', 'Telegram NetworkError: %s! Trying one more time.',
network_err.message network_err.message
) )
bot.send_message( self._updater.bot.send_message(
self._config['telegram']['chat_id'], self._config['telegram']['chat_id'],
text=msg, text=msg,
parse_mode=parse_mode, parse_mode=parse_mode,

View File

@ -100,7 +100,7 @@ def test_authorized_only(default_conf, mocker, caplog) -> None:
bot = FreqtradeBot(default_conf) bot = FreqtradeBot(default_conf)
patch_get_signal(bot, (True, False)) patch_get_signal(bot, (True, False))
dummy = DummyCls(bot) dummy = DummyCls(bot)
dummy.dummy_handler(bot=MagicMock(), update=update) dummy.dummy_handler(update=update, context=MagicMock())
assert dummy.state['called'] is True assert dummy.state['called'] is True
assert log_has('Executing handler: dummy_handler for chat_id: 0', caplog) assert log_has('Executing handler: dummy_handler for chat_id: 0', caplog)
assert not log_has('Rejected unauthorized message from: 0', caplog) assert not log_has('Rejected unauthorized message from: 0', caplog)
@ -117,7 +117,7 @@ def test_authorized_only_unauthorized(default_conf, mocker, caplog) -> None:
bot = FreqtradeBot(default_conf) bot = FreqtradeBot(default_conf)
patch_get_signal(bot, (True, False)) patch_get_signal(bot, (True, False))
dummy = DummyCls(bot) dummy = DummyCls(bot)
dummy.dummy_handler(bot=MagicMock(), update=update) dummy.dummy_handler(update=update, context=MagicMock())
assert dummy.state['called'] is False assert dummy.state['called'] is False
assert not log_has('Executing handler: dummy_handler for chat_id: 3735928559', caplog) assert not log_has('Executing handler: dummy_handler for chat_id: 3735928559', caplog)
assert log_has('Rejected unauthorized message from: 3735928559', caplog) assert log_has('Rejected unauthorized message from: 3735928559', caplog)
@ -136,7 +136,7 @@ def test_authorized_only_exception(default_conf, mocker, caplog) -> None:
patch_get_signal(bot, (True, False)) patch_get_signal(bot, (True, False))
dummy = DummyCls(bot) dummy = DummyCls(bot)
dummy.dummy_exception(bot=MagicMock(), update=update) dummy.dummy_exception(update=update, context=MagicMock())
assert dummy.state['called'] is False assert dummy.state['called'] is False
assert not log_has('Executing handler: dummy_handler for chat_id: 0', caplog) assert not log_has('Executing handler: dummy_handler for chat_id: 0', caplog)
assert not log_has('Rejected unauthorized message from: 0', caplog) assert not log_has('Rejected unauthorized message from: 0', caplog)
@ -194,12 +194,13 @@ def test_status(default_conf, update, mocker, fee, ticker, markets) -> None:
for _ in range(3): for _ in range(3):
freqtradebot.create_trades() freqtradebot.create_trades()
telegram._status(bot=MagicMock(), update=update) telegram._status(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
update.message.text = MagicMock() context = MagicMock()
update.message.text.replace = MagicMock(return_value='table 2 3') # /status table 2 3
telegram._status(bot=MagicMock(), update=update) context.args = ["table", "2", "3"]
telegram._status(update=update, context=context)
assert status_table.call_count == 1 assert status_table.call_count == 1
@ -228,13 +229,13 @@ def test_status_handle(default_conf, update, ticker, fee, markets, mocker) -> No
freqtradebot.state = State.STOPPED freqtradebot.state = State.STOPPED
# Status is also enabled when stopped # Status is also enabled when stopped
telegram._status(bot=MagicMock(), update=update) telegram._status(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'no active trade' in msg_mock.call_args_list[0][0][0] assert 'no active trade' in msg_mock.call_args_list[0][0][0]
msg_mock.reset_mock() msg_mock.reset_mock()
freqtradebot.state = State.RUNNING freqtradebot.state = State.RUNNING
telegram._status(bot=MagicMock(), update=update) telegram._status(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'no active trade' in msg_mock.call_args_list[0][0][0] assert 'no active trade' in msg_mock.call_args_list[0][0][0]
msg_mock.reset_mock() msg_mock.reset_mock()
@ -242,7 +243,7 @@ def test_status_handle(default_conf, update, ticker, fee, markets, mocker) -> No
# Create some test data # Create some test data
freqtradebot.create_trades() freqtradebot.create_trades()
# Trigger status while we have a fulfilled order for the open trade # Trigger status while we have a fulfilled order for the open trade
telegram._status(bot=MagicMock(), update=update) telegram._status(update=update, context=MagicMock())
# close_rate should not be included in the message as the trade is not closed # close_rate should not be included in the message as the trade is not closed
# and no line should be empty # and no line should be empty
@ -280,13 +281,13 @@ def test_status_table_handle(default_conf, update, ticker, fee, markets, mocker)
freqtradebot.state = State.STOPPED freqtradebot.state = State.STOPPED
# Status table is also enabled when stopped # Status table is also enabled when stopped
telegram._status_table(bot=MagicMock(), update=update) telegram._status_table(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'no active order' in msg_mock.call_args_list[0][0][0] assert 'no active order' in msg_mock.call_args_list[0][0][0]
msg_mock.reset_mock() msg_mock.reset_mock()
freqtradebot.state = State.RUNNING freqtradebot.state = State.RUNNING
telegram._status_table(bot=MagicMock(), update=update) telegram._status_table(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'no active order' in msg_mock.call_args_list[0][0][0] assert 'no active order' in msg_mock.call_args_list[0][0][0]
msg_mock.reset_mock() msg_mock.reset_mock()
@ -294,7 +295,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, markets, mocker)
# Create some test data # Create some test data
freqtradebot.create_trades() freqtradebot.create_trades()
telegram._status_table(bot=MagicMock(), update=update) telegram._status_table(update=update, context=MagicMock())
text = re.sub('</?pre>', '', msg_mock.call_args_list[-1][0][0]) text = re.sub('</?pre>', '', msg_mock.call_args_list[-1][0][0])
line = text.split("\n") line = text.split("\n")
@ -346,8 +347,10 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
trade.is_open = False trade.is_open = False
# Try valid data # Try valid data
update.message.text = '/daily 2' # /daily 2
telegram._daily(bot=MagicMock(), update=update) context = MagicMock()
context.args = ["2"]
telegram._daily(update=update, context=context)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'Daily' in msg_mock.call_args_list[0][0][0] assert 'Daily' in msg_mock.call_args_list[0][0][0]
assert str(datetime.utcnow().date()) in msg_mock.call_args_list[0][0][0] assert str(datetime.utcnow().date()) in msg_mock.call_args_list[0][0][0]
@ -369,9 +372,10 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
trade.close_date = datetime.utcnow() trade.close_date = datetime.utcnow()
trade.is_open = False trade.is_open = False
update.message.text = '/daily 1' # /daily 1
context = MagicMock()
telegram._daily(bot=MagicMock(), update=update) context.args = ["1"]
telegram._daily(update=update, context=context)
assert str(' 0.00018651 BTC') in msg_mock.call_args_list[0][0][0] assert str(' 0.00018651 BTC') in msg_mock.call_args_list[0][0][0]
assert str(' 2.798 USD') in msg_mock.call_args_list[0][0][0] assert str(' 2.798 USD') in msg_mock.call_args_list[0][0][0]
assert str(' 3 trades') in msg_mock.call_args_list[0][0][0] assert str(' 3 trades') in msg_mock.call_args_list[0][0][0]
@ -398,16 +402,20 @@ def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None:
# Try invalid data # Try invalid data
msg_mock.reset_mock() msg_mock.reset_mock()
freqtradebot.state = State.RUNNING freqtradebot.state = State.RUNNING
update.message.text = '/daily -2' # /daily -2
telegram._daily(bot=MagicMock(), update=update) context = MagicMock()
context.args = ["-2"]
telegram._daily(update=update, context=context)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'must be an integer greater than 0' in msg_mock.call_args_list[0][0][0] assert 'must be an integer greater than 0' in msg_mock.call_args_list[0][0][0]
# Try invalid data # Try invalid data
msg_mock.reset_mock() msg_mock.reset_mock()
freqtradebot.state = State.RUNNING freqtradebot.state = State.RUNNING
update.message.text = '/daily today' # /daily today
telegram._daily(bot=MagicMock(), update=update) context = MagicMock()
context.args = ["today"]
telegram._daily(update=update, context=context)
assert str('Daily Profit over the last 7 days') in msg_mock.call_args_list[0][0][0] assert str('Daily Profit over the last 7 days') in msg_mock.call_args_list[0][0][0]
@ -433,7 +441,7 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
patch_get_signal(freqtradebot, (True, False)) patch_get_signal(freqtradebot, (True, False))
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._profit(bot=MagicMock(), update=update) telegram._profit(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'no closed trade' in msg_mock.call_args_list[0][0][0] assert 'no closed trade' in msg_mock.call_args_list[0][0][0]
msg_mock.reset_mock() msg_mock.reset_mock()
@ -445,7 +453,7 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
# Simulate fulfilled LIMIT_BUY order for trade # Simulate fulfilled LIMIT_BUY order for trade
trade.update(limit_buy_order) trade.update(limit_buy_order)
telegram._profit(bot=MagicMock(), update=update) telegram._profit(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'no closed trade' in msg_mock.call_args_list[-1][0][0] assert 'no closed trade' in msg_mock.call_args_list[-1][0][0]
msg_mock.reset_mock() msg_mock.reset_mock()
@ -457,7 +465,7 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
trade.close_date = datetime.utcnow() trade.close_date = datetime.utcnow()
trade.is_open = False trade.is_open = False
telegram._profit(bot=MagicMock(), update=update) telegram._profit(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert '*ROI:* Close trades' in msg_mock.call_args_list[-1][0][0] assert '*ROI:* Close trades' in msg_mock.call_args_list[-1][0][0]
assert '∙ `0.00006217 BTC (6.20%)`' in msg_mock.call_args_list[-1][0][0] assert '∙ `0.00006217 BTC (6.20%)`' in msg_mock.call_args_list[-1][0][0]
@ -507,7 +515,7 @@ def test_telegram_balance_handle(default_conf, update, mocker, rpc_balance) -> N
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._balance(bot=MagicMock(), update=update) telegram._balance(update=update, context=MagicMock())
result = msg_mock.call_args_list[0][0][0] result = msg_mock.call_args_list[0][0][0]
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert '*BTC:*' in result assert '*BTC:*' in result
@ -536,7 +544,7 @@ def test_balance_handle_empty_response(default_conf, update, mocker) -> None:
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
freqtradebot.config['dry_run'] = False freqtradebot.config['dry_run'] = False
telegram._balance(bot=MagicMock(), update=update) telegram._balance(update=update, context=MagicMock())
result = msg_mock.call_args_list[0][0][0] result = msg_mock.call_args_list[0][0][0]
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'All balances are zero.' in result assert 'All balances are zero.' in result
@ -557,7 +565,7 @@ def test_balance_handle_empty_response_dry(default_conf, update, mocker) -> None
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._balance(bot=MagicMock(), update=update) telegram._balance(update=update, context=MagicMock())
result = msg_mock.call_args_list[0][0][0] result = msg_mock.call_args_list[0][0][0]
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert "Running in Dry Run, balances are not available." in result assert "Running in Dry Run, balances are not available." in result
@ -593,7 +601,7 @@ def test_balance_handle_too_large_response(default_conf, update, mocker) -> None
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._balance(bot=MagicMock(), update=update) telegram._balance(update=update, context=MagicMock())
assert msg_mock.call_count > 1 assert msg_mock.call_count > 1
# Test if wrap happens around 4000 - # Test if wrap happens around 4000 -
# and each single currency-output is around 120 characters long so we need # and each single currency-output is around 120 characters long so we need
@ -615,7 +623,7 @@ def test_start_handle(default_conf, update, mocker) -> None:
freqtradebot.state = State.STOPPED freqtradebot.state = State.STOPPED
assert freqtradebot.state == State.STOPPED assert freqtradebot.state == State.STOPPED
telegram._start(bot=MagicMock(), update=update) telegram._start(update=update, context=MagicMock())
assert freqtradebot.state == State.RUNNING assert freqtradebot.state == State.RUNNING
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
@ -633,7 +641,7 @@ def test_start_handle_already_running(default_conf, update, mocker) -> None:
freqtradebot.state = State.RUNNING freqtradebot.state = State.RUNNING
assert freqtradebot.state == State.RUNNING assert freqtradebot.state == State.RUNNING
telegram._start(bot=MagicMock(), update=update) telegram._start(update=update, context=MagicMock())
assert freqtradebot.state == State.RUNNING assert freqtradebot.state == State.RUNNING
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'already running' in msg_mock.call_args_list[0][0][0] assert 'already running' in msg_mock.call_args_list[0][0][0]
@ -652,7 +660,7 @@ def test_stop_handle(default_conf, update, mocker) -> None:
freqtradebot.state = State.RUNNING freqtradebot.state = State.RUNNING
assert freqtradebot.state == State.RUNNING assert freqtradebot.state == State.RUNNING
telegram._stop(bot=MagicMock(), update=update) telegram._stop(update=update, context=MagicMock())
assert freqtradebot.state == State.STOPPED assert freqtradebot.state == State.STOPPED
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'stopping trader' in msg_mock.call_args_list[0][0][0] assert 'stopping trader' in msg_mock.call_args_list[0][0][0]
@ -671,7 +679,7 @@ def test_stop_handle_already_stopped(default_conf, update, mocker) -> None:
freqtradebot.state = State.STOPPED freqtradebot.state = State.STOPPED
assert freqtradebot.state == State.STOPPED assert freqtradebot.state == State.STOPPED
telegram._stop(bot=MagicMock(), update=update) telegram._stop(update=update, context=MagicMock())
assert freqtradebot.state == State.STOPPED assert freqtradebot.state == State.STOPPED
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'already stopped' in msg_mock.call_args_list[0][0][0] assert 'already stopped' in msg_mock.call_args_list[0][0][0]
@ -689,7 +697,7 @@ def test_stopbuy_handle(default_conf, update, mocker) -> None:
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
assert freqtradebot.config['max_open_trades'] != 0 assert freqtradebot.config['max_open_trades'] != 0
telegram._stopbuy(bot=MagicMock(), update=update) telegram._stopbuy(update=update, context=MagicMock())
assert freqtradebot.config['max_open_trades'] == 0 assert freqtradebot.config['max_open_trades'] == 0
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'No more buy will occur from now. Run /reload_conf to reset.' \ assert 'No more buy will occur from now. Run /reload_conf to reset.' \
@ -709,7 +717,7 @@ def test_reload_conf_handle(default_conf, update, mocker) -> None:
freqtradebot.state = State.RUNNING freqtradebot.state = State.RUNNING
assert freqtradebot.state == State.RUNNING assert freqtradebot.state == State.RUNNING
telegram._reload_conf(bot=MagicMock(), update=update) telegram._reload_conf(update=update, context=MagicMock())
assert freqtradebot.state == State.RELOAD_CONF assert freqtradebot.state == State.RELOAD_CONF
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'reloading config' in msg_mock.call_args_list[0][0][0] assert 'reloading config' in msg_mock.call_args_list[0][0][0]
@ -742,8 +750,10 @@ def test_forcesell_handle(default_conf, update, ticker, fee,
# Increase the price and sell it # Increase the price and sell it
mocker.patch('freqtrade.exchange.Exchange.get_ticker', ticker_sell_up) mocker.patch('freqtrade.exchange.Exchange.get_ticker', ticker_sell_up)
update.message.text = '/forcesell 1' # /forcesell 1
telegram._forcesell(bot=MagicMock(), update=update) context = MagicMock()
context.args = ["1"]
telegram._forcesell(update=update, context=context)
assert rpc_mock.call_count == 2 assert rpc_mock.call_count == 2
last_msg = rpc_mock.call_args_list[-1][0][0] last_msg = rpc_mock.call_args_list[-1][0][0]
@ -796,8 +806,10 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee,
trade = Trade.query.first() trade = Trade.query.first()
assert trade assert trade
update.message.text = '/forcesell 1' # /forcesell 1
telegram._forcesell(bot=MagicMock(), update=update) context = MagicMock()
context.args = ["1"]
telegram._forcesell(update=update, context=context)
assert rpc_mock.call_count == 2 assert rpc_mock.call_count == 2
@ -842,8 +854,10 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, markets, mocker
freqtradebot.create_trades() freqtradebot.create_trades()
rpc_mock.reset_mock() rpc_mock.reset_mock()
update.message.text = '/forcesell all' # /forcesell all
telegram._forcesell(bot=MagicMock(), update=update) context = MagicMock()
context.args = ["all"]
telegram._forcesell(update=update, context=context)
assert rpc_mock.call_count == 4 assert rpc_mock.call_count == 4
msg = rpc_mock.call_args_list[0][0][0] msg = rpc_mock.call_args_list[0][0][0]
@ -882,24 +896,29 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
# Trader is not running # Trader is not running
freqtradebot.state = State.STOPPED freqtradebot.state = State.STOPPED
update.message.text = '/forcesell 1' # /forcesell 1
telegram._forcesell(bot=MagicMock(), update=update) context = MagicMock()
context.args = ["1"]
telegram._forcesell(update=update, context=context)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'not running' in msg_mock.call_args_list[0][0][0] assert 'not running' in msg_mock.call_args_list[0][0][0]
# No argument # No argument
msg_mock.reset_mock() msg_mock.reset_mock()
freqtradebot.state = State.RUNNING freqtradebot.state = State.RUNNING
update.message.text = '/forcesell' context = MagicMock()
telegram._forcesell(bot=MagicMock(), update=update) context.args = []
telegram._forcesell(update=update, context=context)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'invalid argument' in msg_mock.call_args_list[0][0][0] assert 'invalid argument' in msg_mock.call_args_list[0][0][0]
# Invalid argument # Invalid argument
msg_mock.reset_mock() msg_mock.reset_mock()
freqtradebot.state = State.RUNNING freqtradebot.state = State.RUNNING
update.message.text = '/forcesell 123456' # /forcesell 123456
telegram._forcesell(bot=MagicMock(), update=update) context = MagicMock()
context.args = ["123456"]
telegram._forcesell(update=update, context=context)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'invalid argument' in msg_mock.call_args_list[0][0][0] assert 'invalid argument' in msg_mock.call_args_list[0][0][0]
@ -921,8 +940,10 @@ def test_forcebuy_handle(default_conf, update, markets, mocker) -> None:
patch_get_signal(freqtradebot, (True, False)) patch_get_signal(freqtradebot, (True, False))
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
update.message.text = '/forcebuy ETH/BTC' # /forcebuy ETH/BTC
telegram._forcebuy(bot=MagicMock(), update=update) context = MagicMock()
context.args = ["ETH/BTC"]
telegram._forcebuy(update=update, context=context)
assert fbuy_mock.call_count == 1 assert fbuy_mock.call_count == 1
assert fbuy_mock.call_args_list[0][0][0] == 'ETH/BTC' assert fbuy_mock.call_args_list[0][0][0] == 'ETH/BTC'
@ -931,8 +952,10 @@ def test_forcebuy_handle(default_conf, update, markets, mocker) -> None:
# Reset and retry with specified price # Reset and retry with specified price
fbuy_mock = MagicMock(return_value=None) fbuy_mock = MagicMock(return_value=None)
mocker.patch('freqtrade.rpc.RPC._rpc_forcebuy', fbuy_mock) mocker.patch('freqtrade.rpc.RPC._rpc_forcebuy', fbuy_mock)
update.message.text = '/forcebuy ETH/BTC 0.055' # /forcebuy ETH/BTC 0.055
telegram._forcebuy(bot=MagicMock(), update=update) context = MagicMock()
context.args = ["ETH/BTC", "0.055"]
telegram._forcebuy(update=update, context=context)
assert fbuy_mock.call_count == 1 assert fbuy_mock.call_count == 1
assert fbuy_mock.call_args_list[0][0][0] == 'ETH/BTC' assert fbuy_mock.call_args_list[0][0][0] == 'ETH/BTC'
@ -955,7 +978,7 @@ def test_forcebuy_handle_exception(default_conf, update, markets, mocker) -> Non
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
update.message.text = '/forcebuy ETH/Nonepair' update.message.text = '/forcebuy ETH/Nonepair'
telegram._forcebuy(bot=MagicMock(), update=update) telegram._forcebuy(update=update, context=MagicMock())
assert rpc_mock.call_count == 1 assert rpc_mock.call_count == 1
assert rpc_mock.call_args_list[0][0][0] == 'Forcebuy not enabled.' assert rpc_mock.call_args_list[0][0][0] == 'Forcebuy not enabled.'
@ -995,7 +1018,7 @@ def test_performance_handle(default_conf, update, ticker, fee,
trade.close_date = datetime.utcnow() trade.close_date = datetime.utcnow()
trade.is_open = False trade.is_open = False
telegram._performance(bot=MagicMock(), update=update) telegram._performance(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'Performance' in msg_mock.call_args_list[0][0][0] assert 'Performance' in msg_mock.call_args_list[0][0][0]
assert '<code>ETH/BTC\t6.20% (1)</code>' in msg_mock.call_args_list[0][0][0] assert '<code>ETH/BTC\t6.20% (1)</code>' in msg_mock.call_args_list[0][0][0]
@ -1021,7 +1044,7 @@ def test_count_handle(default_conf, update, ticker, fee, markets, mocker) -> Non
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
freqtradebot.state = State.STOPPED freqtradebot.state = State.STOPPED
telegram._count(bot=MagicMock(), update=update) telegram._count(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'not running' in msg_mock.call_args_list[0][0][0] assert 'not running' in msg_mock.call_args_list[0][0][0]
msg_mock.reset_mock() msg_mock.reset_mock()
@ -1030,7 +1053,7 @@ def test_count_handle(default_conf, update, ticker, fee, markets, mocker) -> Non
# Create some test data # Create some test data
freqtradebot.create_trades() freqtradebot.create_trades()
msg_mock.reset_mock() msg_mock.reset_mock()
telegram._count(bot=MagicMock(), update=update) telegram._count(update=update, context=MagicMock())
msg = '<pre> current max total stake\n--------- ----- -------------\n' \ msg = '<pre> current max total stake\n--------- ----- -------------\n' \
' 1 {} {}</pre>'\ ' 1 {} {}</pre>'\
@ -1052,7 +1075,7 @@ def test_whitelist_static(default_conf, update, mocker) -> None:
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._whitelist(bot=MagicMock(), update=update) telegram._whitelist(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert ('Using whitelist `StaticPairList` with 4 pairs\n`ETH/BTC, LTC/BTC, XRP/BTC, NEO/BTC`' assert ('Using whitelist `StaticPairList` with 4 pairs\n`ETH/BTC, LTC/BTC, XRP/BTC, NEO/BTC`'
in msg_mock.call_args_list[0][0][0]) in msg_mock.call_args_list[0][0][0])
@ -1073,7 +1096,7 @@ def test_whitelist_dynamic(default_conf, update, mocker) -> None:
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._whitelist(bot=MagicMock(), update=update) telegram._whitelist(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert ('Using whitelist `VolumePairList` with 4 pairs\n`ETH/BTC, LTC/BTC, XRP/BTC, NEO/BTC`' assert ('Using whitelist `VolumePairList` with 4 pairs\n`ETH/BTC, LTC/BTC, XRP/BTC, NEO/BTC`'
in msg_mock.call_args_list[0][0][0]) in msg_mock.call_args_list[0][0][0])
@ -1090,13 +1113,17 @@ def test_blacklist_static(default_conf, update, mocker) -> None:
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._blacklist(bot=MagicMock(), update=update, args=[]) telegram._blacklist(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert ("Blacklist contains 2 pairs\n`DOGE/BTC, HOT/BTC`" assert ("Blacklist contains 2 pairs\n`DOGE/BTC, HOT/BTC`"
in msg_mock.call_args_list[0][0][0]) in msg_mock.call_args_list[0][0][0])
msg_mock.reset_mock() msg_mock.reset_mock()
telegram._blacklist(bot=MagicMock(), update=update, args=["ETH/BTC"])
# /blacklist ETH/BTC
context = MagicMock()
context.args = ["ETH/BTC"]
telegram._blacklist(update=update, context=context)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert ("Blacklist contains 3 pairs\n`DOGE/BTC, HOT/BTC, ETH/BTC`" assert ("Blacklist contains 3 pairs\n`DOGE/BTC, HOT/BTC, ETH/BTC`"
in msg_mock.call_args_list[0][0][0]) in msg_mock.call_args_list[0][0][0])
@ -1115,7 +1142,7 @@ def test_edge_disabled(default_conf, update, mocker) -> None:
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._edge(bot=MagicMock(), update=update) telegram._edge(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert "Edge is not enabled." in msg_mock.call_args_list[0][0][0] assert "Edge is not enabled." in msg_mock.call_args_list[0][0][0]
@ -1137,7 +1164,7 @@ def test_edge_enabled(edge_conf, update, mocker) -> None:
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._edge(bot=MagicMock(), update=update) telegram._edge(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert '<b>Edge only validated following pairs:</b>\n<pre>' in msg_mock.call_args_list[0][0][0] assert '<b>Edge only validated following pairs:</b>\n<pre>' in msg_mock.call_args_list[0][0][0]
assert 'Pair Winrate Expectancy Stoploss' in msg_mock.call_args_list[0][0][0] assert 'Pair Winrate Expectancy Stoploss' in msg_mock.call_args_list[0][0][0]
@ -1154,7 +1181,7 @@ def test_help_handle(default_conf, update, mocker) -> None:
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._help(bot=MagicMock(), update=update) telegram._help(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert '*/help:* `This help message`' in msg_mock.call_args_list[0][0][0] assert '*/help:* `This help message`' in msg_mock.call_args_list[0][0][0]
@ -1169,7 +1196,7 @@ def test_version_handle(default_conf, update, mocker) -> None:
freqtradebot = get_patched_freqtradebot(mocker, default_conf) freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._version(bot=MagicMock(), update=update) telegram._version(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert '*Version:* `{}`'.format(__version__) in msg_mock.call_args_list[0][0][0] assert '*Version:* `{}`'.format(__version__) in msg_mock.call_args_list[0][0][0]
@ -1395,9 +1422,11 @@ def test__send_msg(default_conf, mocker) -> None:
bot = MagicMock() bot = MagicMock()
freqtradebot = get_patched_freqtradebot(mocker, default_conf) freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._updater = MagicMock()
telegram._updater.bot = bot
telegram._config['telegram']['enabled'] = True telegram._config['telegram']['enabled'] = True
telegram._send_msg('test', bot) telegram._send_msg('test')
assert len(bot.method_calls) == 1 assert len(bot.method_calls) == 1
@ -1407,9 +1436,11 @@ def test__send_msg_network_error(default_conf, mocker, caplog) -> None:
bot.send_message = MagicMock(side_effect=NetworkError('Oh snap')) bot.send_message = MagicMock(side_effect=NetworkError('Oh snap'))
freqtradebot = get_patched_freqtradebot(mocker, default_conf) freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot) telegram = Telegram(freqtradebot)
telegram._updater = MagicMock()
telegram._updater.bot = bot
telegram._config['telegram']['enabled'] = True telegram._config['telegram']['enabled'] = True
telegram._send_msg('test', bot) telegram._send_msg('test')
# Bot should've tried to send it twice # Bot should've tried to send it twice
assert len(bot.method_calls) == 2 assert len(bot.method_calls) == 2

View File

@ -2,7 +2,7 @@
# mainly used for Raspberry pi installs # mainly used for Raspberry pi installs
ccxt==1.18.1115 ccxt==1.18.1115
SQLAlchemy==1.3.8 SQLAlchemy==1.3.8
python-telegram-bot==11.1.0 python-telegram-bot==12.0.0
arrow==0.14.6 arrow==0.14.6
cachetools==3.1.1 cachetools==3.1.1
requests==2.22.0 requests==2.22.0