fix most tests

This commit is contained in:
xmatthias 2018-06-17 20:13:39 +02:00
parent 67d345bc08
commit 68f6423d39

View File

@ -8,28 +8,14 @@ from unittest.mock import MagicMock, PropertyMock
import ccxt import ccxt
import pytest import pytest
import freqtrade.exchange as exchange
from freqtrade import OperationalException, DependencyException, TemporaryError from freqtrade import OperationalException, DependencyException, TemporaryError
from freqtrade.exchange import (init, validate_pairs, buy, sell, get_balance, get_balances, from freqtrade.exchange import Exchange, API_RETRY_COUNT
get_ticker, get_ticker_history, cancel_order, get_name, get_fee, from freqtrade.tests.conftest import log_has, get_patched_exchange
get_id, get_pair_detail_url, get_amount_lots)
from freqtrade.tests.conftest import log_has
API_INIT = False
def maybe_init_api(conf, mocker, force=False):
global API_INIT
if force or not API_INIT:
mocker.patch('freqtrade.exchange.validate_pairs',
side_effect=lambda s: True)
init(config=conf)
API_INIT = True
def test_init(default_conf, mocker, caplog): def test_init(default_conf, mocker, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
maybe_init_api(default_conf, mocker, True) get_patched_exchange(mocker, default_conf)
assert log_has('Instance is running with dry_run enabled', caplog.record_tuples) assert log_has('Instance is running with dry_run enabled', caplog.record_tuples)
@ -39,7 +25,7 @@ def test_init_exception(default_conf):
with pytest.raises( with pytest.raises(
OperationalException, OperationalException,
match='Exchange {} is not supported'.format(default_conf['exchange']['name'])): match='Exchange {} is not supported'.format(default_conf['exchange']['name'])):
init(config=default_conf) Exchange(default_conf)
def test_validate_pairs(default_conf, mocker): def test_validate_pairs(default_conf, mocker):
@ -50,18 +36,17 @@ def test_validate_pairs(default_conf, mocker):
id_mock = PropertyMock(return_value='test_exchange') id_mock = PropertyMock(return_value='test_exchange')
type(api_mock).id = id_mock type(api_mock).id = id_mock
mocker.patch('freqtrade.exchange._API', api_mock) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) Exchange(default_conf)
validate_pairs(default_conf['exchange']['pair_whitelist'])
def test_validate_pairs_not_available(default_conf, mocker): def test_validate_pairs_not_available(default_conf, mocker):
api_mock = MagicMock() api_mock = MagicMock()
api_mock.load_markets = MagicMock(return_value={}) api_mock.load_markets = MagicMock(return_value={})
mocker.patch('freqtrade.exchange._API', api_mock) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
with pytest.raises(OperationalException, match=r'not available'): with pytest.raises(OperationalException, match=r'not available'):
validate_pairs(default_conf['exchange']['pair_whitelist']) Exchange(default_conf)
def test_validate_pairs_not_compatible(default_conf, mocker): def test_validate_pairs_not_compatible(default_conf, mocker):
@ -71,25 +56,24 @@ def test_validate_pairs_not_compatible(default_conf, mocker):
}) })
conf = deepcopy(default_conf) conf = deepcopy(default_conf)
conf['stake_currency'] = 'ETH' conf['stake_currency'] = 'ETH'
mocker.patch('freqtrade.exchange._API', api_mock) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
mocker.patch.dict('freqtrade.exchange._CONF', conf)
with pytest.raises(OperationalException, match=r'not compatible'): with pytest.raises(OperationalException, match=r'not compatible'):
validate_pairs(conf['exchange']['pair_whitelist']) Exchange(conf)
def test_validate_pairs_exception(default_conf, mocker, caplog): def test_validate_pairs_exception(default_conf, mocker, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
api_mock = MagicMock() api_mock = MagicMock()
api_mock.name = 'Binance' api_mock.name = 'Binance'
mocker.patch('freqtrade.exchange._API', api_mock) mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock())
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) exchange = Exchange(default_conf)
api_mock.load_markets = MagicMock(return_value={}) api_mock.load_markets = MagicMock(return_value={})
with pytest.raises(OperationalException, match=r'Pair ETH/BTC is not available at Binance'): with pytest.raises(OperationalException, match=r'Pair ETH/BTC is not available at Binance'):
validate_pairs(default_conf['exchange']['pair_whitelist']) exchange.validate_pairs(default_conf['exchange']['pair_whitelist'])
api_mock.load_markets = MagicMock(side_effect=ccxt.BaseError()) api_mock.load_markets = MagicMock(side_effect=ccxt.BaseError())
validate_pairs(default_conf['exchange']['pair_whitelist']) exchange.validate_pairs(default_conf['exchange']['pair_whitelist'])
assert log_has('Unable to validate pairs (assuming they are correct). Reason: ', assert log_has('Unable to validate pairs (assuming they are correct). Reason: ',
caplog.record_tuples) caplog.record_tuples)
@ -100,21 +84,20 @@ def test_validate_pairs_stake_exception(default_conf, mocker, caplog):
conf['stake_currency'] = 'ETH' conf['stake_currency'] = 'ETH'
api_mock = MagicMock() api_mock = MagicMock()
api_mock.name = 'binance' api_mock.name = 'binance'
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
mocker.patch.dict('freqtrade.exchange._CONF', conf)
with pytest.raises( with pytest.raises(
OperationalException, OperationalException,
match=r'Pair ETH/BTC not compatible with stake_currency: ETH' match=r'Pair ETH/BTC not compatible with stake_currency: ETH'
): ):
validate_pairs(default_conf['exchange']['pair_whitelist']) exchange.validate_pairs(default_conf['exchange']['pair_whitelist'])
def test_buy_dry_run(default_conf, mocker): def test_buy_dry_run(default_conf, mocker):
default_conf['dry_run'] = True default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) exchange = get_patched_exchange(mocker, default_conf)
order = buy(pair='ETH/BTC', rate=200, amount=1) order = exchange.buy(pair='ETH/BTC', rate=200, amount=1)
assert 'id' in order assert 'id' in order
assert 'dry_run_buy_' in order['id'] assert 'dry_run_buy_' in order['id']
@ -128,12 +111,10 @@ def test_buy_prod(default_conf, mocker):
'foo': 'bar' 'foo': 'bar'
} }
}) })
mocker.patch('freqtrade.exchange._API', api_mock)
default_conf['dry_run'] = False default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) exchange = get_patched_exchange(mocker, default_conf, api_mock)
order = buy(pair='ETH/BTC', rate=200, amount=1) order = exchange.buy(pair='ETH/BTC', rate=200, amount=1)
assert 'id' in order assert 'id' in order
assert 'info' in order assert 'info' in order
assert order['id'] == order_id assert order['id'] == order_id
@ -141,30 +122,30 @@ def test_buy_prod(default_conf, mocker):
# test exception handling # test exception handling
with pytest.raises(DependencyException): with pytest.raises(DependencyException):
api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.InsufficientFunds) api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.InsufficientFunds)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
buy(pair='ETH/BTC', rate=200, amount=1) exchange.buy(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(DependencyException): with pytest.raises(DependencyException):
api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.InvalidOrder) api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.InvalidOrder)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
buy(pair='ETH/BTC', rate=200, amount=1) exchange.buy(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(TemporaryError): with pytest.raises(TemporaryError):
api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.NetworkError) api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
buy(pair='ETH/BTC', rate=200, amount=1) exchange.buy(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(OperationalException): with pytest.raises(OperationalException):
api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.BaseError) api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
buy(pair='ETH/BTC', rate=200, amount=1) exchange.buy(pair='ETH/BTC', rate=200, amount=1)
def test_sell_dry_run(default_conf, mocker): def test_sell_dry_run(default_conf, mocker):
default_conf['dry_run'] = True default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) exchange = get_patched_exchange(mocker, default_conf)
order = sell(pair='ETH/BTC', rate=200, amount=1) order = exchange.sell(pair='ETH/BTC', rate=200, amount=1)
assert 'id' in order assert 'id' in order
assert 'dry_run_sell_' in order['id'] assert 'dry_run_sell_' in order['id']
@ -178,12 +159,11 @@ def test_sell_prod(default_conf, mocker):
'foo': 'bar' 'foo': 'bar'
} }
}) })
mocker.patch('freqtrade.exchange._API', api_mock)
default_conf['dry_run'] = False default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
order = sell(pair='ETH/BTC', rate=200, amount=1) exchange = get_patched_exchange(mocker, default_conf, api_mock)
order = exchange.sell(pair='ETH/BTC', rate=200, amount=1)
assert 'id' in order assert 'id' in order
assert 'info' in order assert 'info' in order
assert order['id'] == order_id assert order['id'] == order_id
@ -191,53 +171,52 @@ def test_sell_prod(default_conf, mocker):
# test exception handling # test exception handling
with pytest.raises(DependencyException): with pytest.raises(DependencyException):
api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.InsufficientFunds) api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.InsufficientFunds)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
sell(pair='ETH/BTC', rate=200, amount=1) exchange.sell(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(DependencyException): with pytest.raises(DependencyException):
api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.InvalidOrder) api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.InvalidOrder)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
sell(pair='ETH/BTC', rate=200, amount=1) exchange.sell(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(TemporaryError): with pytest.raises(TemporaryError):
api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.NetworkError) api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
sell(pair='ETH/BTC', rate=200, amount=1) exchange.sell(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(OperationalException): with pytest.raises(OperationalException):
api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.BaseError) api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
sell(pair='ETH/BTC', rate=200, amount=1) exchange.sell(pair='ETH/BTC', rate=200, amount=1)
def test_get_balance_dry_run(default_conf, mocker): def test_get_balance_dry_run(default_conf, mocker):
default_conf['dry_run'] = True default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
assert get_balance(currency='BTC') == 999.9 exchange = get_patched_exchange(mocker, default_conf)
assert exchange.get_balance(currency='BTC') == 999.9
def test_get_balance_prod(default_conf, mocker): def test_get_balance_prod(default_conf, mocker):
api_mock = MagicMock() api_mock = MagicMock()
api_mock.fetch_balance = MagicMock(return_value={'BTC': {'free': 123.4}}) api_mock.fetch_balance = MagicMock(return_value={'BTC': {'free': 123.4}})
mocker.patch('freqtrade.exchange._API', api_mock)
default_conf['dry_run'] = False default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
assert get_balance(currency='BTC') == 123.4 exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert exchange.get_balance(currency='BTC') == 123.4
with pytest.raises(OperationalException): with pytest.raises(OperationalException):
api_mock.fetch_balance = MagicMock(side_effect=ccxt.BaseError) api_mock.fetch_balance = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
get_balance(currency='BTC')
exchange.get_balance(currency='BTC')
def test_get_balances_dry_run(default_conf, mocker): def test_get_balances_dry_run(default_conf, mocker):
default_conf['dry_run'] = True default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) exchange = get_patched_exchange(mocker, default_conf)
assert exchange.get_balances() == {}
assert get_balances() == {}
def test_get_balances_prod(default_conf, mocker): def test_get_balances_prod(default_conf, mocker):
@ -253,33 +232,29 @@ def test_get_balances_prod(default_conf, mocker):
'2ST': balance_item, '2ST': balance_item,
'3ST': balance_item '3ST': balance_item
}) })
mocker.patch('freqtrade.exchange._API', api_mock)
default_conf['dry_run'] = False default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert len(exchange.get_balances()) == 3
assert len(get_balances()) == 3 assert exchange.get_balances()['1ST']['free'] == 10.0
assert get_balances()['1ST']['free'] == 10.0 assert exchange.get_balances()['1ST']['total'] == 10.0
assert get_balances()['1ST']['total'] == 10.0 assert exchange.get_balances()['1ST']['used'] == 0.0
assert get_balances()['1ST']['used'] == 0.0
with pytest.raises(TemporaryError): with pytest.raises(TemporaryError):
api_mock.fetch_balance = MagicMock(side_effect=ccxt.NetworkError) api_mock.fetch_balance = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
get_balances() exchange.get_balances()
assert api_mock.fetch_balance.call_count == exchange.API_RETRY_COUNT + 1 assert api_mock.fetch_balance.call_count == API_RETRY_COUNT + 1
with pytest.raises(OperationalException): with pytest.raises(OperationalException):
api_mock.fetch_balance = MagicMock(side_effect=ccxt.BaseError) api_mock.fetch_balance = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
get_balances() exchange.get_balances()
assert api_mock.fetch_balance.call_count == 1 assert api_mock.fetch_balance.call_count == 1
# This test is somewhat redundant with # This test is somewhat redundant with
# test_exchange_bittrex.py::test_exchange_bittrex_get_ticker # test_exchange_bittrex.py::test_exchange_bittrex_get_ticker
def test_get_ticker(default_conf, mocker): def test_get_ticker(default_conf, mocker):
maybe_init_api(default_conf, mocker)
api_mock = MagicMock() api_mock = MagicMock()
tick = { tick = {
'symbol': 'ETH/BTC', 'symbol': 'ETH/BTC',
@ -288,10 +263,9 @@ def test_get_ticker(default_conf, mocker):
'last': 0.0001, 'last': 0.0001,
} }
api_mock.fetch_ticker = MagicMock(return_value=tick) api_mock.fetch_ticker = MagicMock(return_value=tick)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
# retrieve original ticker # retrieve original ticker
ticker = get_ticker(pair='ETH/BTC') ticker = exchange.get_ticker(pair='ETH/BTC')
assert ticker['bid'] == 0.00001098 assert ticker['bid'] == 0.00001098
assert ticker['ask'] == 0.00001099 assert ticker['ask'] == 0.00001099
@ -304,11 +278,11 @@ def test_get_ticker(default_conf, mocker):
'last': 42, 'last': 42,
} }
api_mock.fetch_ticker = MagicMock(return_value=tick) api_mock.fetch_ticker = MagicMock(return_value=tick)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
# if not caching the result we should get the same ticker # if not caching the result we should get the same ticker
# if not fetching a new result we should get the cached ticker # if not fetching a new result we should get the cached ticker
ticker = get_ticker(pair='ETH/BTC') ticker = exchange.get_ticker(pair='ETH/BTC')
assert api_mock.fetch_ticker.call_count == 1 assert api_mock.fetch_ticker.call_count == 1
assert ticker['bid'] == 0.5 assert ticker['bid'] == 0.5
@ -320,22 +294,22 @@ def test_get_ticker(default_conf, mocker):
# Test caching # Test caching
api_mock.fetch_ticker = MagicMock() api_mock.fetch_ticker = MagicMock()
get_ticker(pair='ETH/BTC', refresh=False) exchange.get_ticker(pair='ETH/BTC', refresh=False)
assert api_mock.fetch_ticker.call_count == 0 assert api_mock.fetch_ticker.call_count == 0
with pytest.raises(TemporaryError): # test retrier with pytest.raises(TemporaryError): # test retrier
api_mock.fetch_ticker = MagicMock(side_effect=ccxt.NetworkError) api_mock.fetch_ticker = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
get_ticker(pair='ETH/BTC', refresh=True) exchange.get_ticker(pair='ETH/BTC', refresh=True)
with pytest.raises(OperationalException): with pytest.raises(OperationalException):
api_mock.fetch_ticker = MagicMock(side_effect=ccxt.BaseError) api_mock.fetch_ticker = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
get_ticker(pair='ETH/BTC', refresh=True) exchange.get_ticker(pair='ETH/BTC', refresh=True)
api_mock.fetch_ticker = MagicMock(return_value={}) api_mock.fetch_ticker = MagicMock(return_value={})
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
get_ticker(pair='ETH/BTC', refresh=True) exchange.get_ticker(pair='ETH/BTC', refresh=True)
def make_fetch_ohlcv_mock(data): def make_fetch_ohlcv_mock(data):
@ -361,10 +335,10 @@ def test_get_ticker_history(default_conf, mocker):
] ]
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True}) type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick)) api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
# retrieve original ticker # retrieve original ticker
ticks = get_ticker_history('ETH/BTC', default_conf['ticker_interval']) ticks = exchange.get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
assert ticks[0][0] == 1511686200000 assert ticks[0][0] == 1511686200000
assert ticks[0][1] == 1 assert ticks[0][1] == 1
assert ticks[0][2] == 2 assert ticks[0][2] == 2
@ -384,9 +358,9 @@ def test_get_ticker_history(default_conf, mocker):
] ]
] ]
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(new_tick)) api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(new_tick))
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
ticks = get_ticker_history('ETH/BTC', default_conf['ticker_interval']) ticks = exchange.get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
assert ticks[0][0] == 1511686210000 assert ticks[0][0] == 1511686210000
assert ticks[0][1] == 6 assert ticks[0][1] == 6
assert ticks[0][2] == 7 assert ticks[0][2] == 7
@ -396,15 +370,15 @@ def test_get_ticker_history(default_conf, mocker):
with pytest.raises(TemporaryError): # test retrier with pytest.raises(TemporaryError): # test retrier
api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.NetworkError) api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
# new symbol to get around cache # new symbol to get around cache
get_ticker_history('ABCD/BTC', default_conf['ticker_interval']) exchange.get_ticker_history('ABCD/BTC', default_conf['ticker_interval'])
with pytest.raises(OperationalException): with pytest.raises(OperationalException):
api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.BaseError) api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
# new symbol to get around cache # new symbol to get around cache
get_ticker_history('EFGH/BTC', default_conf['ticker_interval']) exchange.get_ticker_history('EFGH/BTC', default_conf['ticker_interval'])
def test_get_ticker_history_sort(default_conf, mocker): def test_get_ticker_history_sort(default_conf, mocker):
@ -426,10 +400,11 @@ def test_get_ticker_history_sort(default_conf, mocker):
] ]
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True}) type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick)) api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
# Test the ticker history sort # Test the ticker history sort
ticks = get_ticker_history('ETH/BTC', default_conf['ticker_interval']) ticks = exchange.get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
assert ticks[0][0] == 1527830400000 assert ticks[0][0] == 1527830400000
assert ticks[0][1] == 0.07649 assert ticks[0][1] == 0.07649
assert ticks[0][2] == 0.07651 assert ticks[0][2] == 0.07651
@ -460,10 +435,9 @@ def test_get_ticker_history_sort(default_conf, mocker):
] ]
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True}) type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick)) api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
# Test the ticker history sort # Test the ticker history sort
ticks = get_ticker_history('ETH/BTC', default_conf['ticker_interval']) ticks = exchange.get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
assert ticks[0][0] == 1527827700000 assert ticks[0][0] == 1527827700000
assert ticks[0][1] == 0.07659999 assert ticks[0][1] == 0.07659999
assert ticks[0][2] == 0.0766 assert ticks[0][2] == 0.0766
@ -481,114 +455,115 @@ def test_get_ticker_history_sort(default_conf, mocker):
def test_cancel_order_dry_run(default_conf, mocker): def test_cancel_order_dry_run(default_conf, mocker):
default_conf['dry_run'] = True default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) exchange = get_patched_exchange(mocker, default_conf)
assert exchange.cancel_order(order_id='123', pair='TKN/BTC') is None
assert cancel_order(order_id='123', pair='TKN/BTC') is None
# Ensure that if not dry_run, we should call API # Ensure that if not dry_run, we should call API
def test_cancel_order(default_conf, mocker): def test_cancel_order(default_conf, mocker):
default_conf['dry_run'] = False default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) # mocker.patch.dict('freqtrade.exchange.._CONF', default_conf)
api_mock = MagicMock() api_mock = MagicMock()
api_mock.cancel_order = MagicMock(return_value=123) api_mock.cancel_order = MagicMock(return_value=123)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert cancel_order(order_id='_', pair='TKN/BTC') == 123 assert exchange.cancel_order(order_id='_', pair='TKN/BTC') == 123
with pytest.raises(TemporaryError): with pytest.raises(TemporaryError):
api_mock.cancel_order = MagicMock(side_effect=ccxt.NetworkError) api_mock.cancel_order = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock)
cancel_order(order_id='_', pair='TKN/BTC') exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert api_mock.cancel_order.call_count == exchange.API_RETRY_COUNT + 1 exchange.cancel_order(order_id='_', pair='TKN/BTC')
assert api_mock.cancel_order.call_count == API_RETRY_COUNT + 1
with pytest.raises(DependencyException): with pytest.raises(DependencyException):
api_mock.cancel_order = MagicMock(side_effect=ccxt.InvalidOrder) api_mock.cancel_order = MagicMock(side_effect=ccxt.InvalidOrder)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
cancel_order(order_id='_', pair='TKN/BTC') exchange.cancel_order(order_id='_', pair='TKN/BTC')
assert api_mock.cancel_order.call_count == exchange.API_RETRY_COUNT + 1 assert api_mock.cancel_order.call_count == API_RETRY_COUNT + 1
with pytest.raises(OperationalException): with pytest.raises(OperationalException):
api_mock.cancel_order = MagicMock(side_effect=ccxt.BaseError) api_mock.cancel_order = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
cancel_order(order_id='_', pair='TKN/BTC') exchange.cancel_order(order_id='_', pair='TKN/BTC')
assert api_mock.cancel_order.call_count == 1 assert api_mock.cancel_order.call_count == 1
def test_get_order(default_conf, mocker): def test_get_order(default_conf, mocker):
default_conf['dry_run'] = True default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) mocker.patch.dict('freqtrade.exchange.Exchange._CONF', default_conf)
order = MagicMock() order = MagicMock()
order.myid = 123 order.myid = 123
exchange = Exchange(default_conf)
exchange._DRY_RUN_OPEN_ORDERS['X'] = order exchange._DRY_RUN_OPEN_ORDERS['X'] = order
print(exchange.get_order('X', 'TKN/BTC')) print(exchange.get_order('X', 'TKN/BTC'))
assert exchange.get_order('X', 'TKN/BTC').myid == 123 assert exchange.get_order('X', 'TKN/BTC').myid == 123
default_conf['dry_run'] = False default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf) mocker.patch.dict('freqtrade.exchange.Exchange._CONF', default_conf)
api_mock = MagicMock() api_mock = MagicMock()
api_mock.fetch_order = MagicMock(return_value=456) api_mock.fetch_order = MagicMock(return_value=456)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert exchange.get_order('X', 'TKN/BTC') == 456 assert exchange.get_order('X', 'TKN/BTC') == 456
with pytest.raises(TemporaryError): with pytest.raises(TemporaryError):
api_mock.fetch_order = MagicMock(side_effect=ccxt.NetworkError) api_mock.fetch_order = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_order(order_id='_', pair='TKN/BTC') exchange.get_order(order_id='_', pair='TKN/BTC')
assert api_mock.fetch_order.call_count == exchange.API_RETRY_COUNT + 1 assert api_mock.fetch_order.call_count == API_RETRY_COUNT + 1
with pytest.raises(DependencyException): with pytest.raises(DependencyException):
api_mock.fetch_order = MagicMock(side_effect=ccxt.InvalidOrder) api_mock.fetch_order = MagicMock(side_effect=ccxt.InvalidOrder)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_order(order_id='_', pair='TKN/BTC') exchange.get_order(order_id='_', pair='TKN/BTC')
assert api_mock.fetch_order.call_count == exchange.API_RETRY_COUNT + 1 assert api_mock.fetch_order.call_count == API_RETRY_COUNT + 1
with pytest.raises(OperationalException): with pytest.raises(OperationalException):
api_mock.fetch_order = MagicMock(side_effect=ccxt.BaseError) api_mock.fetch_order = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_order(order_id='_', pair='TKN/BTC') exchange.get_order(order_id='_', pair='TKN/BTC')
assert api_mock.fetch_order.call_count == 1 assert api_mock.fetch_order.call_count == 1
def test_get_name(default_conf, mocker): def test_get_name(default_conf, mocker):
mocker.patch('freqtrade.exchange.validate_pairs', mocker.patch('freqtrade.exchange.Exchange.validate_pairs',
side_effect=lambda s: True) side_effect=lambda s: True)
default_conf['exchange']['name'] = 'binance' default_conf['exchange']['name'] = 'binance'
init(default_conf) exchange = Exchange(default_conf)
assert get_name() == 'Binance' assert exchange.get_name() == 'Binance'
def test_get_id(default_conf, mocker): def test_get_id(default_conf, mocker):
mocker.patch('freqtrade.exchange.validate_pairs', mocker.patch('freqtrade.exchange.Exchange.validate_pairs',
side_effect=lambda s: True) side_effect=lambda s: True)
default_conf['exchange']['name'] = 'binance' default_conf['exchange']['name'] = 'binance'
init(default_conf) exchange = Exchange(default_conf)
assert exchange.get_id() == 'binance'
assert get_id() == 'binance'
def test_get_pair_detail_url(default_conf, mocker): def test_get_pair_detail_url(default_conf, mocker):
mocker.patch('freqtrade.exchange.validate_pairs', mocker.patch('freqtrade.exchange.Exchange.validate_pairs',
side_effect=lambda s: True) side_effect=lambda s: True)
default_conf['exchange']['name'] = 'binance' default_conf['exchange']['name'] = 'binance'
init(default_conf) # exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange = Exchange(default_conf)
url = get_pair_detail_url('TKN/ETH') url = exchange.get_pair_detail_url('TKN/ETH')
assert 'TKN' in url assert 'TKN' in url
assert 'ETH' in url assert 'ETH' in url
url = get_pair_detail_url('LOOONG/BTC') url = exchange.get_pair_detail_url('LOOONG/BTC')
assert 'LOOONG' in url assert 'LOOONG' in url
assert 'BTC' in url assert 'BTC' in url
default_conf['exchange']['name'] = 'bittrex' default_conf['exchange']['name'] = 'bittrex'
init(default_conf) exchange = Exchange(default_conf)
url = get_pair_detail_url('TKN/ETH') url = exchange.get_pair_detail_url('TKN/ETH')
assert 'TKN' in url assert 'TKN' in url
assert 'ETH' in url assert 'ETH' in url
url = get_pair_detail_url('LOOONG/BTC') url = exchange.get_pair_detail_url('LOOONG/BTC')
assert 'LOOONG' in url assert 'LOOONG' in url
assert 'BTC' in url assert 'BTC' in url
@ -601,12 +576,14 @@ def test_get_fee(default_conf, mocker):
'rate': 0.025, 'rate': 0.025,
'cost': 0.05 'cost': 0.05
}) })
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert get_fee() == 0.025
assert exchange.get_fee() == 0.025
def test_get_amount_lots(default_conf, mocker): def test_get_amount_lots(default_conf, mocker):
api_mock = MagicMock() api_mock = MagicMock()
api_mock.amount_to_lots = MagicMock(return_value=1.0) api_mock.amount_to_lots = MagicMock(return_value=1.0)
mocker.patch('freqtrade.exchange._API', api_mock) exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert get_amount_lots('LTC/BTC', 1.54) == 1
assert exchange.get_amount_lots('LTC/BTC', 1.54) == 1