ruff format: rpc tests
This commit is contained in:
@@ -13,10 +13,10 @@ from tests.conftest import log_has, log_has_re
|
|||||||
|
|
||||||
def test_fiat_convert_is_supported(mocker):
|
def test_fiat_convert_is_supported(mocker):
|
||||||
fiat_convert = CryptoToFiatConverter()
|
fiat_convert = CryptoToFiatConverter()
|
||||||
assert fiat_convert._is_supported_fiat(fiat='USD') is True
|
assert fiat_convert._is_supported_fiat(fiat="USD") is True
|
||||||
assert fiat_convert._is_supported_fiat(fiat='usd') is True
|
assert fiat_convert._is_supported_fiat(fiat="usd") is True
|
||||||
assert fiat_convert._is_supported_fiat(fiat='abc') is False
|
assert fiat_convert._is_supported_fiat(fiat="abc") is False
|
||||||
assert fiat_convert._is_supported_fiat(fiat='ABC') is False
|
assert fiat_convert._is_supported_fiat(fiat="ABC") is False
|
||||||
|
|
||||||
|
|
||||||
def test_fiat_convert_find_price(mocker):
|
def test_fiat_convert_find_price(mocker):
|
||||||
@@ -24,69 +24,72 @@ def test_fiat_convert_find_price(mocker):
|
|||||||
|
|
||||||
fiat_convert._coinlistings = {}
|
fiat_convert._coinlistings = {}
|
||||||
fiat_convert._backoff = 0
|
fiat_convert._backoff = 0
|
||||||
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._load_cryptomap',
|
mocker.patch(
|
||||||
return_value=None)
|
"freqtrade.rpc.fiat_convert.CryptoToFiatConverter._load_cryptomap", return_value=None
|
||||||
assert fiat_convert.get_price(crypto_symbol='BTC', fiat_symbol='EUR') == 0.0
|
)
|
||||||
|
assert fiat_convert.get_price(crypto_symbol="BTC", fiat_symbol="EUR") == 0.0
|
||||||
|
|
||||||
with pytest.raises(ValueError, match=r'The fiat ABC is not supported.'):
|
with pytest.raises(ValueError, match=r"The fiat ABC is not supported."):
|
||||||
fiat_convert._find_price(crypto_symbol='BTC', fiat_symbol='ABC')
|
fiat_convert._find_price(crypto_symbol="BTC", fiat_symbol="ABC")
|
||||||
|
|
||||||
assert fiat_convert.get_price(crypto_symbol='XRP', fiat_symbol='USD') == 0.0
|
assert fiat_convert.get_price(crypto_symbol="XRP", fiat_symbol="USD") == 0.0
|
||||||
|
|
||||||
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price',
|
mocker.patch(
|
||||||
return_value=12345.0)
|
"freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price", return_value=12345.0
|
||||||
assert fiat_convert.get_price(crypto_symbol='BTC', fiat_symbol='USD') == 12345.0
|
)
|
||||||
assert fiat_convert.get_price(crypto_symbol='btc', fiat_symbol='usd') == 12345.0
|
assert fiat_convert.get_price(crypto_symbol="BTC", fiat_symbol="USD") == 12345.0
|
||||||
|
assert fiat_convert.get_price(crypto_symbol="btc", fiat_symbol="usd") == 12345.0
|
||||||
|
|
||||||
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price',
|
mocker.patch(
|
||||||
return_value=13000.2)
|
"freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price", return_value=13000.2
|
||||||
assert fiat_convert.get_price(crypto_symbol='BTC', fiat_symbol='EUR') == 13000.2
|
)
|
||||||
|
assert fiat_convert.get_price(crypto_symbol="BTC", fiat_symbol="EUR") == 13000.2
|
||||||
|
|
||||||
|
|
||||||
def test_fiat_convert_unsupported_crypto(mocker, caplog):
|
def test_fiat_convert_unsupported_crypto(mocker, caplog):
|
||||||
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._coinlistings', return_value=[])
|
mocker.patch("freqtrade.rpc.fiat_convert.CryptoToFiatConverter._coinlistings", return_value=[])
|
||||||
fiat_convert = CryptoToFiatConverter()
|
fiat_convert = CryptoToFiatConverter()
|
||||||
assert fiat_convert._find_price(crypto_symbol='CRYPTO_123', fiat_symbol='EUR') == 0.0
|
assert fiat_convert._find_price(crypto_symbol="CRYPTO_123", fiat_symbol="EUR") == 0.0
|
||||||
assert log_has('unsupported crypto-symbol CRYPTO_123 - returning 0.0', caplog)
|
assert log_has("unsupported crypto-symbol CRYPTO_123 - returning 0.0", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_fiat_convert_get_price(mocker):
|
def test_fiat_convert_get_price(mocker):
|
||||||
find_price = mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price',
|
find_price = mocker.patch(
|
||||||
return_value=28000.0)
|
"freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price", return_value=28000.0
|
||||||
|
)
|
||||||
|
|
||||||
fiat_convert = CryptoToFiatConverter()
|
fiat_convert = CryptoToFiatConverter()
|
||||||
|
|
||||||
with pytest.raises(ValueError, match=r'The fiat us dollar is not supported.'):
|
with pytest.raises(ValueError, match=r"The fiat us dollar is not supported."):
|
||||||
fiat_convert.get_price(crypto_symbol='btc', fiat_symbol='US Dollar')
|
fiat_convert.get_price(crypto_symbol="btc", fiat_symbol="US Dollar")
|
||||||
|
|
||||||
# Check the value return by the method
|
# Check the value return by the method
|
||||||
pair_len = len(fiat_convert._pair_price)
|
pair_len = len(fiat_convert._pair_price)
|
||||||
assert pair_len == 0
|
assert pair_len == 0
|
||||||
assert fiat_convert.get_price(crypto_symbol='btc', fiat_symbol='usd') == 28000.0
|
assert fiat_convert.get_price(crypto_symbol="btc", fiat_symbol="usd") == 28000.0
|
||||||
assert fiat_convert._pair_price['btc/usd'] == 28000.0
|
assert fiat_convert._pair_price["btc/usd"] == 28000.0
|
||||||
assert len(fiat_convert._pair_price) == 1
|
assert len(fiat_convert._pair_price) == 1
|
||||||
assert find_price.call_count == 1
|
assert find_price.call_count == 1
|
||||||
|
|
||||||
# Verify the cached is used
|
# Verify the cached is used
|
||||||
fiat_convert._pair_price['btc/usd'] = 9867.543
|
fiat_convert._pair_price["btc/usd"] = 9867.543
|
||||||
assert fiat_convert.get_price(crypto_symbol='btc', fiat_symbol='usd') == 9867.543
|
assert fiat_convert.get_price(crypto_symbol="btc", fiat_symbol="usd") == 9867.543
|
||||||
assert find_price.call_count == 1
|
assert find_price.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
def test_fiat_convert_same_currencies(mocker):
|
def test_fiat_convert_same_currencies(mocker):
|
||||||
fiat_convert = CryptoToFiatConverter()
|
fiat_convert = CryptoToFiatConverter()
|
||||||
|
|
||||||
assert fiat_convert.get_price(crypto_symbol='USD', fiat_symbol='USD') == 1.0
|
assert fiat_convert.get_price(crypto_symbol="USD", fiat_symbol="USD") == 1.0
|
||||||
|
|
||||||
|
|
||||||
def test_fiat_convert_two_FIAT(mocker):
|
def test_fiat_convert_two_FIAT(mocker):
|
||||||
fiat_convert = CryptoToFiatConverter()
|
fiat_convert = CryptoToFiatConverter()
|
||||||
|
|
||||||
assert fiat_convert.get_price(crypto_symbol='USD', fiat_symbol='EUR') == 0.0
|
assert fiat_convert.get_price(crypto_symbol="USD", fiat_symbol="EUR") == 0.0
|
||||||
|
|
||||||
|
|
||||||
def test_loadcryptomap(mocker):
|
def test_loadcryptomap(mocker):
|
||||||
|
|
||||||
fiat_convert = CryptoToFiatConverter()
|
fiat_convert = CryptoToFiatConverter()
|
||||||
assert len(fiat_convert._coinlistings) == 2
|
assert len(fiat_convert._coinlistings) == 2
|
||||||
|
|
||||||
@@ -97,7 +100,7 @@ def test_fiat_init_network_exception(mocker):
|
|||||||
# Because CryptoToFiatConverter is a Singleton we reset the listings
|
# Because CryptoToFiatConverter is a Singleton we reset the listings
|
||||||
listmock = MagicMock(side_effect=RequestException)
|
listmock = MagicMock(side_effect=RequestException)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.rpc.fiat_convert.CoinGeckoAPI',
|
"freqtrade.rpc.fiat_convert.CoinGeckoAPI",
|
||||||
get_coins_list=listmock,
|
get_coins_list=listmock,
|
||||||
)
|
)
|
||||||
# with pytest.raises(RequestEsxception):
|
# with pytest.raises(RequestEsxception):
|
||||||
@@ -117,7 +120,7 @@ def test_fiat_convert_without_network(mocker):
|
|||||||
CryptoToFiatConverter._coingecko = None
|
CryptoToFiatConverter._coingecko = None
|
||||||
|
|
||||||
assert fiat_convert._coingecko is None
|
assert fiat_convert._coingecko is None
|
||||||
assert fiat_convert._find_price(crypto_symbol='btc', fiat_symbol='usd') == 0.0
|
assert fiat_convert._find_price(crypto_symbol="btc", fiat_symbol="usd") == 0.0
|
||||||
CryptoToFiatConverter._coingecko = cmc_temp
|
CryptoToFiatConverter._coingecko = cmc_temp
|
||||||
|
|
||||||
|
|
||||||
@@ -126,7 +129,7 @@ def test_fiat_too_many_requests_response(mocker, caplog):
|
|||||||
req_exception = "429 Too Many Requests"
|
req_exception = "429 Too Many Requests"
|
||||||
listmock = MagicMock(return_value="{}", side_effect=RequestException(req_exception))
|
listmock = MagicMock(return_value="{}", side_effect=RequestException(req_exception))
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.rpc.fiat_convert.CoinGeckoAPI',
|
"freqtrade.rpc.fiat_convert.CoinGeckoAPI",
|
||||||
get_coins_list=listmock,
|
get_coins_list=listmock,
|
||||||
)
|
)
|
||||||
# with pytest.raises(RequestEsxception):
|
# with pytest.raises(RequestEsxception):
|
||||||
@@ -137,33 +140,32 @@ def test_fiat_too_many_requests_response(mocker, caplog):
|
|||||||
assert len(fiat_convert._coinlistings) == 0
|
assert len(fiat_convert._coinlistings) == 0
|
||||||
assert fiat_convert._backoff > datetime.datetime.now().timestamp()
|
assert fiat_convert._backoff > datetime.datetime.now().timestamp()
|
||||||
assert log_has(
|
assert log_has(
|
||||||
'Too many requests for CoinGecko API, backing off and trying again later.',
|
"Too many requests for CoinGecko API, backing off and trying again later.", caplog
|
||||||
caplog
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_fiat_multiple_coins(mocker, caplog):
|
def test_fiat_multiple_coins(mocker, caplog):
|
||||||
fiat_convert = CryptoToFiatConverter()
|
fiat_convert = CryptoToFiatConverter()
|
||||||
fiat_convert._coinlistings = [
|
fiat_convert._coinlistings = [
|
||||||
{'id': 'helium', 'symbol': 'hnt', 'name': 'Helium'},
|
{"id": "helium", "symbol": "hnt", "name": "Helium"},
|
||||||
{'id': 'hymnode', 'symbol': 'hnt', 'name': 'Hymnode'},
|
{"id": "hymnode", "symbol": "hnt", "name": "Hymnode"},
|
||||||
{'id': 'bitcoin', 'symbol': 'btc', 'name': 'Bitcoin'},
|
{"id": "bitcoin", "symbol": "btc", "name": "Bitcoin"},
|
||||||
{'id': 'ethereum', 'symbol': 'eth', 'name': 'Ethereum'},
|
{"id": "ethereum", "symbol": "eth", "name": "Ethereum"},
|
||||||
{'id': 'ethereum-wormhole', 'symbol': 'eth', 'name': 'Ethereum Wormhole'},
|
{"id": "ethereum-wormhole", "symbol": "eth", "name": "Ethereum Wormhole"},
|
||||||
]
|
]
|
||||||
|
|
||||||
assert fiat_convert._get_gecko_id('btc') == 'bitcoin'
|
assert fiat_convert._get_gecko_id("btc") == "bitcoin"
|
||||||
assert fiat_convert._get_gecko_id('hnt') is None
|
assert fiat_convert._get_gecko_id("hnt") is None
|
||||||
assert fiat_convert._get_gecko_id('eth') == 'ethereum'
|
assert fiat_convert._get_gecko_id("eth") == "ethereum"
|
||||||
|
|
||||||
assert log_has('Found multiple mappings in CoinGecko for hnt.', caplog)
|
assert log_has("Found multiple mappings in CoinGecko for hnt.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_fiat_invalid_response(mocker, caplog):
|
def test_fiat_invalid_response(mocker, caplog):
|
||||||
# Because CryptoToFiatConverter is a Singleton we reset the listings
|
# Because CryptoToFiatConverter is a Singleton we reset the listings
|
||||||
listmock = MagicMock(return_value=None)
|
listmock = MagicMock(return_value=None)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.rpc.fiat_convert.CoinGeckoAPI',
|
"freqtrade.rpc.fiat_convert.CoinGeckoAPI",
|
||||||
get_coins_list=listmock,
|
get_coins_list=listmock,
|
||||||
)
|
)
|
||||||
# with pytest.raises(RequestEsxception):
|
# with pytest.raises(RequestEsxception):
|
||||||
@@ -172,31 +174,22 @@ def test_fiat_invalid_response(mocker, caplog):
|
|||||||
fiat_convert._load_cryptomap()
|
fiat_convert._load_cryptomap()
|
||||||
|
|
||||||
assert len(fiat_convert._coinlistings) == 0
|
assert len(fiat_convert._coinlistings) == 0
|
||||||
assert log_has_re('Could not load FIAT Cryptocurrency map for the following problem: .*',
|
assert log_has_re(
|
||||||
caplog)
|
"Could not load FIAT Cryptocurrency map for the following problem: .*", caplog
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_convert_amount(mocker):
|
def test_convert_amount(mocker):
|
||||||
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter.get_price', return_value=12345.0)
|
mocker.patch("freqtrade.rpc.fiat_convert.CryptoToFiatConverter.get_price", return_value=12345.0)
|
||||||
|
|
||||||
fiat_convert = CryptoToFiatConverter()
|
fiat_convert = CryptoToFiatConverter()
|
||||||
result = fiat_convert.convert_amount(
|
result = fiat_convert.convert_amount(crypto_amount=1.23, crypto_symbol="BTC", fiat_symbol="USD")
|
||||||
crypto_amount=1.23,
|
|
||||||
crypto_symbol="BTC",
|
|
||||||
fiat_symbol="USD"
|
|
||||||
)
|
|
||||||
assert result == 15184.35
|
assert result == 15184.35
|
||||||
|
|
||||||
result = fiat_convert.convert_amount(
|
result = fiat_convert.convert_amount(crypto_amount=1.23, crypto_symbol="BTC", fiat_symbol="BTC")
|
||||||
crypto_amount=1.23,
|
|
||||||
crypto_symbol="BTC",
|
|
||||||
fiat_symbol="BTC"
|
|
||||||
)
|
|
||||||
assert result == 1.23
|
assert result == 1.23
|
||||||
|
|
||||||
result = fiat_convert.convert_amount(
|
result = fiat_convert.convert_amount(
|
||||||
crypto_amount="1.23",
|
crypto_amount="1.23", crypto_symbol="BTC", fiat_symbol="BTC"
|
||||||
crypto_symbol="BTC",
|
|
||||||
fiat_symbol="BTC"
|
|
||||||
)
|
)
|
||||||
assert result == 1.23
|
assert result == 1.23
|
||||||
|
|||||||
+624
-622
File diff suppressed because it is too large
Load Diff
+1265
-920
File diff suppressed because it is too large
Load Diff
+83
-71
@@ -1,6 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
Unit test file for rpc/external_message_consumer.py
|
Unit test file for rpc/external_message_consumer.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
@@ -21,19 +22,16 @@ _TEST_WS_PORT = 9989
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def patched_emc(default_conf, mocker):
|
def patched_emc(default_conf, mocker):
|
||||||
default_conf.update({
|
default_conf.update(
|
||||||
|
{
|
||||||
"external_message_consumer": {
|
"external_message_consumer": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"producers": [
|
"producers": [
|
||||||
{
|
{"name": "default", "host": "null", "port": 9891, "ws_token": _TEST_WS_TOKEN}
|
||||||
"name": "default",
|
],
|
||||||
"host": "null",
|
|
||||||
"port": 9891,
|
|
||||||
"ws_token": _TEST_WS_TOKEN
|
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
dataprovider = DataProvider(default_conf, None, None, None)
|
dataprovider = DataProvider(default_conf, None, None, None)
|
||||||
emc = ExternalMessageConsumer(default_conf, dataprovider)
|
emc = ExternalMessageConsumer(default_conf, dataprovider)
|
||||||
|
|
||||||
@@ -81,7 +79,7 @@ def test_emc_init(patched_emc):
|
|||||||
# Parametrize this?
|
# Parametrize this?
|
||||||
def test_emc_handle_producer_message(patched_emc, caplog, ohlcv_history):
|
def test_emc_handle_producer_message(patched_emc, caplog, ohlcv_history):
|
||||||
test_producer = {"name": "test", "url": "ws://test", "ws_token": "test"}
|
test_producer = {"name": "test", "url": "ws://test", "ws_token": "test"}
|
||||||
producer_name = test_producer['name']
|
producer_name = test_producer["name"]
|
||||||
invalid_msg = r"Invalid message .+"
|
invalid_msg = r"Invalid message .+"
|
||||||
|
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
@@ -92,7 +90,8 @@ def test_emc_handle_producer_message(patched_emc, caplog, ohlcv_history):
|
|||||||
|
|
||||||
assert log_has(f"Received message of type `whitelist` from `{producer_name}`", caplog)
|
assert log_has(f"Received message of type `whitelist` from `{producer_name}`", caplog)
|
||||||
assert log_has(
|
assert log_has(
|
||||||
f"Consumed message from `{producer_name}` of type `RPCMessageType.WHITELIST`", caplog)
|
f"Consumed message from `{producer_name}` of type `RPCMessageType.WHITELIST`", caplog
|
||||||
|
)
|
||||||
|
|
||||||
# Test handle analyzed_df single candle message
|
# Test handle analyzed_df single candle message
|
||||||
df_message = {
|
df_message = {
|
||||||
@@ -100,8 +99,8 @@ def test_emc_handle_producer_message(patched_emc, caplog, ohlcv_history):
|
|||||||
"data": {
|
"data": {
|
||||||
"key": ("BTC/USDT", "5m", "spot"),
|
"key": ("BTC/USDT", "5m", "spot"),
|
||||||
"df": ohlcv_history,
|
"df": ohlcv_history,
|
||||||
"la": datetime.now(timezone.utc)
|
"la": datetime.now(timezone.utc),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
patched_emc.handle_producer_message(test_producer, df_message)
|
patched_emc.handle_producer_message(test_producer, df_message)
|
||||||
|
|
||||||
@@ -124,11 +123,7 @@ def test_emc_handle_producer_message(patched_emc, caplog, ohlcv_history):
|
|||||||
|
|
||||||
malformed_message = {
|
malformed_message = {
|
||||||
"type": "analyzed_df",
|
"type": "analyzed_df",
|
||||||
"data": {
|
"data": {"key": "BTC/USDT", "df": ohlcv_history, "la": datetime.now(timezone.utc)},
|
||||||
"key": "BTC/USDT",
|
|
||||||
"df": ohlcv_history,
|
|
||||||
"la": datetime.now(timezone.utc)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
patched_emc.handle_producer_message(test_producer, malformed_message)
|
patched_emc.handle_producer_message(test_producer, malformed_message)
|
||||||
|
|
||||||
@@ -141,9 +136,9 @@ def test_emc_handle_producer_message(patched_emc, caplog, ohlcv_history):
|
|||||||
"type": "analyzed_df",
|
"type": "analyzed_df",
|
||||||
"data": {
|
"data": {
|
||||||
"key": ("BTC/USDT", "5m", "spot"),
|
"key": ("BTC/USDT", "5m", "spot"),
|
||||||
"df": ohlcv_history.loc[ohlcv_history['open'] < 0],
|
"df": ohlcv_history.loc[ohlcv_history["open"] < 0],
|
||||||
"la": datetime.now(timezone.utc)
|
"la": datetime.now(timezone.utc),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
patched_emc.handle_producer_message(test_producer, malformed_message)
|
patched_emc.handle_producer_message(test_producer, malformed_message)
|
||||||
|
|
||||||
@@ -166,7 +161,8 @@ def test_emc_handle_producer_message(patched_emc, caplog, ohlcv_history):
|
|||||||
|
|
||||||
|
|
||||||
async def test_emc_create_connection_success(default_conf, caplog, mocker):
|
async def test_emc_create_connection_success(default_conf, caplog, mocker):
|
||||||
default_conf.update({
|
default_conf.update(
|
||||||
|
{
|
||||||
"external_message_consumer": {
|
"external_message_consumer": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"producers": [
|
"producers": [
|
||||||
@@ -174,21 +170,23 @@ async def test_emc_create_connection_success(default_conf, caplog, mocker):
|
|||||||
"name": "default",
|
"name": "default",
|
||||||
"host": _TEST_WS_HOST,
|
"host": _TEST_WS_HOST,
|
||||||
"port": _TEST_WS_PORT,
|
"port": _TEST_WS_PORT,
|
||||||
"ws_token": _TEST_WS_TOKEN
|
"ws_token": _TEST_WS_TOKEN,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"wait_timeout": 60,
|
"wait_timeout": 60,
|
||||||
"ping_timeout": 60,
|
"ping_timeout": 60,
|
||||||
"sleep_timeout": 60
|
"sleep_timeout": 60,
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
mocker.patch('freqtrade.rpc.external_message_consumer.ExternalMessageConsumer.start',
|
mocker.patch(
|
||||||
MagicMock())
|
"freqtrade.rpc.external_message_consumer.ExternalMessageConsumer.start", MagicMock()
|
||||||
|
)
|
||||||
dp = DataProvider(default_conf, None, None, None)
|
dp = DataProvider(default_conf, None, None, None)
|
||||||
emc = ExternalMessageConsumer(default_conf, dp)
|
emc = ExternalMessageConsumer(default_conf, dp)
|
||||||
|
|
||||||
test_producer = default_conf['external_message_consumer']['producers'][0]
|
test_producer = default_conf["external_message_consumer"]["producers"][0]
|
||||||
lock = asyncio.Lock()
|
lock = asyncio.Lock()
|
||||||
|
|
||||||
emc._running = True
|
emc._running = True
|
||||||
@@ -205,27 +203,27 @@ async def test_emc_create_connection_success(default_conf, caplog, mocker):
|
|||||||
emc.shutdown()
|
emc.shutdown()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('host,port', [
|
@pytest.mark.parametrize(
|
||||||
|
"host,port",
|
||||||
|
[
|
||||||
(_TEST_WS_HOST, -1),
|
(_TEST_WS_HOST, -1),
|
||||||
("10000.1241..2121/", _TEST_WS_PORT),
|
("10000.1241..2121/", _TEST_WS_PORT),
|
||||||
])
|
],
|
||||||
|
)
|
||||||
async def test_emc_create_connection_invalid_url(default_conf, caplog, mocker, host, port):
|
async def test_emc_create_connection_invalid_url(default_conf, caplog, mocker, host, port):
|
||||||
default_conf.update({
|
default_conf.update(
|
||||||
|
{
|
||||||
"external_message_consumer": {
|
"external_message_consumer": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"producers": [
|
"producers": [
|
||||||
{
|
{"name": "default", "host": host, "port": port, "ws_token": _TEST_WS_TOKEN}
|
||||||
"name": "default",
|
|
||||||
"host": host,
|
|
||||||
"port": port,
|
|
||||||
"ws_token": _TEST_WS_TOKEN
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"wait_timeout": 60,
|
"wait_timeout": 60,
|
||||||
"ping_timeout": 60,
|
"ping_timeout": 60,
|
||||||
"sleep_timeout": 60
|
"sleep_timeout": 60,
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
dp = DataProvider(default_conf, None, None, None)
|
dp = DataProvider(default_conf, None, None, None)
|
||||||
# Handle start explicitly to avoid messing with threading in tests
|
# Handle start explicitly to avoid messing with threading in tests
|
||||||
@@ -242,7 +240,8 @@ async def test_emc_create_connection_invalid_url(default_conf, caplog, mocker, h
|
|||||||
|
|
||||||
|
|
||||||
async def test_emc_create_connection_error(default_conf, caplog, mocker):
|
async def test_emc_create_connection_error(default_conf, caplog, mocker):
|
||||||
default_conf.update({
|
default_conf.update(
|
||||||
|
{
|
||||||
"external_message_consumer": {
|
"external_message_consumer": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"producers": [
|
"producers": [
|
||||||
@@ -250,17 +249,18 @@ async def test_emc_create_connection_error(default_conf, caplog, mocker):
|
|||||||
"name": "default",
|
"name": "default",
|
||||||
"host": _TEST_WS_HOST,
|
"host": _TEST_WS_HOST,
|
||||||
"port": _TEST_WS_PORT,
|
"port": _TEST_WS_PORT,
|
||||||
"ws_token": _TEST_WS_TOKEN
|
"ws_token": _TEST_WS_TOKEN,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"wait_timeout": 60,
|
"wait_timeout": 60,
|
||||||
"ping_timeout": 60,
|
"ping_timeout": 60,
|
||||||
"sleep_timeout": 60
|
"sleep_timeout": 60,
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# Test unexpected error
|
# Test unexpected error
|
||||||
mocker.patch('websockets.connect', side_effect=RuntimeError)
|
mocker.patch("websockets.connect", side_effect=RuntimeError)
|
||||||
|
|
||||||
dp = DataProvider(default_conf, None, None, None)
|
dp = DataProvider(default_conf, None, None, None)
|
||||||
emc = ExternalMessageConsumer(default_conf, dp)
|
emc = ExternalMessageConsumer(default_conf, dp)
|
||||||
@@ -275,7 +275,8 @@ async def test_emc_create_connection_error(default_conf, caplog, mocker):
|
|||||||
async def test_emc_receive_messages_valid(default_conf, caplog, mocker):
|
async def test_emc_receive_messages_valid(default_conf, caplog, mocker):
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
|
|
||||||
default_conf.update({
|
default_conf.update(
|
||||||
|
{
|
||||||
"external_message_consumer": {
|
"external_message_consumer": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"producers": [
|
"producers": [
|
||||||
@@ -283,20 +284,22 @@ async def test_emc_receive_messages_valid(default_conf, caplog, mocker):
|
|||||||
"name": "default",
|
"name": "default",
|
||||||
"host": _TEST_WS_HOST,
|
"host": _TEST_WS_HOST,
|
||||||
"port": _TEST_WS_PORT,
|
"port": _TEST_WS_PORT,
|
||||||
"ws_token": _TEST_WS_TOKEN
|
"ws_token": _TEST_WS_TOKEN,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"wait_timeout": 1,
|
"wait_timeout": 1,
|
||||||
"ping_timeout": 60,
|
"ping_timeout": 60,
|
||||||
"sleep_time": 60
|
"sleep_time": 60,
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
mocker.patch('freqtrade.rpc.external_message_consumer.ExternalMessageConsumer.start',
|
mocker.patch(
|
||||||
MagicMock())
|
"freqtrade.rpc.external_message_consumer.ExternalMessageConsumer.start", MagicMock()
|
||||||
|
)
|
||||||
|
|
||||||
lock = asyncio.Lock()
|
lock = asyncio.Lock()
|
||||||
test_producer = default_conf['external_message_consumer']['producers'][0]
|
test_producer = default_conf["external_message_consumer"]["producers"][0]
|
||||||
|
|
||||||
dp = DataProvider(default_conf, None, None, None)
|
dp = DataProvider(default_conf, None, None, None)
|
||||||
emc = ExternalMessageConsumer(default_conf, dp)
|
emc = ExternalMessageConsumer(default_conf, dp)
|
||||||
@@ -319,7 +322,8 @@ async def test_emc_receive_messages_valid(default_conf, caplog, mocker):
|
|||||||
|
|
||||||
|
|
||||||
async def test_emc_receive_messages_invalid(default_conf, caplog, mocker):
|
async def test_emc_receive_messages_invalid(default_conf, caplog, mocker):
|
||||||
default_conf.update({
|
default_conf.update(
|
||||||
|
{
|
||||||
"external_message_consumer": {
|
"external_message_consumer": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"producers": [
|
"producers": [
|
||||||
@@ -327,20 +331,22 @@ async def test_emc_receive_messages_invalid(default_conf, caplog, mocker):
|
|||||||
"name": "default",
|
"name": "default",
|
||||||
"host": _TEST_WS_HOST,
|
"host": _TEST_WS_HOST,
|
||||||
"port": _TEST_WS_PORT,
|
"port": _TEST_WS_PORT,
|
||||||
"ws_token": _TEST_WS_TOKEN
|
"ws_token": _TEST_WS_TOKEN,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"wait_timeout": 1,
|
"wait_timeout": 1,
|
||||||
"ping_timeout": 60,
|
"ping_timeout": 60,
|
||||||
"sleep_time": 60
|
"sleep_time": 60,
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
mocker.patch('freqtrade.rpc.external_message_consumer.ExternalMessageConsumer.start',
|
mocker.patch(
|
||||||
MagicMock())
|
"freqtrade.rpc.external_message_consumer.ExternalMessageConsumer.start", MagicMock()
|
||||||
|
)
|
||||||
|
|
||||||
lock = asyncio.Lock()
|
lock = asyncio.Lock()
|
||||||
test_producer = default_conf['external_message_consumer']['producers'][0]
|
test_producer = default_conf["external_message_consumer"]["producers"][0]
|
||||||
|
|
||||||
dp = DataProvider(default_conf, None, None, None)
|
dp = DataProvider(default_conf, None, None, None)
|
||||||
emc = ExternalMessageConsumer(default_conf, dp)
|
emc = ExternalMessageConsumer(default_conf, dp)
|
||||||
@@ -363,7 +369,8 @@ async def test_emc_receive_messages_invalid(default_conf, caplog, mocker):
|
|||||||
|
|
||||||
|
|
||||||
async def test_emc_receive_messages_timeout(default_conf, caplog, mocker):
|
async def test_emc_receive_messages_timeout(default_conf, caplog, mocker):
|
||||||
default_conf.update({
|
default_conf.update(
|
||||||
|
{
|
||||||
"external_message_consumer": {
|
"external_message_consumer": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"producers": [
|
"producers": [
|
||||||
@@ -371,20 +378,22 @@ async def test_emc_receive_messages_timeout(default_conf, caplog, mocker):
|
|||||||
"name": "default",
|
"name": "default",
|
||||||
"host": _TEST_WS_HOST,
|
"host": _TEST_WS_HOST,
|
||||||
"port": _TEST_WS_PORT,
|
"port": _TEST_WS_PORT,
|
||||||
"ws_token": _TEST_WS_TOKEN
|
"ws_token": _TEST_WS_TOKEN,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"wait_timeout": 0.1,
|
"wait_timeout": 0.1,
|
||||||
"ping_timeout": 1,
|
"ping_timeout": 1,
|
||||||
"sleep_time": 1
|
"sleep_time": 1,
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
mocker.patch('freqtrade.rpc.external_message_consumer.ExternalMessageConsumer.start',
|
mocker.patch(
|
||||||
MagicMock())
|
"freqtrade.rpc.external_message_consumer.ExternalMessageConsumer.start", MagicMock()
|
||||||
|
)
|
||||||
|
|
||||||
lock = asyncio.Lock()
|
lock = asyncio.Lock()
|
||||||
test_producer = default_conf['external_message_consumer']['producers'][0]
|
test_producer = default_conf["external_message_consumer"]["producers"][0]
|
||||||
|
|
||||||
dp = DataProvider(default_conf, None, None, None)
|
dp = DataProvider(default_conf, None, None, None)
|
||||||
emc = ExternalMessageConsumer(default_conf, dp)
|
emc = ExternalMessageConsumer(default_conf, dp)
|
||||||
@@ -411,7 +420,8 @@ async def test_emc_receive_messages_timeout(default_conf, caplog, mocker):
|
|||||||
|
|
||||||
|
|
||||||
async def test_emc_receive_messages_handle_error(default_conf, caplog, mocker):
|
async def test_emc_receive_messages_handle_error(default_conf, caplog, mocker):
|
||||||
default_conf.update({
|
default_conf.update(
|
||||||
|
{
|
||||||
"external_message_consumer": {
|
"external_message_consumer": {
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"producers": [
|
"producers": [
|
||||||
@@ -419,20 +429,22 @@ async def test_emc_receive_messages_handle_error(default_conf, caplog, mocker):
|
|||||||
"name": "default",
|
"name": "default",
|
||||||
"host": _TEST_WS_HOST,
|
"host": _TEST_WS_HOST,
|
||||||
"port": _TEST_WS_PORT,
|
"port": _TEST_WS_PORT,
|
||||||
"ws_token": _TEST_WS_TOKEN
|
"ws_token": _TEST_WS_TOKEN,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"wait_timeout": 1,
|
"wait_timeout": 1,
|
||||||
"ping_timeout": 1,
|
"ping_timeout": 1,
|
||||||
"sleep_time": 1
|
"sleep_time": 1,
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
mocker.patch('freqtrade.rpc.external_message_consumer.ExternalMessageConsumer.start',
|
mocker.patch(
|
||||||
MagicMock())
|
"freqtrade.rpc.external_message_consumer.ExternalMessageConsumer.start", MagicMock()
|
||||||
|
)
|
||||||
|
|
||||||
lock = asyncio.Lock()
|
lock = asyncio.Lock()
|
||||||
test_producer = default_conf['external_message_consumer']['producers'][0]
|
test_producer = default_conf["external_message_consumer"]["producers"][0]
|
||||||
|
|
||||||
dp = DataProvider(default_conf, None, None, None)
|
dp = DataProvider(default_conf, None, None, None)
|
||||||
emc = ExternalMessageConsumer(default_conf, dp)
|
emc = ExternalMessageConsumer(default_conf, dp)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from tests.conftest import get_patched_freqtradebot, log_has
|
|||||||
|
|
||||||
|
|
||||||
def test__init__(mocker, default_conf) -> None:
|
def test__init__(mocker, default_conf) -> None:
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf["telegram"]["enabled"] = False
|
||||||
|
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
assert rpc_manager.registered_modules == []
|
assert rpc_manager.registered_modules == []
|
||||||
@@ -19,97 +19,91 @@ def test__init__(mocker, default_conf) -> None:
|
|||||||
|
|
||||||
def test_init_telegram_disabled(mocker, default_conf, caplog) -> None:
|
def test_init_telegram_disabled(mocker, default_conf, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf["telegram"]["enabled"] = False
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert not log_has('Enabling rpc.telegram ...', caplog)
|
assert not log_has("Enabling rpc.telegram ...", caplog)
|
||||||
assert rpc_manager.registered_modules == []
|
assert rpc_manager.registered_modules == []
|
||||||
|
|
||||||
|
|
||||||
def test_init_telegram_enabled(mocker, default_conf, caplog) -> None:
|
def test_init_telegram_enabled(mocker, default_conf, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
default_conf['telegram']['enabled'] = True
|
default_conf["telegram"]["enabled"] = True
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
mocker.patch("freqtrade.rpc.telegram.Telegram._init", MagicMock())
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert log_has('Enabling rpc.telegram ...', caplog)
|
assert log_has("Enabling rpc.telegram ...", caplog)
|
||||||
len_modules = len(rpc_manager.registered_modules)
|
len_modules = len(rpc_manager.registered_modules)
|
||||||
assert len_modules == 1
|
assert len_modules == 1
|
||||||
assert 'telegram' in [mod.name for mod in rpc_manager.registered_modules]
|
assert "telegram" in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
|
|
||||||
|
|
||||||
def test_cleanup_telegram_disabled(mocker, default_conf, caplog) -> None:
|
def test_cleanup_telegram_disabled(mocker, default_conf, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.cleanup', MagicMock())
|
telegram_mock = mocker.patch("freqtrade.rpc.telegram.Telegram.cleanup", MagicMock())
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf["telegram"]["enabled"] = False
|
||||||
|
|
||||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc_manager = RPCManager(freqtradebot)
|
rpc_manager = RPCManager(freqtradebot)
|
||||||
rpc_manager.cleanup()
|
rpc_manager.cleanup()
|
||||||
|
|
||||||
assert not log_has('Cleaning up rpc.telegram ...', caplog)
|
assert not log_has("Cleaning up rpc.telegram ...", caplog)
|
||||||
assert telegram_mock.call_count == 0
|
assert telegram_mock.call_count == 0
|
||||||
|
|
||||||
|
|
||||||
def test_cleanup_telegram_enabled(mocker, default_conf, caplog) -> None:
|
def test_cleanup_telegram_enabled(mocker, default_conf, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
default_conf['telegram']['enabled'] = True
|
default_conf["telegram"]["enabled"] = True
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
mocker.patch("freqtrade.rpc.telegram.Telegram._init", MagicMock())
|
||||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.cleanup', MagicMock())
|
telegram_mock = mocker.patch("freqtrade.rpc.telegram.Telegram.cleanup", MagicMock())
|
||||||
|
|
||||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc_manager = RPCManager(freqtradebot)
|
rpc_manager = RPCManager(freqtradebot)
|
||||||
|
|
||||||
# Check we have Telegram as a registered modules
|
# Check we have Telegram as a registered modules
|
||||||
assert 'telegram' in [mod.name for mod in rpc_manager.registered_modules]
|
assert "telegram" in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
|
|
||||||
rpc_manager.cleanup()
|
rpc_manager.cleanup()
|
||||||
assert log_has('Cleaning up rpc.telegram ...', caplog)
|
assert log_has("Cleaning up rpc.telegram ...", caplog)
|
||||||
assert 'telegram' not in [mod.name for mod in rpc_manager.registered_modules]
|
assert "telegram" not in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
assert telegram_mock.call_count == 1
|
assert telegram_mock.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
def test_send_msg_telegram_disabled(mocker, default_conf, caplog) -> None:
|
def test_send_msg_telegram_disabled(mocker, default_conf, caplog) -> None:
|
||||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
|
telegram_mock = mocker.patch("freqtrade.rpc.telegram.Telegram.send_msg", MagicMock())
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf["telegram"]["enabled"] = False
|
||||||
|
|
||||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc_manager = RPCManager(freqtradebot)
|
rpc_manager = RPCManager(freqtradebot)
|
||||||
rpc_manager.send_msg({
|
rpc_manager.send_msg({"type": RPCMessageType.STATUS, "status": "test"})
|
||||||
'type': RPCMessageType.STATUS,
|
|
||||||
'status': 'test'
|
|
||||||
})
|
|
||||||
|
|
||||||
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog)
|
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog)
|
||||||
assert telegram_mock.call_count == 0
|
assert telegram_mock.call_count == 0
|
||||||
|
|
||||||
|
|
||||||
def test_send_msg_telegram_error(mocker, default_conf, caplog) -> None:
|
def test_send_msg_telegram_error(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
mocker.patch("freqtrade.rpc.telegram.Telegram._init", MagicMock())
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', side_effect=ValueError())
|
mocker.patch("freqtrade.rpc.telegram.Telegram.send_msg", side_effect=ValueError())
|
||||||
default_conf['telegram']['enabled'] = True
|
default_conf["telegram"]["enabled"] = True
|
||||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc_manager = RPCManager(freqtradebot)
|
rpc_manager = RPCManager(freqtradebot)
|
||||||
rpc_manager.send_msg({
|
rpc_manager.send_msg({"type": RPCMessageType.STATUS, "status": "test"})
|
||||||
'type': RPCMessageType.STATUS,
|
|
||||||
'status': 'test'
|
|
||||||
})
|
|
||||||
|
|
||||||
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog)
|
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog)
|
||||||
assert log_has("Exception occurred within RPC module telegram", caplog)
|
assert log_has("Exception occurred within RPC module telegram", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_process_msg_queue(mocker, default_conf, caplog) -> None:
|
def test_process_msg_queue(mocker, default_conf, caplog) -> None:
|
||||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg')
|
telegram_mock = mocker.patch("freqtrade.rpc.telegram.Telegram.send_msg")
|
||||||
default_conf['telegram']['enabled'] = True
|
default_conf["telegram"]["enabled"] = True
|
||||||
default_conf['telegram']['allow_custom_messages'] = True
|
default_conf["telegram"]["allow_custom_messages"] = True
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init')
|
mocker.patch("freqtrade.rpc.telegram.Telegram._init")
|
||||||
|
|
||||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc_manager = RPCManager(freqtradebot)
|
rpc_manager = RPCManager(freqtradebot)
|
||||||
queue = deque()
|
queue = deque()
|
||||||
queue.append('Test message')
|
queue.append("Test message")
|
||||||
queue.append('Test message 2')
|
queue.append("Test message 2")
|
||||||
rpc_manager.process_msg_queue(queue)
|
rpc_manager.process_msg_queue(queue)
|
||||||
|
|
||||||
assert log_has("Sending rpc strategy_msg: Test message", caplog)
|
assert log_has("Sending rpc strategy_msg: Test message", caplog)
|
||||||
@@ -118,15 +112,12 @@ def test_process_msg_queue(mocker, default_conf, caplog) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_send_msg_telegram_enabled(mocker, default_conf, caplog) -> None:
|
def test_send_msg_telegram_enabled(mocker, default_conf, caplog) -> None:
|
||||||
default_conf['telegram']['enabled'] = True
|
default_conf["telegram"]["enabled"] = True
|
||||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg')
|
telegram_mock = mocker.patch("freqtrade.rpc.telegram.Telegram.send_msg")
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init')
|
mocker.patch("freqtrade.rpc.telegram.Telegram._init")
|
||||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc_manager = RPCManager(freqtradebot)
|
rpc_manager = RPCManager(freqtradebot)
|
||||||
rpc_manager.send_msg({
|
rpc_manager.send_msg({"type": RPCMessageType.STATUS, "status": "test"})
|
||||||
'type': RPCMessageType.STATUS,
|
|
||||||
'status': 'test'
|
|
||||||
})
|
|
||||||
|
|
||||||
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog)
|
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog)
|
||||||
assert telegram_mock.call_count == 1
|
assert telegram_mock.call_count == 1
|
||||||
@@ -134,76 +125,73 @@ def test_send_msg_telegram_enabled(mocker, default_conf, caplog) -> None:
|
|||||||
|
|
||||||
def test_init_webhook_disabled(mocker, default_conf, caplog) -> None:
|
def test_init_webhook_disabled(mocker, default_conf, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf["telegram"]["enabled"] = False
|
||||||
default_conf['webhook'] = {'enabled': False}
|
default_conf["webhook"] = {"enabled": False}
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert not log_has('Enabling rpc.webhook ...', caplog)
|
assert not log_has("Enabling rpc.webhook ...", caplog)
|
||||||
assert rpc_manager.registered_modules == []
|
assert rpc_manager.registered_modules == []
|
||||||
|
|
||||||
|
|
||||||
def test_init_webhook_enabled(mocker, default_conf, caplog) -> None:
|
def test_init_webhook_enabled(mocker, default_conf, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf["telegram"]["enabled"] = False
|
||||||
default_conf['webhook'] = {'enabled': True, 'url': "https://DEADBEEF.com"}
|
default_conf["webhook"] = {"enabled": True, "url": "https://DEADBEEF.com"}
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert log_has('Enabling rpc.webhook ...', caplog)
|
assert log_has("Enabling rpc.webhook ...", caplog)
|
||||||
assert len(rpc_manager.registered_modules) == 1
|
assert len(rpc_manager.registered_modules) == 1
|
||||||
assert 'webhook' in [mod.name for mod in rpc_manager.registered_modules]
|
assert "webhook" in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
|
|
||||||
|
|
||||||
def test_send_msg_webhook_CustomMessagetype(mocker, default_conf, caplog) -> None:
|
def test_send_msg_webhook_CustomMessagetype(mocker, default_conf, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf["telegram"]["enabled"] = False
|
||||||
default_conf['webhook'] = {'enabled': True, 'url': "https://DEADBEEF.com"}
|
default_conf["webhook"] = {"enabled": True, "url": "https://DEADBEEF.com"}
|
||||||
mocker.patch('freqtrade.rpc.webhook.Webhook.send_msg',
|
mocker.patch(
|
||||||
MagicMock(side_effect=NotImplementedError))
|
"freqtrade.rpc.webhook.Webhook.send_msg", MagicMock(side_effect=NotImplementedError)
|
||||||
|
)
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert 'webhook' in [mod.name for mod in rpc_manager.registered_modules]
|
assert "webhook" in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
rpc_manager.send_msg({'type': RPCMessageType.STARTUP,
|
rpc_manager.send_msg({"type": RPCMessageType.STARTUP, "status": "TestMessage"})
|
||||||
'status': 'TestMessage'})
|
assert log_has("Message type 'startup' not implemented by handler webhook.", caplog)
|
||||||
assert log_has(
|
|
||||||
"Message type 'startup' not implemented by handler webhook.",
|
|
||||||
caplog)
|
|
||||||
|
|
||||||
|
|
||||||
def test_startupmessages_telegram_enabled(mocker, default_conf) -> None:
|
def test_startupmessages_telegram_enabled(mocker, default_conf) -> None:
|
||||||
default_conf['telegram']['enabled'] = True
|
default_conf["telegram"]["enabled"] = True
|
||||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
|
telegram_mock = mocker.patch("freqtrade.rpc.telegram.Telegram.send_msg", MagicMock())
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
mocker.patch("freqtrade.rpc.telegram.Telegram._init", MagicMock())
|
||||||
|
|
||||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc_manager = RPCManager(freqtradebot)
|
rpc_manager = RPCManager(freqtradebot)
|
||||||
rpc_manager.startup_messages(default_conf, freqtradebot.pairlists, freqtradebot.protections)
|
rpc_manager.startup_messages(default_conf, freqtradebot.pairlists, freqtradebot.protections)
|
||||||
|
|
||||||
assert telegram_mock.call_count == 3
|
assert telegram_mock.call_count == 3
|
||||||
assert "*Exchange:* `binance`" in telegram_mock.call_args_list[1][0][0]['status']
|
assert "*Exchange:* `binance`" in telegram_mock.call_args_list[1][0][0]["status"]
|
||||||
|
|
||||||
telegram_mock.reset_mock()
|
telegram_mock.reset_mock()
|
||||||
default_conf['dry_run'] = True
|
default_conf["dry_run"] = True
|
||||||
default_conf['whitelist'] = {'method': 'VolumePairList',
|
default_conf["whitelist"] = {"method": "VolumePairList", "config": {"number_assets": 20}}
|
||||||
'config': {'number_assets': 20}
|
default_conf["protections"] = [
|
||||||
}
|
{"method": "StoplossGuard", "lookback_period": 60, "trade_limit": 2, "stop_duration": 60}
|
||||||
default_conf['protections'] = [{"method": "StoplossGuard",
|
]
|
||||||
"lookback_period": 60, "trade_limit": 2, "stop_duration": 60}]
|
|
||||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
|
|
||||||
rpc_manager.startup_messages(default_conf, freqtradebot.pairlists, freqtradebot.protections)
|
rpc_manager.startup_messages(default_conf, freqtradebot.pairlists, freqtradebot.protections)
|
||||||
assert telegram_mock.call_count == 4
|
assert telegram_mock.call_count == 4
|
||||||
assert "Dry run is enabled." in telegram_mock.call_args_list[0][0][0]['status']
|
assert "Dry run is enabled." in telegram_mock.call_args_list[0][0][0]["status"]
|
||||||
assert 'StoplossGuard' in telegram_mock.call_args_list[-1][0][0]['status']
|
assert "StoplossGuard" in telegram_mock.call_args_list[-1][0][0]["status"]
|
||||||
|
|
||||||
|
|
||||||
def test_init_apiserver_disabled(mocker, default_conf, caplog) -> None:
|
def test_init_apiserver_disabled(mocker, default_conf, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
run_mock = MagicMock()
|
run_mock = MagicMock()
|
||||||
mocker.patch('freqtrade.rpc.api_server.ApiServer.start_api', run_mock)
|
mocker.patch("freqtrade.rpc.api_server.ApiServer.start_api", run_mock)
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf["telegram"]["enabled"] = False
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert not log_has('Enabling rpc.api_server', caplog)
|
assert not log_has("Enabling rpc.api_server", caplog)
|
||||||
assert rpc_manager.registered_modules == []
|
assert rpc_manager.registered_modules == []
|
||||||
assert run_mock.call_count == 0
|
assert run_mock.call_count == 0
|
||||||
|
|
||||||
@@ -211,10 +199,11 @@ def test_init_apiserver_disabled(mocker, default_conf, caplog) -> None:
|
|||||||
def test_init_apiserver_enabled(mocker, default_conf, caplog) -> None:
|
def test_init_apiserver_enabled(mocker, default_conf, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
run_mock = MagicMock()
|
run_mock = MagicMock()
|
||||||
mocker.patch('freqtrade.rpc.api_server.ApiServer.start_api', run_mock)
|
mocker.patch("freqtrade.rpc.api_server.ApiServer.start_api", run_mock)
|
||||||
|
|
||||||
default_conf["telegram"]["enabled"] = False
|
default_conf["telegram"]["enabled"] = False
|
||||||
default_conf["api_server"] = {"enabled": True,
|
default_conf["api_server"] = {
|
||||||
|
"enabled": True,
|
||||||
"listen_ip_address": "127.0.0.1",
|
"listen_ip_address": "127.0.0.1",
|
||||||
"listen_port": 8080,
|
"listen_port": 8080,
|
||||||
"username": "TestUser",
|
"username": "TestUser",
|
||||||
@@ -224,8 +213,8 @@ def test_init_apiserver_enabled(mocker, default_conf, caplog) -> None:
|
|||||||
|
|
||||||
# Sleep to allow the thread to start
|
# Sleep to allow the thread to start
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
assert log_has('Enabling rpc.api_server', caplog)
|
assert log_has("Enabling rpc.api_server", caplog)
|
||||||
assert len(rpc_manager.registered_modules) == 1
|
assert len(rpc_manager.registered_modules) == 1
|
||||||
assert 'apiserver' in [mod.name for mod in rpc_manager.registered_modules]
|
assert "apiserver" in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
assert run_mock.call_count == 1
|
assert run_mock.call_count == 1
|
||||||
ApiServer.shutdown()
|
ApiServer.shutdown()
|
||||||
|
|||||||
+1092
-1002
File diff suppressed because it is too large
Load Diff
+273
-252
@@ -26,47 +26,43 @@ def get_webhook_dict() -> dict:
|
|||||||
"value2": "limit {limit:8f}",
|
"value2": "limit {limit:8f}",
|
||||||
"value3": "{stake_amount:8f} {stake_currency}",
|
"value3": "{stake_amount:8f} {stake_currency}",
|
||||||
"value4": "leverage {leverage:.1f}",
|
"value4": "leverage {leverage:.1f}",
|
||||||
"value5": "direction {direction}"
|
"value5": "direction {direction}",
|
||||||
},
|
},
|
||||||
"webhookentrycancel": {
|
"webhookentrycancel": {
|
||||||
"value1": "Cancelling Open Buy Order for {pair}",
|
"value1": "Cancelling Open Buy Order for {pair}",
|
||||||
"value2": "limit {limit:8f}",
|
"value2": "limit {limit:8f}",
|
||||||
"value3": "{stake_amount:8f} {stake_currency}",
|
"value3": "{stake_amount:8f} {stake_currency}",
|
||||||
"value4": "leverage {leverage:.1f}",
|
"value4": "leverage {leverage:.1f}",
|
||||||
"value5": "direction {direction}"
|
"value5": "direction {direction}",
|
||||||
},
|
},
|
||||||
"webhookentryfill": {
|
"webhookentryfill": {
|
||||||
"value1": "Buy Order for {pair} filled",
|
"value1": "Buy Order for {pair} filled",
|
||||||
"value2": "at {open_rate:8f}",
|
"value2": "at {open_rate:8f}",
|
||||||
"value3": "{stake_amount:8f} {stake_currency}",
|
"value3": "{stake_amount:8f} {stake_currency}",
|
||||||
"value4": "leverage {leverage:.1f}",
|
"value4": "leverage {leverage:.1f}",
|
||||||
"value5": "direction {direction}"
|
"value5": "direction {direction}",
|
||||||
},
|
},
|
||||||
"webhookexit": {
|
"webhookexit": {
|
||||||
"value1": "Selling {pair}",
|
"value1": "Selling {pair}",
|
||||||
"value2": "limit {limit:8f}",
|
"value2": "limit {limit:8f}",
|
||||||
"value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})"
|
"value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})",
|
||||||
},
|
},
|
||||||
"webhookexitcancel": {
|
"webhookexitcancel": {
|
||||||
"value1": "Cancelling Open Sell Order for {pair}",
|
"value1": "Cancelling Open Sell Order for {pair}",
|
||||||
"value2": "limit {limit:8f}",
|
"value2": "limit {limit:8f}",
|
||||||
"value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})"
|
"value3": "profit: {profit_amount:8f} {stake_currency} ({profit_ratio})",
|
||||||
},
|
},
|
||||||
"webhookexitfill": {
|
"webhookexitfill": {
|
||||||
"value1": "Sell Order for {pair} filled",
|
"value1": "Sell Order for {pair} filled",
|
||||||
"value2": "at {close_rate:8f}",
|
"value2": "at {close_rate:8f}",
|
||||||
"value3": ""
|
"value3": "",
|
||||||
},
|
},
|
||||||
"webhookstatus": {
|
"webhookstatus": {"value1": "Status: {status}", "value2": "", "value3": ""},
|
||||||
"value1": "Status: {status}",
|
|
||||||
"value2": "",
|
|
||||||
"value3": ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test__init__(mocker, default_conf):
|
def test__init__(mocker, default_conf):
|
||||||
default_conf['webhook'] = {'enabled': True, 'url': "https://DEADBEEF.com"}
|
default_conf["webhook"] = {"enabled": True, "url": "https://DEADBEEF.com"}
|
||||||
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
||||||
assert webhook._config == default_conf
|
assert webhook._config == default_conf
|
||||||
|
|
||||||
@@ -80,255 +76,290 @@ def test_send_msg_webhook(default_conf, mocker):
|
|||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
|
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.ENTRY,
|
"type": RPCMessageType.ENTRY,
|
||||||
'exchange': 'Binance',
|
"exchange": "Binance",
|
||||||
'pair': 'ETH/BTC',
|
"pair": "ETH/BTC",
|
||||||
'leverage': 1.0,
|
"leverage": 1.0,
|
||||||
'direction': 'Long',
|
"direction": "Long",
|
||||||
'limit': 0.005,
|
"limit": 0.005,
|
||||||
'stake_amount': 0.8,
|
"stake_amount": 0.8,
|
||||||
'stake_amount_fiat': 500,
|
"stake_amount_fiat": 500,
|
||||||
'stake_currency': 'BTC',
|
"stake_currency": "BTC",
|
||||||
'fiat_currency': 'EUR'
|
"fiat_currency": "EUR",
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg=msg)
|
webhook.send_msg(msg=msg)
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert (msg_mock.call_args[0][0]["value1"] ==
|
assert msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]["entry"]["value1"].format(
|
||||||
default_conf["webhook"]["entry"]["value1"].format(**msg))
|
**msg
|
||||||
assert (msg_mock.call_args[0][0]["value2"] ==
|
)
|
||||||
default_conf["webhook"]["entry"]["value2"].format(**msg))
|
assert msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]["entry"]["value2"].format(
|
||||||
assert (msg_mock.call_args[0][0]["value3"] ==
|
**msg
|
||||||
default_conf["webhook"]["entry"]["value3"].format(**msg))
|
)
|
||||||
assert (msg_mock.call_args[0][0]["value4"] ==
|
assert msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["entry"]["value3"].format(
|
||||||
default_conf["webhook"]["entry"]["value4"].format(**msg))
|
**msg
|
||||||
assert (msg_mock.call_args[0][0]["value5"] ==
|
)
|
||||||
default_conf["webhook"]["entry"]["value5"].format(**msg))
|
assert msg_mock.call_args[0][0]["value4"] == default_conf["webhook"]["entry"]["value4"].format(
|
||||||
|
**msg
|
||||||
|
)
|
||||||
|
assert msg_mock.call_args[0][0]["value5"] == default_conf["webhook"]["entry"]["value5"].format(
|
||||||
|
**msg
|
||||||
|
)
|
||||||
# Test short
|
# Test short
|
||||||
msg_mock.reset_mock()
|
msg_mock.reset_mock()
|
||||||
|
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.ENTRY,
|
"type": RPCMessageType.ENTRY,
|
||||||
'exchange': 'Binance',
|
"exchange": "Binance",
|
||||||
'pair': 'ETH/BTC',
|
"pair": "ETH/BTC",
|
||||||
'leverage': 2.0,
|
"leverage": 2.0,
|
||||||
'direction': 'Short',
|
"direction": "Short",
|
||||||
'limit': 0.005,
|
"limit": 0.005,
|
||||||
'stake_amount': 0.8,
|
"stake_amount": 0.8,
|
||||||
'stake_amount_fiat': 500,
|
"stake_amount_fiat": 500,
|
||||||
'stake_currency': 'BTC',
|
"stake_currency": "BTC",
|
||||||
'fiat_currency': 'EUR'
|
"fiat_currency": "EUR",
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg=msg)
|
webhook.send_msg(msg=msg)
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert (msg_mock.call_args[0][0]["value1"] ==
|
assert msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]["entry"]["value1"].format(
|
||||||
default_conf["webhook"]["entry"]["value1"].format(**msg))
|
**msg
|
||||||
assert (msg_mock.call_args[0][0]["value2"] ==
|
)
|
||||||
default_conf["webhook"]["entry"]["value2"].format(**msg))
|
assert msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]["entry"]["value2"].format(
|
||||||
assert (msg_mock.call_args[0][0]["value3"] ==
|
**msg
|
||||||
default_conf["webhook"]["entry"]["value3"].format(**msg))
|
)
|
||||||
assert (msg_mock.call_args[0][0]["value4"] ==
|
assert msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["entry"]["value3"].format(
|
||||||
default_conf["webhook"]["entry"]["value4"].format(**msg))
|
**msg
|
||||||
assert (msg_mock.call_args[0][0]["value5"] ==
|
)
|
||||||
default_conf["webhook"]["entry"]["value5"].format(**msg))
|
assert msg_mock.call_args[0][0]["value4"] == default_conf["webhook"]["entry"]["value4"].format(
|
||||||
|
**msg
|
||||||
|
)
|
||||||
|
assert msg_mock.call_args[0][0]["value5"] == default_conf["webhook"]["entry"]["value5"].format(
|
||||||
|
**msg
|
||||||
|
)
|
||||||
# Test buy cancel
|
# Test buy cancel
|
||||||
msg_mock.reset_mock()
|
msg_mock.reset_mock()
|
||||||
|
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.ENTRY_CANCEL,
|
"type": RPCMessageType.ENTRY_CANCEL,
|
||||||
'exchange': 'Binance',
|
"exchange": "Binance",
|
||||||
'pair': 'ETH/BTC',
|
"pair": "ETH/BTC",
|
||||||
'leverage': 1.0,
|
"leverage": 1.0,
|
||||||
'direction': 'Long',
|
"direction": "Long",
|
||||||
'limit': 0.005,
|
"limit": 0.005,
|
||||||
'stake_amount': 0.8,
|
"stake_amount": 0.8,
|
||||||
'stake_amount_fiat': 500,
|
"stake_amount_fiat": 500,
|
||||||
'stake_currency': 'BTC',
|
"stake_currency": "BTC",
|
||||||
'fiat_currency': 'EUR'
|
"fiat_currency": "EUR",
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg=msg)
|
webhook.send_msg(msg=msg)
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert (msg_mock.call_args[0][0]["value1"] ==
|
assert msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]["webhookentrycancel"][
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value1"].format(**msg))
|
"value1"
|
||||||
assert (msg_mock.call_args[0][0]["value2"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value2"].format(**msg))
|
assert msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]["webhookentrycancel"][
|
||||||
assert (msg_mock.call_args[0][0]["value3"] ==
|
"value2"
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value3"].format(**msg))
|
].format(**msg)
|
||||||
|
assert msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["webhookentrycancel"][
|
||||||
|
"value3"
|
||||||
|
].format(**msg)
|
||||||
# Test short cancel
|
# Test short cancel
|
||||||
msg_mock.reset_mock()
|
msg_mock.reset_mock()
|
||||||
|
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.ENTRY_CANCEL,
|
"type": RPCMessageType.ENTRY_CANCEL,
|
||||||
'exchange': 'Binance',
|
"exchange": "Binance",
|
||||||
'pair': 'ETH/BTC',
|
"pair": "ETH/BTC",
|
||||||
'leverage': 2.0,
|
"leverage": 2.0,
|
||||||
'direction': 'Short',
|
"direction": "Short",
|
||||||
'limit': 0.005,
|
"limit": 0.005,
|
||||||
'stake_amount': 0.8,
|
"stake_amount": 0.8,
|
||||||
'stake_amount_fiat': 500,
|
"stake_amount_fiat": 500,
|
||||||
'stake_currency': 'BTC',
|
"stake_currency": "BTC",
|
||||||
'fiat_currency': 'EUR'
|
"fiat_currency": "EUR",
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg=msg)
|
webhook.send_msg(msg=msg)
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert (msg_mock.call_args[0][0]["value1"] ==
|
assert msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]["webhookentrycancel"][
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value1"].format(**msg))
|
"value1"
|
||||||
assert (msg_mock.call_args[0][0]["value2"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value2"].format(**msg))
|
assert msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]["webhookentrycancel"][
|
||||||
assert (msg_mock.call_args[0][0]["value3"] ==
|
"value2"
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value3"].format(**msg))
|
].format(**msg)
|
||||||
assert (msg_mock.call_args[0][0]["value4"] ==
|
assert msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["webhookentrycancel"][
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value4"].format(**msg))
|
"value3"
|
||||||
assert (msg_mock.call_args[0][0]["value5"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value5"].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
|
# Test buy fill
|
||||||
msg_mock.reset_mock()
|
msg_mock.reset_mock()
|
||||||
|
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.ENTRY_FILL,
|
"type": RPCMessageType.ENTRY_FILL,
|
||||||
'exchange': 'Binance',
|
"exchange": "Binance",
|
||||||
'pair': 'ETH/BTC',
|
"pair": "ETH/BTC",
|
||||||
'leverage': 1.0,
|
"leverage": 1.0,
|
||||||
'direction': 'Long',
|
"direction": "Long",
|
||||||
'open_rate': 0.005,
|
"open_rate": 0.005,
|
||||||
'stake_amount': 0.8,
|
"stake_amount": 0.8,
|
||||||
'stake_amount_fiat': 500,
|
"stake_amount_fiat": 500,
|
||||||
'stake_currency': 'BTC',
|
"stake_currency": "BTC",
|
||||||
'fiat_currency': 'EUR'
|
"fiat_currency": "EUR",
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg=msg)
|
webhook.send_msg(msg=msg)
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert (msg_mock.call_args[0][0]["value1"] ==
|
assert msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]["webhookentryfill"][
|
||||||
default_conf["webhook"]["webhookentryfill"]["value1"].format(**msg))
|
"value1"
|
||||||
assert (msg_mock.call_args[0][0]["value2"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookentryfill"]["value2"].format(**msg))
|
assert msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]["webhookentryfill"][
|
||||||
assert (msg_mock.call_args[0][0]["value3"] ==
|
"value2"
|
||||||
default_conf["webhook"]["webhookentryfill"]["value3"].format(**msg))
|
].format(**msg)
|
||||||
assert (msg_mock.call_args[0][0]["value4"] ==
|
assert msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["webhookentryfill"][
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value4"].format(**msg))
|
"value3"
|
||||||
assert (msg_mock.call_args[0][0]["value5"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value5"].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
|
# Test short fill
|
||||||
msg_mock.reset_mock()
|
msg_mock.reset_mock()
|
||||||
|
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.ENTRY_FILL,
|
"type": RPCMessageType.ENTRY_FILL,
|
||||||
'exchange': 'Binance',
|
"exchange": "Binance",
|
||||||
'pair': 'ETH/BTC',
|
"pair": "ETH/BTC",
|
||||||
'leverage': 2.0,
|
"leverage": 2.0,
|
||||||
'direction': 'Short',
|
"direction": "Short",
|
||||||
'open_rate': 0.005,
|
"open_rate": 0.005,
|
||||||
'stake_amount': 0.8,
|
"stake_amount": 0.8,
|
||||||
'stake_amount_fiat': 500,
|
"stake_amount_fiat": 500,
|
||||||
'stake_currency': 'BTC',
|
"stake_currency": "BTC",
|
||||||
'fiat_currency': 'EUR'
|
"fiat_currency": "EUR",
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg=msg)
|
webhook.send_msg(msg=msg)
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert (msg_mock.call_args[0][0]["value1"] ==
|
assert msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]["webhookentryfill"][
|
||||||
default_conf["webhook"]["webhookentryfill"]["value1"].format(**msg))
|
"value1"
|
||||||
assert (msg_mock.call_args[0][0]["value2"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookentryfill"]["value2"].format(**msg))
|
assert msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]["webhookentryfill"][
|
||||||
assert (msg_mock.call_args[0][0]["value3"] ==
|
"value2"
|
||||||
default_conf["webhook"]["webhookentryfill"]["value3"].format(**msg))
|
].format(**msg)
|
||||||
assert (msg_mock.call_args[0][0]["value4"] ==
|
assert msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["webhookentryfill"][
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value4"].format(**msg))
|
"value3"
|
||||||
assert (msg_mock.call_args[0][0]["value5"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookentrycancel"]["value5"].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
|
# Test sell
|
||||||
msg_mock.reset_mock()
|
msg_mock.reset_mock()
|
||||||
|
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.EXIT,
|
"type": RPCMessageType.EXIT,
|
||||||
'exchange': 'Binance',
|
"exchange": "Binance",
|
||||||
'pair': 'ETH/BTC',
|
"pair": "ETH/BTC",
|
||||||
'gain': "profit",
|
"gain": "profit",
|
||||||
'limit': 0.005,
|
"limit": 0.005,
|
||||||
'amount': 0.8,
|
"amount": 0.8,
|
||||||
'order_type': 'limit',
|
"order_type": "limit",
|
||||||
'open_rate': 0.004,
|
"open_rate": 0.004,
|
||||||
'current_rate': 0.005,
|
"current_rate": 0.005,
|
||||||
'profit_amount': 0.001,
|
"profit_amount": 0.001,
|
||||||
'profit_ratio': 0.20,
|
"profit_ratio": 0.20,
|
||||||
'stake_currency': 'BTC',
|
"stake_currency": "BTC",
|
||||||
'sell_reason': ExitType.STOP_LOSS.value
|
"sell_reason": ExitType.STOP_LOSS.value,
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg=msg)
|
webhook.send_msg(msg=msg)
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert (msg_mock.call_args[0][0]["value1"] ==
|
assert msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]["webhookexit"][
|
||||||
default_conf["webhook"]["webhookexit"]["value1"].format(**msg))
|
"value1"
|
||||||
assert (msg_mock.call_args[0][0]["value2"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookexit"]["value2"].format(**msg))
|
assert msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]["webhookexit"][
|
||||||
assert (msg_mock.call_args[0][0]["value3"] ==
|
"value2"
|
||||||
default_conf["webhook"]["webhookexit"]["value3"].format(**msg))
|
].format(**msg)
|
||||||
|
assert msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["webhookexit"][
|
||||||
|
"value3"
|
||||||
|
].format(**msg)
|
||||||
# Test sell cancel
|
# Test sell cancel
|
||||||
msg_mock.reset_mock()
|
msg_mock.reset_mock()
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.EXIT_CANCEL,
|
"type": RPCMessageType.EXIT_CANCEL,
|
||||||
'exchange': 'Binance',
|
"exchange": "Binance",
|
||||||
'pair': 'ETH/BTC',
|
"pair": "ETH/BTC",
|
||||||
'gain': "profit",
|
"gain": "profit",
|
||||||
'limit': 0.005,
|
"limit": 0.005,
|
||||||
'amount': 0.8,
|
"amount": 0.8,
|
||||||
'order_type': 'limit',
|
"order_type": "limit",
|
||||||
'open_rate': 0.004,
|
"open_rate": 0.004,
|
||||||
'current_rate': 0.005,
|
"current_rate": 0.005,
|
||||||
'profit_amount': 0.001,
|
"profit_amount": 0.001,
|
||||||
'profit_ratio': 0.20,
|
"profit_ratio": 0.20,
|
||||||
'stake_currency': 'BTC',
|
"stake_currency": "BTC",
|
||||||
'sell_reason': ExitType.STOP_LOSS.value
|
"sell_reason": ExitType.STOP_LOSS.value,
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg=msg)
|
webhook.send_msg(msg=msg)
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert (msg_mock.call_args[0][0]["value1"] ==
|
assert msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]["webhookexitcancel"][
|
||||||
default_conf["webhook"]["webhookexitcancel"]["value1"].format(**msg))
|
"value1"
|
||||||
assert (msg_mock.call_args[0][0]["value2"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookexitcancel"]["value2"].format(**msg))
|
assert msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]["webhookexitcancel"][
|
||||||
assert (msg_mock.call_args[0][0]["value3"] ==
|
"value2"
|
||||||
default_conf["webhook"]["webhookexitcancel"]["value3"].format(**msg))
|
].format(**msg)
|
||||||
|
assert msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["webhookexitcancel"][
|
||||||
|
"value3"
|
||||||
|
].format(**msg)
|
||||||
# Test Sell fill
|
# Test Sell fill
|
||||||
msg_mock.reset_mock()
|
msg_mock.reset_mock()
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.EXIT_FILL,
|
"type": RPCMessageType.EXIT_FILL,
|
||||||
'exchange': 'Binance',
|
"exchange": "Binance",
|
||||||
'pair': 'ETH/BTC',
|
"pair": "ETH/BTC",
|
||||||
'gain': "profit",
|
"gain": "profit",
|
||||||
'close_rate': 0.005,
|
"close_rate": 0.005,
|
||||||
'amount': 0.8,
|
"amount": 0.8,
|
||||||
'order_type': 'limit',
|
"order_type": "limit",
|
||||||
'open_rate': 0.004,
|
"open_rate": 0.004,
|
||||||
'current_rate': 0.005,
|
"current_rate": 0.005,
|
||||||
'profit_amount': 0.001,
|
"profit_amount": 0.001,
|
||||||
'profit_ratio': 0.20,
|
"profit_ratio": 0.20,
|
||||||
'stake_currency': 'BTC',
|
"stake_currency": "BTC",
|
||||||
'sell_reason': ExitType.STOP_LOSS.value
|
"sell_reason": ExitType.STOP_LOSS.value,
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg=msg)
|
webhook.send_msg(msg=msg)
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert (msg_mock.call_args[0][0]["value1"] ==
|
assert msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]["webhookexitfill"][
|
||||||
default_conf["webhook"]["webhookexitfill"]["value1"].format(**msg))
|
"value1"
|
||||||
assert (msg_mock.call_args[0][0]["value2"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookexitfill"]["value2"].format(**msg))
|
assert msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]["webhookexitfill"][
|
||||||
assert (msg_mock.call_args[0][0]["value3"] ==
|
"value2"
|
||||||
default_conf["webhook"]["webhookexitfill"]["value3"].format(**msg))
|
].format(**msg)
|
||||||
|
assert msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["webhookexitfill"][
|
||||||
|
"value3"
|
||||||
|
].format(**msg)
|
||||||
|
|
||||||
for msgtype in [RPCMessageType.STATUS,
|
for msgtype in [RPCMessageType.STATUS, RPCMessageType.WARNING, RPCMessageType.STARTUP]:
|
||||||
RPCMessageType.WARNING,
|
|
||||||
RPCMessageType.STARTUP]:
|
|
||||||
# Test notification
|
# Test notification
|
||||||
msg = {
|
msg = {"type": msgtype, "status": "Unfilled sell order for BTC cancelled due to timeout"}
|
||||||
'type': msgtype,
|
|
||||||
'status': 'Unfilled sell order for BTC cancelled due to timeout'
|
|
||||||
}
|
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
|
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
|
||||||
webhook.send_msg(msg)
|
webhook.send_msg(msg)
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert (msg_mock.call_args[0][0]["value1"] ==
|
assert msg_mock.call_args[0][0]["value1"] == default_conf["webhook"]["webhookstatus"][
|
||||||
default_conf["webhook"]["webhookstatus"]["value1"].format(**msg))
|
"value1"
|
||||||
assert (msg_mock.call_args[0][0]["value2"] ==
|
].format(**msg)
|
||||||
default_conf["webhook"]["webhookstatus"]["value2"].format(**msg))
|
assert msg_mock.call_args[0][0]["value2"] == default_conf["webhook"]["webhookstatus"][
|
||||||
assert (msg_mock.call_args[0][0]["value3"] ==
|
"value2"
|
||||||
default_conf["webhook"]["webhookstatus"]["value3"].format(**msg))
|
].format(**msg)
|
||||||
|
assert msg_mock.call_args[0][0]["value3"] == default_conf["webhook"]["webhookstatus"][
|
||||||
|
"value3"
|
||||||
|
].format(**msg)
|
||||||
|
|
||||||
|
|
||||||
def test_exception_send_msg(default_conf, mocker, caplog):
|
def test_exception_send_msg(default_conf, mocker, caplog):
|
||||||
@@ -338,9 +369,8 @@ def test_exception_send_msg(default_conf, mocker, caplog):
|
|||||||
del default_conf["webhook"]["webhookentry"]
|
del default_conf["webhook"]["webhookentry"]
|
||||||
|
|
||||||
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
||||||
webhook.send_msg({'type': RPCMessageType.ENTRY})
|
webhook.send_msg({"type": RPCMessageType.ENTRY})
|
||||||
assert log_has(f"Message type '{RPCMessageType.ENTRY}' not configured for webhooks",
|
assert log_has(f"Message type '{RPCMessageType.ENTRY}' not configured for webhooks", caplog)
|
||||||
caplog)
|
|
||||||
|
|
||||||
default_conf["webhook"] = get_webhook_dict()
|
default_conf["webhook"] = get_webhook_dict()
|
||||||
default_conf["webhook"]["strategy_msg"] = {"value1": "{DEADBEEF:8f}"}
|
default_conf["webhook"]["strategy_msg"] = {"value1": "{DEADBEEF:8f}"}
|
||||||
@@ -348,112 +378,103 @@ def test_exception_send_msg(default_conf, mocker, caplog):
|
|||||||
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
|
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
|
||||||
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.STRATEGY_MSG,
|
"type": RPCMessageType.STRATEGY_MSG,
|
||||||
'msg': 'hello world',
|
"msg": "hello world",
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg)
|
webhook.send_msg(msg)
|
||||||
assert log_has("Problem calling Webhook. Please check your webhook configuration. "
|
assert log_has(
|
||||||
"Exception: 'DEADBEEF'", caplog)
|
"Problem calling Webhook. Please check your webhook configuration. "
|
||||||
|
"Exception: 'DEADBEEF'",
|
||||||
|
caplog,
|
||||||
|
)
|
||||||
|
|
||||||
# Test no failure for not implemented but known messagetypes
|
# Test no failure for not implemented but known messagetypes
|
||||||
for e in RPCMessageType:
|
for e in RPCMessageType:
|
||||||
msg = {
|
msg = {"type": e, "status": "whatever"}
|
||||||
'type': e,
|
|
||||||
'status': 'whatever'
|
|
||||||
}
|
|
||||||
webhook.send_msg(msg)
|
webhook.send_msg(msg)
|
||||||
|
|
||||||
# Test no failure for not implemented but known messagetypes
|
# Test no failure for not implemented but known messagetypes
|
||||||
for e in RPCMessageType:
|
for e in RPCMessageType:
|
||||||
msg = {
|
msg = {"type": e, "status": "whatever"}
|
||||||
'type': e,
|
|
||||||
'status': 'whatever'
|
|
||||||
}
|
|
||||||
webhook.send_msg(msg)
|
webhook.send_msg(msg)
|
||||||
|
|
||||||
|
|
||||||
def test__send_msg(default_conf, mocker, caplog):
|
def test__send_msg(default_conf, mocker, caplog):
|
||||||
default_conf["webhook"] = get_webhook_dict()
|
default_conf["webhook"] = get_webhook_dict()
|
||||||
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
||||||
msg = {'value1': 'DEADBEEF',
|
msg = {"value1": "DEADBEEF", "value2": "ALIVEBEEF", "value3": "FREQTRADE"}
|
||||||
'value2': 'ALIVEBEEF',
|
|
||||||
'value3': 'FREQTRADE'}
|
|
||||||
post = MagicMock()
|
post = MagicMock()
|
||||||
mocker.patch("freqtrade.rpc.webhook.post", post)
|
mocker.patch("freqtrade.rpc.webhook.post", post)
|
||||||
webhook._send_msg(msg)
|
webhook._send_msg(msg)
|
||||||
|
|
||||||
assert post.call_count == 1
|
assert post.call_count == 1
|
||||||
assert post.call_args[1] == {'data': msg, 'timeout': 10}
|
assert post.call_args[1] == {"data": msg, "timeout": 10}
|
||||||
assert post.call_args[0] == (default_conf['webhook']['url'], )
|
assert post.call_args[0] == (default_conf["webhook"]["url"],)
|
||||||
|
|
||||||
post = MagicMock(side_effect=RequestException)
|
post = MagicMock(side_effect=RequestException)
|
||||||
mocker.patch("freqtrade.rpc.webhook.post", post)
|
mocker.patch("freqtrade.rpc.webhook.post", post)
|
||||||
webhook._send_msg(msg)
|
webhook._send_msg(msg)
|
||||||
assert log_has('Could not call webhook url. Exception: ', caplog)
|
assert log_has("Could not call webhook url. Exception: ", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test__send_msg_with_json_format(default_conf, mocker, caplog):
|
def test__send_msg_with_json_format(default_conf, mocker, caplog):
|
||||||
default_conf["webhook"] = get_webhook_dict()
|
default_conf["webhook"] = get_webhook_dict()
|
||||||
default_conf["webhook"]["format"] = "json"
|
default_conf["webhook"]["format"] = "json"
|
||||||
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
||||||
msg = {'text': 'Hello'}
|
msg = {"text": "Hello"}
|
||||||
post = MagicMock()
|
post = MagicMock()
|
||||||
mocker.patch("freqtrade.rpc.webhook.post", post)
|
mocker.patch("freqtrade.rpc.webhook.post", post)
|
||||||
webhook._send_msg(msg)
|
webhook._send_msg(msg)
|
||||||
|
|
||||||
assert post.call_args[1] == {'json': msg, 'timeout': 10}
|
assert post.call_args[1] == {"json": msg, "timeout": 10}
|
||||||
|
|
||||||
|
|
||||||
def test__send_msg_with_raw_format(default_conf, mocker, caplog):
|
def test__send_msg_with_raw_format(default_conf, mocker, caplog):
|
||||||
default_conf["webhook"] = get_webhook_dict()
|
default_conf["webhook"] = get_webhook_dict()
|
||||||
default_conf["webhook"]["format"] = "raw"
|
default_conf["webhook"]["format"] = "raw"
|
||||||
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
||||||
msg = {'data': 'Hello'}
|
msg = {"data": "Hello"}
|
||||||
post = MagicMock()
|
post = MagicMock()
|
||||||
mocker.patch("freqtrade.rpc.webhook.post", post)
|
mocker.patch("freqtrade.rpc.webhook.post", post)
|
||||||
webhook._send_msg(msg)
|
webhook._send_msg(msg)
|
||||||
|
|
||||||
assert post.call_args[1] == {
|
assert post.call_args[1] == {
|
||||||
'data': msg['data'],
|
"data": msg["data"],
|
||||||
'headers': {'Content-Type': 'text/plain'},
|
"headers": {"Content-Type": "text/plain"},
|
||||||
'timeout': 10
|
"timeout": 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_send_msg_discord(default_conf, mocker):
|
def test_send_msg_discord(default_conf, mocker):
|
||||||
|
default_conf["discord"] = {"enabled": True, "webhook_url": "https://webhookurl..."}
|
||||||
default_conf["discord"] = {
|
|
||||||
'enabled': True,
|
|
||||||
'webhook_url': "https://webhookurl..."
|
|
||||||
}
|
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
|
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
|
||||||
discord = Discord(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
discord = Discord(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
|
||||||
|
|
||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.EXIT_FILL,
|
"type": RPCMessageType.EXIT_FILL,
|
||||||
'trade_id': 1,
|
"trade_id": 1,
|
||||||
'exchange': 'Binance',
|
"exchange": "Binance",
|
||||||
'pair': 'ETH/BTC',
|
"pair": "ETH/BTC",
|
||||||
'direction': 'Long',
|
"direction": "Long",
|
||||||
'gain': "profit",
|
"gain": "profit",
|
||||||
'close_rate': 0.005,
|
"close_rate": 0.005,
|
||||||
'amount': 0.8,
|
"amount": 0.8,
|
||||||
'order_type': 'limit',
|
"order_type": "limit",
|
||||||
'open_date': datetime.now() - timedelta(days=1),
|
"open_date": datetime.now() - timedelta(days=1),
|
||||||
'close_date': datetime.now(),
|
"close_date": datetime.now(),
|
||||||
'open_rate': 0.004,
|
"open_rate": 0.004,
|
||||||
'current_rate': 0.005,
|
"current_rate": 0.005,
|
||||||
'profit_amount': 0.001,
|
"profit_amount": 0.001,
|
||||||
'profit_ratio': 0.20,
|
"profit_ratio": 0.20,
|
||||||
'stake_currency': 'BTC',
|
"stake_currency": "BTC",
|
||||||
'enter_tag': 'enter_tagggg',
|
"enter_tag": "enter_tagggg",
|
||||||
'exit_reason': ExitType.STOP_LOSS.value,
|
"exit_reason": ExitType.STOP_LOSS.value,
|
||||||
}
|
}
|
||||||
discord.send_msg(msg=msg)
|
discord.send_msg(msg=msg)
|
||||||
|
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert 'embeds' in msg_mock.call_args_list[0][0][0]
|
assert "embeds" in msg_mock.call_args_list[0][0][0]
|
||||||
assert 'title' in msg_mock.call_args_list[0][0][0]['embeds'][0]
|
assert "title" in msg_mock.call_args_list[0][0][0]["embeds"][0]
|
||||||
assert 'color' in msg_mock.call_args_list[0][0][0]['embeds'][0]
|
assert "color" in msg_mock.call_args_list[0][0][0]["embeds"][0]
|
||||||
assert 'fields' in msg_mock.call_args_list[0][0][0]['embeds'][0]
|
assert "fields" in msg_mock.call_args_list[0][0][0]["embeds"][0]
|
||||||
|
|||||||
Reference in New Issue
Block a user