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 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_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))