From 606edeac8cfe2b934339254b06e5eae62c52cc0f Mon Sep 17 00:00:00 2001 From: Tine Date: Fri, 1 Dec 2017 00:23:23 +0000 Subject: [PATCH 1/4] Test: add buy_limit_query test --- bittrex/test/bittrex_tests.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/bittrex/test/bittrex_tests.py b/bittrex/test/bittrex_tests.py index 48dd359..697461d 100644 --- a/bittrex/test/bittrex_tests.py +++ b/bittrex/test/bittrex_tests.py @@ -3,6 +3,11 @@ import os from bittrex.bittrex import Bittrex, API_V2_0, API_V1_1, BUY_ORDERBOOK, TICKINTERVAL_ONEMIN +try: + from unittest import mock +except ImportError: + import mock + IS_CI_ENV = True if 'IN_CI' in os.environ else False @@ -118,6 +123,8 @@ def test_get_markets(self): def test_get_currencies(self): actual = self.bittrex.get_currencies() test_basic_response(self, actual, "get_currencies") + self.assertTrue(isinstance(actual['result'], list), "result is not a list") + self.assertTrue('BTC' in str(actual['result']), 'BTC not in result list') def test_get_ticker(self): self.assertRaisesRegexp(Exception, 'method call not available', self.bittrex.get_ticker, @@ -165,6 +172,10 @@ def test_get_latest_candle(self): self.assertIsInstance(actual['result'], list) +def mocked_buy_limit_query(protection=None, path_dict=None, options=None): + return {"success": "true", "message": "", "result": {"uuid": "e606d53c-8d70-11e3-94b5-425861b86ab6"}} + + @unittest.skipIf(IS_CI_ENV, 'no account secrets uploaded in CI envieonment, TODO') class TestBittrexV11AccountAPI(unittest.TestCase): """ @@ -271,6 +282,11 @@ def test_get_pending_deposits(self): def test_generate_deposit_address(self): self.assertRaisesRegexp(Exception, 'method call not available', self.bittrex.generate_deposit_address, currency='BTC') + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_limit_query) + def test_buy_limit(self, mock_buy): + actual = self.bittrex.buy_limit(market='BTC-LTC', quantity=0.00015, rate=0.00865) + test_basic_response(self, actual, "test_buy_limit") + @unittest.skipIf(IS_CI_ENV, 'no account secrets uploaded in CI envieonment, TODO') class TestBittrexV20AccountAPI(unittest.TestCase): From 473b3c3df1e854ed792da7b2ee40db2ab6c10056 Mon Sep 17 00:00:00 2001 From: Tine Date: Fri, 1 Dec 2017 15:10:50 +0000 Subject: [PATCH 2/4] Test: add mocked test sceleton for buy, sell and withdraw functions --- bittrex/test/bittrex_tests.py | 84 ++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/bittrex/test/bittrex_tests.py b/bittrex/test/bittrex_tests.py index 697461d..2481708 100644 --- a/bittrex/test/bittrex_tests.py +++ b/bittrex/test/bittrex_tests.py @@ -172,10 +172,47 @@ def test_get_latest_candle(self): self.assertIsInstance(actual['result'], list) -def mocked_buy_limit_query(protection=None, path_dict=None, options=None): +def mocked_buy_sell_withdraw_query(protection=None, path_dict=None, options=None): return {"success": "true", "message": "", "result": {"uuid": "e606d53c-8d70-11e3-94b5-425861b86ab6"}} +def mocked_cancel_query(protection=None, path_dict=None, options=None): + return {"success": "true", "message": "", "result": "null"} + + +def mocked_get_order(protection=None, path_dict=None, options=None): + return json.loads( + '{\ + "success" : "true", \ + "message" : "", \ + "result" : { \ + "AccountId" : null, \ + "OrderUuid" : "0cb4c4e4-bdc7-4e13-8c13-430e587d2cc1", \ + "Exchange" : "BTC-SHLD", \ + "Type" : "LIMIT_BUY", \ + "Quantity" : 1000.00000000, \ + "QuantityRemaining" : 1000.00000000, \ + "Limit" : 0.00000001, \ + "Reserved" : 0.00001000, \ + "ReserveRemaining" : 0.00001000, \ + "CommissionReserved" : 0.00000002, \ + "CommissionReserveRemaining" : 0.00000002,\ + "CommissionPaid" : 0.00000000, \ + "Price" : 0.00000000, \ + "PricePerUnit" : null, \ + "Opened" : "2014-07-13T07:45:46.27", \ + "Closed" : null, \ + "IsOpen" : true, \ + "Sentinel" : "6c454604-22e2-4fb4-892e-179eede20972", \ + "CancelInitiated" : false, \ + "ImmediateOrCancel" : false, \ + "IsConditional" : false, \ + "Condition" : "NONE", \ + "ConditionTarget" : null \ + } \ + }' + ) + @unittest.skipIf(IS_CI_ENV, 'no account secrets uploaded in CI envieonment, TODO') class TestBittrexV11AccountAPI(unittest.TestCase): """ @@ -282,11 +319,54 @@ def test_get_pending_deposits(self): def test_generate_deposit_address(self): self.assertRaisesRegexp(Exception, 'method call not available', self.bittrex.generate_deposit_address, currency='BTC') - @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_limit_query) + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_sell_withdraw_query) def test_buy_limit(self, mock_buy): actual = self.bittrex.buy_limit(market='BTC-LTC', quantity=0.00015, rate=0.00865) test_basic_response(self, actual, "test_buy_limit") + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_sell_withdraw_query) + def test_sell_limit(self, mock_sell): + actual = self.bittrex.sell_limit(market='BTC-LTC', quantity=0.00015, rate=0.00865) + test_basic_response(self, actual, "test_sell_limit") + + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_cancel_query) + def test_cancel(self, mock_cancel): + actual = self.bittrex.cancel(uuid='e606d53c-8d70-11e3-94b5-425861b86ab6') + test_basic_response(self, actual, "test_cancel") + + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_sell_withdraw_query) + def test_withdrawl(self, mock_withdraw): + actual = self.bittrex.withdraw(currency='BTC', quantity=0.0001, address='3QtaHWctjScd17uewd5LDpjKfmoAeyo9Lj') + test_basic_response(self, actual, "test_withdrawl") + + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_get_order) + def test_get_order(self, mock_order): + actual = self.bittrex.get_order(uuid='e606d53c-8d70-11e3-94b5-425861b86ab6') + test_basic_response(self, actual, "test_get_order") + self.assertIsInstance(actual['result'], dict, "result is not a dict") + + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_sell_withdraw_query) + def test_trade_sell(self, mock_trade_sell): + actual = self.bittrex.trade_sell(market='BTC-LTC', + order_type='MARKET', + quantity=0.0001, + rate=0.00865, + time_in_effect='IMMEDIATE_OR_CANCEL', + condition_type='LESS_THAN', + target=0.00876) + test_basic_response(self, actual, "test_trade_sell") + + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_sell_withdraw_query) + def test_trade_buy(self, mock_trade_buy): + actual = self.bittrex.trade_buy(market='BTC-LTC', + order_type='MARKET', + quantity=0.00015, + rate=0.00899, + time_in_effect='IMMEDIATE_OR_CANCEL', + condition_type='MORE_THAN', + target=0.00899) + test_basic_response(self, actual, "test_trade_buy") + @unittest.skipIf(IS_CI_ENV, 'no account secrets uploaded in CI envieonment, TODO') class TestBittrexV20AccountAPI(unittest.TestCase): From 661377f794f3c207cf1bd3d016adea3df525c400 Mon Sep 17 00:00:00 2001 From: Tine Date: Fri, 1 Dec 2017 15:17:38 +0000 Subject: [PATCH 3/4] Test: change test split between API v1.1 and v2.0 --- bittrex/test/bittrex_tests.py | 129 +++++++++++++++++----------------- 1 file changed, 65 insertions(+), 64 deletions(-) diff --git a/bittrex/test/bittrex_tests.py b/bittrex/test/bittrex_tests.py index 2481708..9ac37fc 100644 --- a/bittrex/test/bittrex_tests.py +++ b/bittrex/test/bittrex_tests.py @@ -23,6 +23,48 @@ def test_auth_basic_failures(unit_test, result, test_type): unit_test.assertIsNone(result['result'], "{0:s} failed response result not None".format(test_type)) +def mocked_buy_sell_withdraw_query(protection=None, path_dict=None, options=None): + return {"success": "true", "message": "", "result": {"uuid": "e606d53c-8d70-11e3-94b5-425861b86ab6"}} + + +def mocked_cancel_query(protection=None, path_dict=None, options=None): + return {"success": "true", "message": "", "result": "null"} + + +def mocked_get_order_query(protection=None, path_dict=None, options=None): + return json.loads( + '{\ + "success" : "true", \ + "message" : "", \ + "result" : { \ + "AccountId" : null, \ + "OrderUuid" : "0cb4c4e4-bdc7-4e13-8c13-430e587d2cc1", \ + "Exchange" : "BTC-SHLD", \ + "Type" : "LIMIT_BUY", \ + "Quantity" : 1000.00000000, \ + "QuantityRemaining" : 1000.00000000, \ + "Limit" : 0.00000001, \ + "Reserved" : 0.00001000, \ + "ReserveRemaining" : 0.00001000, \ + "CommissionReserved" : 0.00000002, \ + "CommissionReserveRemaining" : 0.00000002,\ + "CommissionPaid" : 0.00000000, \ + "Price" : 0.00000000, \ + "PricePerUnit" : null, \ + "Opened" : "2014-07-13T07:45:46.27", \ + "Closed" : null, \ + "IsOpen" : true, \ + "Sentinel" : "6c454604-22e2-4fb4-892e-179eede20972", \ + "CancelInitiated" : false, \ + "ImmediateOrCancel" : false, \ + "IsConditional" : false, \ + "Condition" : "NONE", \ + "ConditionTarget" : null \ + } \ + }' + ) + + class TestBittrexV11PublicAPI(unittest.TestCase): """ Integration tests for the Bittrex public API. @@ -172,47 +214,6 @@ def test_get_latest_candle(self): self.assertIsInstance(actual['result'], list) -def mocked_buy_sell_withdraw_query(protection=None, path_dict=None, options=None): - return {"success": "true", "message": "", "result": {"uuid": "e606d53c-8d70-11e3-94b5-425861b86ab6"}} - - -def mocked_cancel_query(protection=None, path_dict=None, options=None): - return {"success": "true", "message": "", "result": "null"} - - -def mocked_get_order(protection=None, path_dict=None, options=None): - return json.loads( - '{\ - "success" : "true", \ - "message" : "", \ - "result" : { \ - "AccountId" : null, \ - "OrderUuid" : "0cb4c4e4-bdc7-4e13-8c13-430e587d2cc1", \ - "Exchange" : "BTC-SHLD", \ - "Type" : "LIMIT_BUY", \ - "Quantity" : 1000.00000000, \ - "QuantityRemaining" : 1000.00000000, \ - "Limit" : 0.00000001, \ - "Reserved" : 0.00001000, \ - "ReserveRemaining" : 0.00001000, \ - "CommissionReserved" : 0.00000002, \ - "CommissionReserveRemaining" : 0.00000002,\ - "CommissionPaid" : 0.00000000, \ - "Price" : 0.00000000, \ - "PricePerUnit" : null, \ - "Opened" : "2014-07-13T07:45:46.27", \ - "Closed" : null, \ - "IsOpen" : true, \ - "Sentinel" : "6c454604-22e2-4fb4-892e-179eede20972", \ - "CancelInitiated" : false, \ - "ImmediateOrCancel" : false, \ - "IsConditional" : false, \ - "Condition" : "NONE", \ - "ConditionTarget" : null \ - } \ - }' - ) - @unittest.skipIf(IS_CI_ENV, 'no account secrets uploaded in CI envieonment, TODO') class TestBittrexV11AccountAPI(unittest.TestCase): """ @@ -339,34 +340,12 @@ def test_withdrawl(self, mock_withdraw): actual = self.bittrex.withdraw(currency='BTC', quantity=0.0001, address='3QtaHWctjScd17uewd5LDpjKfmoAeyo9Lj') test_basic_response(self, actual, "test_withdrawl") - @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_get_order) + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_get_order_query) def test_get_order(self, mock_order): actual = self.bittrex.get_order(uuid='e606d53c-8d70-11e3-94b5-425861b86ab6') test_basic_response(self, actual, "test_get_order") self.assertIsInstance(actual['result'], dict, "result is not a dict") - @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_sell_withdraw_query) - def test_trade_sell(self, mock_trade_sell): - actual = self.bittrex.trade_sell(market='BTC-LTC', - order_type='MARKET', - quantity=0.0001, - rate=0.00865, - time_in_effect='IMMEDIATE_OR_CANCEL', - condition_type='LESS_THAN', - target=0.00876) - test_basic_response(self, actual, "test_trade_sell") - - @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_sell_withdraw_query) - def test_trade_buy(self, mock_trade_buy): - actual = self.bittrex.trade_buy(market='BTC-LTC', - order_type='MARKET', - quantity=0.00015, - rate=0.00899, - time_in_effect='IMMEDIATE_OR_CANCEL', - condition_type='MORE_THAN', - target=0.00899) - test_basic_response(self, actual, "test_trade_buy") - @unittest.skipIf(IS_CI_ENV, 'no account secrets uploaded in CI envieonment, TODO') class TestBittrexV20AccountAPI(unittest.TestCase): @@ -489,6 +468,28 @@ def test_generate_deposit_address(self): test_basic_response(self, actual, "generate_deposit_address") self.assertIsInstance(actual['result'], list, "result is not a list") + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_sell_withdraw_query) + def test_trade_sell(self, mock_trade_sell): + actual = self.bittrex.trade_sell(market='BTC-LTC', + order_type='MARKET', + quantity=0.0001, + rate=0.00865, + time_in_effect='IMMEDIATE_OR_CANCEL', + condition_type='LESS_THAN', + target=0.00876) + test_basic_response(self, actual, "test_trade_sell") + + @mock.patch('bittrex.Bittrex._api_query', side_effect=mocked_buy_sell_withdraw_query) + def test_trade_buy(self, mock_trade_buy): + actual = self.bittrex.trade_buy(market='BTC-LTC', + order_type='MARKET', + quantity=0.00015, + rate=0.00899, + time_in_effect='IMMEDIATE_OR_CANCEL', + condition_type='MORE_THAN', + target=0.00899) + test_basic_response(self, actual, "test_trade_buy") + if __name__ == '__main__': unittest.main() From aef4200d7349d702ebc548f211d3a73563d94488 Mon Sep 17 00:00:00 2001 From: Tine Date: Sun, 10 Dec 2017 01:28:12 +0000 Subject: [PATCH 4/4] Test: move mocked response Json to separate file --- bittrex/test/bittrex_tests.py | 45 +++++++++-------------------- bittrex/test/getorder-response.json | 29 +++++++++++++++++++ 2 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 bittrex/test/getorder-response.json diff --git a/bittrex/test/bittrex_tests.py b/bittrex/test/bittrex_tests.py index 9ac37fc..3be5def 100644 --- a/bittrex/test/bittrex_tests.py +++ b/bittrex/test/bittrex_tests.py @@ -32,37 +32,20 @@ def mocked_cancel_query(protection=None, path_dict=None, options=None): def mocked_get_order_query(protection=None, path_dict=None, options=None): - return json.loads( - '{\ - "success" : "true", \ - "message" : "", \ - "result" : { \ - "AccountId" : null, \ - "OrderUuid" : "0cb4c4e4-bdc7-4e13-8c13-430e587d2cc1", \ - "Exchange" : "BTC-SHLD", \ - "Type" : "LIMIT_BUY", \ - "Quantity" : 1000.00000000, \ - "QuantityRemaining" : 1000.00000000, \ - "Limit" : 0.00000001, \ - "Reserved" : 0.00001000, \ - "ReserveRemaining" : 0.00001000, \ - "CommissionReserved" : 0.00000002, \ - "CommissionReserveRemaining" : 0.00000002,\ - "CommissionPaid" : 0.00000000, \ - "Price" : 0.00000000, \ - "PricePerUnit" : null, \ - "Opened" : "2014-07-13T07:45:46.27", \ - "Closed" : null, \ - "IsOpen" : true, \ - "Sentinel" : "6c454604-22e2-4fb4-892e-179eede20972", \ - "CancelInitiated" : false, \ - "ImmediateOrCancel" : false, \ - "IsConditional" : false, \ - "Condition" : "NONE", \ - "ConditionTarget" : null \ - } \ - }' - ) + """ + Mock Bittrex API response for 'get order' query + + Endpoint: + 1.1 /account/getorder + 2.0 /key/orders/getorder + + Docs & response example: + https://bittrex.com/Home/Api + """ + with open(os.path.abspath("bittrex/test/getorder-response.json")) as order_response: + json_response = json.load(order_response) + order_response.close() + return json_response class TestBittrexV11PublicAPI(unittest.TestCase): diff --git a/bittrex/test/getorder-response.json b/bittrex/test/getorder-response.json new file mode 100644 index 0000000..00f1d00 --- /dev/null +++ b/bittrex/test/getorder-response.json @@ -0,0 +1,29 @@ +{ + "success" : "true", + "message" : "", + "result" : { + "AccountId" : null, + "OrderUuid" : "0cb4c4e4-bdc7-4e13-8c13-430e587d2cc1", + "Exchange" : "BTC-SHLD", + "Type" : "LIMIT_BUY", + "Quantity" : 1000.00000000, + "QuantityRemaining" : 1000.00000000, + "Limit" : 0.00000001, + "Reserved" : 0.00001000, + "ReserveRemaining" : 0.00001000, + "CommissionReserved" : 0.00000002, + "CommissionReserveRemaining" : 0.00000002, + "CommissionPaid" : 0.00000000, + "Price" : 0.00000000, + "PricePerUnit" : null, + "Opened" : "2014-07-13T07:45:46.27", + "Closed" : null, + "IsOpen" : true, + "Sentinel" : "6c454604-22e2-4fb4-892e-179eede20972", + "CancelInitiated" : false, + "ImmediateOrCancel" : false, + "IsConditional" : false, + "Condition" : "NONE", + "ConditionTarget" : null + } +} \ No newline at end of file