def test__send_msg_with_json_format(default_conf, mocker, caplog): default_conf["webhook"] = get_webhook_dict() default_conf["webhook"]["format"] = "json" webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf) msg = {'text': 'Hello'} post = MagicMock() mocker.patch("freqtrade.rpc.webhook.post", post) webhook._send_msg(msg) assert post.call_args[1] == {'json': msg}
def test__send_msg_with_raw_format(default_conf, mocker, caplog): default_conf["webhook"] = get_webhook_dict() default_conf["webhook"]["format"] = "raw" webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf) msg = {'data': 'Hello'} post = MagicMock() mocker.patch("freqtrade.rpc.webhook.post", post) webhook._send_msg(msg) assert post.call_args[1] == {'data': msg['data'], 'headers': {'Content-Type': 'text/plain'}}
def test_exception_send_msg(default_conf, mocker, caplog): default_conf["webhook"] = get_webhook_dict() del default_conf["webhook"]["webhookentry"] webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf) webhook.send_msg({'type': RPCMessageType.ENTRY}) assert log_has( f"Message type '{RPCMessageType.ENTRY}' not configured for webhooks", caplog) default_conf["webhook"] = get_webhook_dict() default_conf["webhook"]["webhookentry"]["value1"] = "{DEADBEEF:8f}" msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf) msg = { 'type': RPCMessageType.ENTRY, 'exchange': 'Binance', 'pair': 'ETH/BTC', 'limit': 0.005, 'order_type': 'limit', 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } webhook.send_msg(msg) assert log_has( "Problem calling Webhook. Please check your webhook configuration. " "Exception: 'DEADBEEF'", caplog) msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) msg = {'type': 'DEADBEEF', 'status': 'whatever'} with pytest.raises(NotImplementedError): webhook.send_msg(msg)
def test_exception_send_msg(default_conf, mocker, caplog): default_conf["webhook"] = get_webhook_dict() default_conf["webhook"]["webhookbuy"] = None webhook = Webhook(get_patched_freqtradebot(mocker, default_conf)) webhook.send_msg({'type': RPCMessageType.BUY_NOTIFICATION}) assert log_has( f"Message type {RPCMessageType.BUY_NOTIFICATION} not configured for webhooks", caplog.record_tuples) default_conf["webhook"] = get_webhook_dict() default_conf["webhook"]["webhookbuy"]["value1"] = "{DEADBEEF:8f}" msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook = Webhook(get_patched_freqtradebot(mocker, default_conf)) msg = { 'type': RPCMessageType.BUY_NOTIFICATION, 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'market_url': "http://mockedurl/ETH_BTC", 'limit': 0.005, 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } webhook.send_msg(msg) assert log_has( "Problem calling Webhook. Please check your webhook configuration. " "Exception: 'DEADBEEF'", caplog.record_tuples) msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) msg = {'type': 'DEADBEEF', 'status': 'whatever'} with pytest.raises(NotImplementedError): webhook.send_msg(msg)
def __init__(self, freqtrade) -> None: """ Initializes all enabled rpc modules """ self.registered_modules: List[RPC] = [] # Enable telegram if freqtrade.config['telegram'].get('enabled', False): logger.info('Enabling rpc.telegram ...') from freqtrade.rpc.telegram import Telegram self.registered_modules.append(Telegram(freqtrade)) # Enable Webhook if freqtrade.config.get('webhook', {}).get('enabled', False): logger.info('Enabling rpc.webhook ...') from freqtrade.rpc.webhook import Webhook self.registered_modules.append(Webhook(freqtrade))
def __init__(self, freqtrade) -> None: """ Initializes all enabled rpc modules """ self.registered_modules: List[RPC] = [] # Enable telegram if freqtrade.config.get('telegram', {}).get('enabled', False): logger.info('Enabling rpc.telegram ...') from freqtrade.rpc.telegram import Telegram self.registered_modules.append(Telegram(freqtrade)) # Enable Webhook if freqtrade.config.get('webhook', {}).get('enabled', False): logger.info('Enabling rpc.webhook ...') from freqtrade.rpc.webhook import Webhook self.registered_modules.append(Webhook(freqtrade)) # Enable local rest api server for cmd line control if freqtrade.config.get('api_server', {}).get('enabled', False): logger.info('Enabling rpc.api_server') from freqtrade.rpc.api_server import ApiServer self.registered_modules.append(ApiServer(freqtrade))
def test__send_msg(default_conf, mocker, caplog): default_conf["webhook"] = get_webhook_dict() webhook = Webhook(get_patched_freqtradebot(mocker, default_conf)) msg = {'value1': 'DEADBEEF', 'value2': 'ALIVEBEEF', 'value3': 'FREQTRADE'} post = MagicMock() mocker.patch("freqtrade.rpc.webhook.post", post) webhook._send_msg(msg) assert post.call_count == 1 assert post.call_args[1] == {'data': msg} assert post.call_args[0] == (default_conf['webhook']['url'], ) post = MagicMock(side_effect=RequestException) mocker.patch("freqtrade.rpc.webhook.post", post) webhook._send_msg(msg) assert log_has('Could not call webhook url. Exception: ', caplog)
def __init__(self, freqtrade) -> None: """ Initializes all enabled rpc modules """ self.registered_modules: List[RPCHandler] = [] self._rpc = RPC(freqtrade) config = freqtrade.config # Enable telegram if config.get('telegram', {}).get('enabled', False): logger.info('Enabling rpc.telegram ...') from freqtrade.rpc.telegram import Telegram self.registered_modules.append(Telegram(self._rpc, config)) # Enable Webhook if config.get('webhook', {}).get('enabled', False): logger.info('Enabling rpc.webhook ...') from freqtrade.rpc.webhook import Webhook self.registered_modules.append(Webhook(self._rpc, config)) # Enable local rest api server for cmd line control if config.get('api_server', {}).get('enabled', False): logger.info('Enabling rpc.api_server') from freqtrade.rpc.api_server import ApiServer apiserver = ApiServer(config) apiserver.add_rpc_handler(self._rpc) self.registered_modules.append(apiserver)
def test_send_msg(default_conf, mocker): default_conf["webhook"] = get_webhook_dict() msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook = Webhook(get_patched_freqtradebot(mocker, default_conf)) # Test buy msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) msg = { 'type': RPCMessageType.BUY_NOTIFICATION, 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'limit': 0.005, 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookbuy"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookbuy"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookbuy"]["value3"].format(**msg)) # Test buy cancel msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) msg = { 'type': RPCMessageType.BUY_CANCEL_NOTIFICATION, 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'limit': 0.005, 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookbuycancel"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookbuycancel"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookbuycancel"]["value3"].format(**msg)) # Test sell msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) msg = { 'type': RPCMessageType.SELL_NOTIFICATION, 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'gain': "profit", 'limit': 0.005, 'amount': 0.8, 'order_type': 'limit', 'open_rate': 0.004, 'current_rate': 0.005, 'profit_amount': 0.001, 'profit_ratio': 0.20, 'stake_currency': 'BTC', 'sell_reason': SellType.STOP_LOSS.value } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhooksell"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhooksell"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhooksell"]["value3"].format(**msg)) # Test sell cancel msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) msg = { 'type': RPCMessageType.SELL_CANCEL_NOTIFICATION, 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'gain': "profit", 'limit': 0.005, 'amount': 0.8, 'order_type': 'limit', 'open_rate': 0.004, 'current_rate': 0.005, 'profit_amount': 0.001, 'profit_ratio': 0.20, 'stake_currency': 'BTC', 'sell_reason': SellType.STOP_LOSS.value } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhooksellcancel"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhooksellcancel"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhooksellcancel"]["value3"].format(**msg)) for msgtype in [ RPCMessageType.STATUS_NOTIFICATION, RPCMessageType.WARNING_NOTIFICATION, RPCMessageType.STARTUP_NOTIFICATION ]: # Test notification msg = { 'type': msgtype, 'status': 'Unfilled sell order for BTC cancelled due to timeout' } msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook.send_msg(msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookstatus"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookstatus"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookstatus"]["value3"].format(**msg))
def test__init__(mocker, default_conf): default_conf['webhook'] = {'enabled': True, 'url': "https://DEADBEEF.com"} webhook = Webhook(get_patched_freqtradebot(mocker, default_conf)) assert webhook._config == default_conf
def test_send_msg(default_conf, mocker): default_conf["webhook"] = get_webhook_dict() msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook = Webhook(get_patched_freqtradebot(mocker, default_conf)) msg = { 'type': RPCMessageType.BUY_NOTIFICATION, 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'market_url': "http://mockedurl/ETH_BTC", 'limit': 0.005, 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookbuy"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookbuy"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookbuy"]["value3"].format(**msg)) # Test sell msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) msg = { 'type': RPCMessageType.SELL_NOTIFICATION, 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'gain': "profit", 'market_url': "http://mockedurl/ETH_BTC", 'limit': 0.005, 'amount': 0.8, 'open_rate': 0.004, 'current_rate': 0.005, 'profit_amount': 0.001, 'profit_percent': 0.20, 'stake_currency': 'BTC', } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhooksell"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhooksell"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhooksell"]["value3"].format(**msg)) # Test notification msg = { 'type': RPCMessageType.STATUS_NOTIFICATION, 'status': 'Unfilled sell order for BTC cancelled due to timeout' } msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook.send_msg(msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookstatus"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookstatus"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookstatus"]["value3"].format(**msg))
def test_send_msg_webhook(default_conf, mocker): default_conf["webhook"] = get_webhook_dict() msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf) # Test buy msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) msg = { 'type': RPCMessageType.ENTRY, 'exchange': 'Binance', 'pair': 'ETH/BTC', 'leverage': 1.0, 'direction': 'Long', 'limit': 0.005, 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookentry"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookentry"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookentry"]["value3"].format(**msg)) assert (msg_mock.call_args[0][0]["value4"] == default_conf["webhook"] ["webhookentry"]["value4"].format(**msg)) assert (msg_mock.call_args[0][0]["value5"] == default_conf["webhook"] ["webhookentry"]["value5"].format(**msg)) # Test short msg_mock.reset_mock() msg = { 'type': RPCMessageType.ENTRY, 'exchange': 'Binance', 'pair': 'ETH/BTC', 'leverage': 2.0, 'direction': 'Short', 'limit': 0.005, 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookentry"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookentry"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookentry"]["value3"].format(**msg)) assert (msg_mock.call_args[0][0]["value4"] == default_conf["webhook"] ["webhookentry"]["value4"].format(**msg)) assert (msg_mock.call_args[0][0]["value5"] == default_conf["webhook"] ["webhookentry"]["value5"].format(**msg)) # Test buy cancel msg_mock.reset_mock() msg = { 'type': RPCMessageType.ENTRY_CANCEL, 'exchange': 'Binance', 'pair': 'ETH/BTC', 'leverage': 1.0, 'direction': 'Long', 'limit': 0.005, 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookentrycancel"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookentrycancel"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookentrycancel"]["value3"].format(**msg)) # Test short cancel msg_mock.reset_mock() msg = { 'type': RPCMessageType.ENTRY_CANCEL, 'exchange': 'Binance', 'pair': 'ETH/BTC', 'leverage': 2.0, 'direction': 'Short', 'limit': 0.005, 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookentrycancel"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookentrycancel"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookentrycancel"]["value3"].format(**msg)) assert (msg_mock.call_args[0][0]["value4"] == default_conf["webhook"] ["webhookentrycancel"]["value4"].format(**msg)) assert (msg_mock.call_args[0][0]["value5"] == default_conf["webhook"] ["webhookentrycancel"]["value5"].format(**msg)) # Test buy fill msg_mock.reset_mock() msg = { 'type': RPCMessageType.ENTRY_FILL, 'exchange': 'Binance', 'pair': 'ETH/BTC', 'leverage': 1.0, 'direction': 'Long', 'open_rate': 0.005, 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookentryfill"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookentryfill"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookentryfill"]["value3"].format(**msg)) assert (msg_mock.call_args[0][0]["value4"] == default_conf["webhook"] ["webhookentrycancel"]["value4"].format(**msg)) assert (msg_mock.call_args[0][0]["value5"] == default_conf["webhook"] ["webhookentrycancel"]["value5"].format(**msg)) # Test short fill msg_mock.reset_mock() msg = { 'type': RPCMessageType.ENTRY_FILL, 'exchange': 'Binance', 'pair': 'ETH/BTC', 'leverage': 2.0, 'direction': 'Short', 'open_rate': 0.005, 'stake_amount': 0.8, 'stake_amount_fiat': 500, 'stake_currency': 'BTC', 'fiat_currency': 'EUR' } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookentryfill"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookentryfill"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookentryfill"]["value3"].format(**msg)) assert (msg_mock.call_args[0][0]["value4"] == default_conf["webhook"] ["webhookentrycancel"]["value4"].format(**msg)) assert (msg_mock.call_args[0][0]["value5"] == default_conf["webhook"] ["webhookentrycancel"]["value5"].format(**msg)) # Test sell msg_mock.reset_mock() msg = { 'type': RPCMessageType.EXIT, 'exchange': 'Binance', 'pair': 'ETH/BTC', 'gain': "profit", 'limit': 0.005, 'amount': 0.8, 'order_type': 'limit', 'open_rate': 0.004, 'current_rate': 0.005, 'profit_amount': 0.001, 'profit_ratio': 0.20, 'stake_currency': 'BTC', 'sell_reason': ExitType.STOP_LOSS.value } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookexit"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookexit"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookexit"]["value3"].format(**msg)) # Test sell cancel msg_mock.reset_mock() msg = { 'type': RPCMessageType.EXIT_CANCEL, 'exchange': 'Binance', 'pair': 'ETH/BTC', 'gain': "profit", 'limit': 0.005, 'amount': 0.8, 'order_type': 'limit', 'open_rate': 0.004, 'current_rate': 0.005, 'profit_amount': 0.001, 'profit_ratio': 0.20, 'stake_currency': 'BTC', 'sell_reason': ExitType.STOP_LOSS.value } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookexitcancel"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookexitcancel"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookexitcancel"]["value3"].format(**msg)) # Test Sell fill msg_mock.reset_mock() msg = { 'type': RPCMessageType.EXIT_FILL, 'exchange': 'Binance', 'pair': 'ETH/BTC', 'gain': "profit", 'close_rate': 0.005, 'amount': 0.8, 'order_type': 'limit', 'open_rate': 0.004, 'current_rate': 0.005, 'profit_amount': 0.001, 'profit_ratio': 0.20, 'stake_currency': 'BTC', 'sell_reason': ExitType.STOP_LOSS.value } webhook.send_msg(msg=msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookexitfill"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookexitfill"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookexitfill"]["value3"].format(**msg)) for msgtype in [ RPCMessageType.STATUS, RPCMessageType.WARNING, RPCMessageType.STARTUP ]: # Test notification msg = { 'type': msgtype, 'status': 'Unfilled sell order for BTC cancelled due to timeout' } msg_mock = MagicMock() mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock) webhook.send_msg(msg) assert msg_mock.call_count == 1 assert (msg_mock.call_args[0][0]["value1"] == default_conf["webhook"] ["webhookstatus"]["value1"].format(**msg)) assert (msg_mock.call_args[0][0]["value2"] == default_conf["webhook"] ["webhookstatus"]["value2"].format(**msg)) assert (msg_mock.call_args[0][0]["value3"] == default_conf["webhook"] ["webhookstatus"]["value3"].format(**msg))