TestBtcdeAPIDocu.test_allowed_pairs()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 15
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 14
nop 3
dl 0
loc 15
rs 9.7
c 0
b 0
f 0
1
from unittest import TestCase
2
import hashlib
3
import hmac
4
import requests_mock
5
from mock import patch
6
import json
7
import btcde
8
from decimal import Decimal
9
from mock import patch
10
from unittest.mock import patch
11
12
13
from urllib.parse import urlencode
14
15
@patch('btcde.log')
16
@requests_mock.Mocker()
17
class TestBtcdeAPIDocu(TestCase):
18
    '''Tests are as in bitcoin.de API documentation.
19
    https://www.bitcoin.de/de/api/tapi/doc'''
20
21
    def sampleData(self, file):
22
        '''Retrieve sample data from json files.'''
23
        filepath = 'tests/resources/{}.json'.format(file)
24
        data = json.load(open(filepath))
25
        return data
26
27
    def sortParams(self, url, params={}):
28
        '''To sort params for url string.'''
29
        self.encoded_string = ''
30
        if len(params) > 0:
31
            self.encoded_string = urlencode(params)
32
            self.url = url + '?' + self.encoded_string
33
        else:
34
            self.url = url
35
        return self.url, self.encoded_string
36
37
    def verifySignature(self, url, method, nonce, params):
38
        '''To verify API Signature.'''
39
        self.XAPINONCE = nonce
40
        self.url, self.encoded_string = self.sortParams(url, params)
41
        if method == 'POST':
42
            md5_encoded_query_string = hashlib.md5(self.encoded_string.encode()
43
                                                   ).hexdigest()
44
        else:
45
            md5_encoded_query_string = hashlib.md5(b'').hexdigest()
46
        hmac_data = '#'.join([method, self.url, self.XAPIKEY,
47
                             str(self.XAPINONCE), md5_encoded_query_string])
48
        hmac_signed = hmac.new(bytearray(self.XAPISECRET.encode()),
49
                               msg=hmac_data.encode(),
50
                               digestmod=hashlib.sha256).hexdigest()
51
        return hmac_signed
52
53
    def setUp(self):
54
        self.XAPIKEY = 'f00b4r'
55
        self.XAPISECRET = 'b4rf00'
56
        self.conn = btcde.Connection(self.XAPIKEY, self.XAPISECRET, ssl_verify=True)
57
        self.XAPINONCE = self.conn.nonce
58
59
    def tearDown(self):
60
        del self.XAPIKEY
61
        del self.XAPISECRET
62
        del self.conn
63
64
    def test_signature_post(self, mock_logger, m):
65
        '''Test signature on a post request.'''
66
        trading_pair = 'btceur'
67
        params = {'max_amount_currency_to_trade': 10,
68
                  'price': 1337,
69
                  'type': 'buy'}
70
        response = self.sampleData('createOrder')
71
        m.post(requests_mock.ANY, json=response, status_code=201)
72
        self.conn.createOrder(params['type'], trading_pair,
73
                              params['max_amount_currency_to_trade'], params['price'])
74
        history = m.request_history
75
        request_signature = history[0].headers.get('X-API-SIGNATURE')
76
        url = f'https://api.bitcoin.de/v4/{trading_pair}/orders'
77
        verified_signature = self.verifySignature(url, 'POST',
78
                                                  self.conn.nonce, params)
79
        self.assertEqual(request_signature, verified_signature)
80
        self.assertTrue(mock_logger.debug.called)
81
82
    def test_signature_get(self, mock_logger, m):
83
        '''Test signature on a get request.'''
84
        trading_pair = 'btceur'
85
        params = { 'type': 'buy' }
86
        response = self.sampleData('showOrderbook_buy')
87
        m.get(requests_mock.ANY, json=response, status_code=200)
88
        self.conn.showOrderbook(params.get('type'), trading_pair)
89
        history = m.request_history
90
        request_signature = history[0].headers.get('X-API-SIGNATURE')
91
        url = f'https://api.bitcoin.de/v4/{trading_pair}/orderbook'
92
        verified_signature = self.verifySignature(url, 'GET',
93
                                                  self.conn.nonce, params)
94
        self.assertEqual(request_signature, verified_signature)
95
        self.assertTrue(mock_logger.debug.called)
96
97
    def test_signature_delete(self, mock_logger, m):
98
        '''Test signature on a delete request.'''
99
        order_id = 'A1234BC'
100
        trading_pair = 'btceur'
101
        m.delete(requests_mock.ANY, json={}, status_code=200)
102
        self.conn.deleteOrder(order_id, trading_pair)
103
        history = m.request_history
104
        request_signature = history[0].headers.get('X-API-SIGNATURE')
105
        url = f'https://api.bitcoin.de/v4/{trading_pair}/orders/{order_id}'
106
        verified_signature = self.verifySignature(url, 'DELETE', self.conn.nonce, {})
107
        self.assertEqual(request_signature, verified_signature)
108
        self.assertTrue(mock_logger.debug.called)
109
110
    def test_add_to_address_pool(self, mock_logger, m):
111
        '''Test function addToAddressPool.'''
112
        currency = 'dash'
113
        params = { 'address': '1337',
114
                   'amount_usages': 3,
115
                   'comment': 'foobar' }
116
        base_url = f'https://api.bitcoin.de/v4/{currency}/address'
117
        url_args = '?' + urlencode(params)
118
        response = self.sampleData('minimal')
119
        m.post(requests_mock.ANY, json=response, status_code=201)
120
        self.conn.addToAddressPool(currency, params['address'],
121
                                   amount_usages=params['amount_usages'],
122
                                   comment=params['comment'])
123
        history = m.request_history
124
        self.assertEqual(history[0].method, "POST")
125
        self.assertEqual(history[0].url, base_url + url_args)
126
        self.assertTrue(mock_logger.debug.called)
127
128
    def test_list_address_pool(self, mock_logger, m):
129
        '''Test function listAddressPool.'''
130
        currency = 'dash'
131
        params = { "comment": "foobar",
132
                   "page": 3,
133
                   "usable": 1 }
134
        base_url = f'https://api.bitcoin.de/v4/{currency}/address'
135
        url_args = '?' + urlencode(params)
136
        response = self.sampleData('listAddressPool')
137
        m.get(requests_mock.ANY, json=response, status_code=200)
138
        self.conn.listAddressPool(currency, usable=params['usable'],
139
                                  comment=params['comment'], page=params['page'])
140
        history = m.request_history
141
        self.assertEqual(history[0].method, "GET")
142
        self.assertEqual(history[0].url, base_url + url_args)
143
        self.assertTrue(mock_logger.debug.called)
144
145
    def test_remove_from_address_pool(self, mock_logger, m):
146
        '''Test function removeFromAddressPool.'''
147
        currency = 'dash'
148
        address = '1337'
149
        base_url = f'https://api.bitcoin.de/v4/{currency}/address/{address}'
150
        response = self.sampleData('minimal')
151
        m.delete(requests_mock.ANY, json=response, status_code=200)
152
        self.conn.removeFromAddressPool(currency, address)
153
        history = m.request_history
154
        self.assertEqual(history[0].method, "DELETE")
155
        self.assertEqual(history[0].url, base_url)
156
        self.assertTrue(mock_logger.debug.called)
157
158 View Code Duplication
    def test_show_orderbook(self, mock_logger, m):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
159
        '''Test function showOrderbook.'''
160
        trading_pair = 'btceur'
161
        params = {'price': 1337,
162
                  'type': 'buy'}
163
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/orderbook'
164
        url_args = '?' + urlencode(params)
165
        response = self.sampleData('showOrderbook_buy')
166
        m.get(requests_mock.ANY, json=response, status_code=200)
167
        self.conn.showOrderbook(params['type'],
168
                                trading_pair,
169
                                price=params['price'])
170
        history = m.request_history
171
        self.assertEqual(history[0].method, "GET")
172
        self.assertEqual(history[0].url, base_url + url_args)
173
        self.assertTrue(mock_logger.debug.called)
174
175
    def test_showOrderDetails(self, mock_logger, m):
176
        '''Test function showOrderDetails.'''
177
        params = {'trading_pair': 'btceur',
178
                  'order_id': '1337'}
179
        base_url = (f'https://api.bitcoin.de/v4/{params["trading_pair"]}'
180
                   f'/orders/public/details/{params["order_id"]}')
181
        response = self.sampleData('showOrderDetails')
182
        m.get(requests_mock.ANY, json=response, status_code=200)
183
        self.conn.showOrderDetails(params['trading_pair'], params['order_id'])
184
        history = m.request_history
185
        self.assertEqual(history[0].method, "GET")
186
        self.assertEqual(history[0].url, base_url)
187
        self.assertTrue(mock_logger.debug.called)
188
189
    def test_createOrder(self, mock_logger, m):
190
        '''Test function createOrder.'''
191
        trading_pair = 'btceur'
192
        params = {'max_amount_currency_to_trade': '10',
193
                  'price': '10',
194
                  'type': 'buy'
195
                  }
196
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/orders'
197
        url_args = '?' + urlencode(params)
198
        response = self.sampleData('createOrder')
199
        m.post(requests_mock.ANY, json=response, status_code=201)
200
        self.conn.createOrder(params['type'],
201
                              trading_pair,
202
                              params['max_amount_currency_to_trade'],
203
                              params['price'])
204
        history = m.request_history
205
        self.assertEqual(history[0].method, "POST")
206
        self.assertEqual(history[0].url, base_url + url_args)
207
        self.assertTrue(mock_logger.debug.called)
208
209
    def test_deleteOrder(self, mock_logger, m):
210
        '''Test function deleteOrder.'''
211
        trading_pair = 'btceur'
212
        order_id = '1337'
213
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/orders/{order_id}'
214
        response = self.sampleData('minimal')
215
        m.delete(requests_mock.ANY, json=response, status_code=200)
216
        self.conn.deleteOrder(order_id, trading_pair)
217
        history = m.request_history
218
        self.assertEqual(history[0].method, "DELETE")
219
        self.assertEqual(history[0].url, base_url)
220
        self.assertTrue(mock_logger.debug.called)
221
222 View Code Duplication
    def test_showMyOrders(self, mock_logger, m):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
223
        '''Test function showMyOrders.'''
224
        trading_pair = 'btceur'
225
        params = { 'type': 'buy' }
226
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/orders'
227
        url_args = '?' + urlencode(params)
228
        response = self.sampleData('showMyOrders')
229
        m.get(requests_mock.ANY, json=response, status_code=200)
230
        self.conn.showMyOrders(type=params.get('type'),
231
                               trading_pair=trading_pair)
232
        history = m.request_history
233
        self.assertEqual(history[0].method, "GET")
234
        self.assertEqual(history[0].url, base_url + url_args)
235
        self.assertTrue(mock_logger.debug.called)
236
237
    def test_showMyOrderDetails(self, mock_logger, m):
238
        '''Test function showMyOrderDetails.'''
239
        trading_pair = 'btceur'
240
        order_id = '1337'
241
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/orders/{order_id}'
242
        response = self.sampleData('showMyOrderDetails')
243
        m.get(requests_mock.ANY, json=response, status_code=200)
244
        self.conn.showMyOrderDetails(trading_pair, order_id)
245
        history = m.request_history
246
        self.assertEqual(history[0].method, "GET")
247
        self.assertEqual(history[0].url, base_url)
248
        self.assertTrue(mock_logger.debug.called)
249
250 View Code Duplication
    def test_executeTrade(self, mock_logger, m):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
251
        '''Test function executeTrade.'''
252
        trading_pair = 'btceur'
253
        order_id = '1337'
254
        params = {'amount_currency_to_trade': '10',
255
                  'payment_option' : 2,
256
                  'type': 'buy',
257
                  }
258
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/trades/{order_id}'
259
        url_args = '?' + urlencode(params)
260
        response = self.sampleData('minimal')
261
        m.post(requests_mock.ANY, json=response, status_code=201)
262
        self.conn.executeTrade(trading_pair,
263
                               order_id,
264
                               params['type'],
265
                               params['amount_currency_to_trade'])
266
        history = m.request_history
267
        self.assertEqual(history[0].method, "POST")
268
        self.assertEqual(history[0].url, base_url + url_args)
269
        self.assertTrue(mock_logger.debug.called)
270
271
    def test_showMyTrades(self, mock_logger, m):
272
        '''Test function showMyTrades.'''
273
        base_url = 'https://api.bitcoin.de/v4/trades'
274
        response = self.sampleData('showMyTrades')
275
        m.get(requests_mock.ANY, json=response, status_code=200)
276
        history = m.request_history
277
        # Test with trading pair
278
        self.conn.showMyTrades()
279
        self.assertEqual(history[0].method, "GET")
280
        self.assertEqual(history[0].url, base_url)
281
        self.assertTrue(mock_logger.debug.called)
282
283 View Code Duplication
    def test_showMyTrades_with_params(self, mock_logger, m):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
284
        '''Test function showMyTrades with parameters.'''
285
        trading_pair = 'btceur'
286
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/trades'
287
        response = self.sampleData('showMyTrades')
288
        m.get(requests_mock.ANY, json=response, status_code=200)
289
        history = m.request_history
290
        # Test again without trading pair, but parameter
291
        params = {'type': 'buy'}
292
        url_args = '?' + urlencode(params)
293
        self.conn.showMyTrades(type=params['type'], trading_pair=trading_pair)
294
        self.assertEqual(history[0].method, "GET")
295
        self.assertEqual(history[0].url, base_url + url_args)
296
        self.assertTrue(mock_logger.debug.called)
297
298
    def test_showMyTradeDetails(self, mock_logger, m):
299
        '''Test function showMyTradeDetails.'''
300
        trading_pair = 'btceur'
301
        trade_id = '1337'
302
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/trades/{trade_id}'
303
        response = self.sampleData('showMyTradeDetails')
304
        m.get(requests_mock.ANY, json=response, status_code=200)
305
        self.conn.showMyTradeDetails(trading_pair, trade_id)
306
        history = m.request_history
307
        self.assertEqual(history[0].method, "GET")
308
        self.assertEqual(history[0].url, base_url)
309
        self.assertTrue(mock_logger.debug.called)
310
311 View Code Duplication
    def test_markCoinsAsTransferred(self, mock_logger, m):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
312
        '''Test function markCoinsAsTransferred.'''
313
        trading_pair = 'btceur'
314
        trade_id = '1337'
315
        params = { 'amount_currency_to_trade_after_fee': 0.1337}
316
        url_args = '?' + urlencode(params)
317
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/trades/{trade_id}/mark_coins_as_transferred'
318
        response = self.sampleData('markCoinsAsTransferred')
319
        m.post(requests_mock.ANY, json=response, status_code=200)
320
        self.conn.markCoinsAsTransferred(trading_pair, trade_id, params['amount_currency_to_trade_after_fee'])
321
        history = m.request_history
322
        self.assertEqual(history[0].method, "POST")
323
        self.assertEqual(history[0].url, base_url + url_args)
324
        self.assertTrue(mock_logger.debug.called)
325
326 View Code Duplication
    def test_markTradeAsPaid(self, mock_logger, m):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
327
        '''Test function markTradeAsPaid.'''
328
        trading_pair = 'btceur'
329
        trade_id = '1337'
330
        params = { 'volume_currency_to_pay_after_fee': 0.1337}
331
        url_args = '?' + urlencode(params)
332
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/trades/{trade_id}/mark_trade_as_paid'
333
        response = self.sampleData('markCoinsAsTransferred')
334
        m.post(requests_mock.ANY, json=response, status_code=200)
335
        self.conn.markTradeAsPaid(trading_pair, trade_id, params['volume_currency_to_pay_after_fee'])
336
        history = m.request_history
337
        self.assertEqual(history[0].method, "POST")
338
        self.assertEqual(history[0].url, base_url + url_args)
339
        self.assertTrue(mock_logger.debug.called)
340
341 View Code Duplication
    def test_markCoinsAsReceived(self, mock_logger, m):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
342
        '''Test function markCoinsAsReceived.'''
343
        trading_pair = 'btceur'
344
        trade_id = '1337'
345
        params = { 'amount_currency_to_trade_after_fee': 0.1337, 'rating': 'positive'}
346
        url_args = '?' + urlencode(params)
347
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/trades/{trade_id}/mark_coins_as_received'
348
        response = self.sampleData('markCoinsAsTransferred')
349
        m.post(requests_mock.ANY, json=response, status_code=200)
350
        self.conn.markCoinsAsReceived(trading_pair, trade_id,
351
                                      params['amount_currency_to_trade_after_fee'],
352
                                      params['rating'])
353
        history = m.request_history
354
        self.assertEqual(history[0].method, "POST")
355
        self.assertEqual(history[0].url, base_url + url_args)
356
        self.assertTrue(mock_logger.debug.called)
357
358
    def test_markTradeAsPaymentReceived(self, mock_logger, m):
359
        '''Test function markTradeAsPaymentReceived.'''
360
        trading_pair = 'btceur'
361
        trade_id = '1337'
362
        params = { 'is_paid_from_correct_bank_account': True, 'rating': 'positive',
363
                   'volume_currency_to_pay_after_fee': 0.1337 }
364
        url_args = '?' + urlencode(params)
365
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/trades/{trade_id}/mark_trade_as_payment_received'
366
        response = self.sampleData('markCoinsAsTransferred')
367
        m.post(requests_mock.ANY, json=response, status_code=200)
368
        self.conn.markTradeAsPaymentReceived(trading_pair, trade_id,
369
                                      params['volume_currency_to_pay_after_fee'],
370
                                      params['rating'],
371
                                      params['is_paid_from_correct_bank_account'])
372
        history = m.request_history
373
        self.assertEqual(history[0].method, "POST")
374
        self.assertEqual(history[0].url, base_url + url_args)
375
        self.assertTrue(mock_logger.debug.called)
376
377 View Code Duplication
    def test_addTradeRating(self, mock_logger, m):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
378
        '''Test function addTradeRating.'''
379
        trading_pair = 'btceur'
380
        trade_id = '1337'
381
        params = { 'rating': 'positive' }
382
        url_args = '?' + urlencode(params)
383
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/trades/{trade_id}/add_trade_rating'
384
        response = self.sampleData('markCoinsAsTransferred')
385
        m.post(requests_mock.ANY, json=response, status_code=200)
386
        self.conn.addTradeRating(trading_pair, trade_id, params['rating'])
387
        history = m.request_history
388
        self.assertEqual(history[0].method, "POST")
389
        self.assertEqual(history[0].url, base_url + url_args)
390
        self.assertTrue(mock_logger.debug.called)
391
392
    def test_showAccountInfo(self, mock_logger, m):
393
        '''Test function showAccountInfo.'''
394
        base_url = 'https://api.bitcoin.de/v4/account'
395
        url_args = ''
396
        response = self.sampleData('showAccountInfo')
397
        m.get(requests_mock.ANY, json=response, status_code=200)
398
        self.conn.showAccountInfo()
399
        history = m.request_history
400
        self.assertEqual(history[0].method, "GET")
401
        self.assertEqual(history[0].url, base_url + url_args)
402
        self.assertTrue(mock_logger.debug.called)
403
404
    def test_showOrderbookCompact(self, mock_logger, m):
405
        '''Test function showOrderbookCompact.'''
406
        trading_pair = 'btceur'
407
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/orderbook/compact'
408
        response = self.sampleData('showOrderbookCompact')
409
        m.get(requests_mock.ANY, json=response, status_code=200)
410
        self.conn.showOrderbookCompact(trading_pair)
411
        history = m.request_history
412
        self.assertEqual(history[0].method, "GET")
413
        self.assertEqual(history[0].url, base_url)
414
        self.assertTrue(mock_logger.debug.called)
415
416
    def test_showPublicTradeHistory(self, mock_logger, m):
417
        '''Test function showPublicTradeHistory.'''
418
        trading_pair = 'btceur'
419
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/trades/history'
420
        response = self.sampleData('showPublicTradeHistory')
421
        m.get(requests_mock.ANY, json=response, status_code=200)
422
        self.conn.showPublicTradeHistory(trading_pair)
423
        history = m.request_history
424
        self.assertEqual(history[0].method, "GET")
425
        self.assertEqual(history[0].url, base_url)
426
        self.assertTrue(mock_logger.debug.called)
427
428
    def test_showPublicTradeHistory_since(self, mock_logger, m):
429
        '''Test function showPublicTradeHistory with since_tid.'''
430
        trading_pair = 'btceur'
431
        params = {'since_tid': '123'}
432
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/trades/history'
433
        url_args = '?' + urlencode(params)
434
        response = self.sampleData('showPublicTradeHistory')
435
        m.get(requests_mock.ANY, json=response, status_code=200)
436
        self.conn.showPublicTradeHistory(trading_pair, since_tid=params.get('since_tid'))
437
        history = m.request_history
438
        self.assertEqual(history[0].method, "GET")
439
        self.assertEqual(history[0].url, base_url + url_args)
440
        self.assertTrue(mock_logger.debug.called)
441
442
    def test_showRates(self, mock_logger, m):
443
        '''Test function showRates.'''
444
        trading_pair = 'btceur'
445
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/rates'
446
        response = self.sampleData('showRates')
447
        m.get(requests_mock.ANY, json=response, status_code=200)
448
        self.conn.showRates(trading_pair)
449
        history = m.request_history
450
        self.assertEqual(history[0].method, "GET")
451
        self.assertEqual(history[0].url, base_url)
452
        self.assertTrue(mock_logger.debug.called)
453
454 View Code Duplication
    def test_showAccountLedger(self, mock_logger, m):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
455
        '''Test function showAccountLedger.'''
456
        currency = 'btc'
457
        params = {'type': 'all'}
458
        url_args = '?' + urlencode(params)
459
        base_url = f'https://api.bitcoin.de/v4/{currency}/account/ledger'
460
        response = self.sampleData('showAccountLedger')
461
        m.get(requests_mock.ANY, json=response, status_code=200)
462
        self.conn.showAccountLedger(currency, type=params['type'])
463
        history = m.request_history
464
        self.assertEqual(history[0].method, "GET")
465
        self.assertEqual(history[0].url, base_url + url_args)
466
        self.assertTrue(mock_logger.debug.called)
467
468
    def test_showPermissions(self, mock_logger, m):
469
        '''Test function showPermissions.'''
470
        base_url = f'https://api.bitcoin.de/v4/permissions'
471
        response = self.sampleData('showPermissions')
472
        m.get(requests_mock.ANY, json=response, status_code=200)
473
        self.conn.showPermissions()
474
        history = m.request_history
475
        self.assertEqual(history[0].method, "GET")
476
        self.assertEqual(history[0].url, base_url)
477
        self.assertTrue(mock_logger.debug.called)
478
479 View Code Duplication
    def test_urlEncoding(self, mock_logger, m):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
480
        '''Test URL encoding on parameters.'''
481
        currency = 'btc'
482
        params = {'datetime_start': '2018-01-01T01:00:00+01:00'}
483
        base_url = f'https://api.bitcoin.de/v4/{currency}/account/ledger'
484
        url_args = '?' + urlencode(params)
485
        response = self.sampleData('showAccountLedger')
486
        m.get(requests_mock.ANY, json=response, status_code=200)
487
        r = self.conn.showAccountLedger(currency, datetime_start="2018-01-01T01:00:00+01:00")
488
        history = m.request_history
489
        self.assertEqual(history[0].method, "GET")
490
        self.assertEqual(history[0].url, base_url + url_args)
491
        self.assertTrue(mock_logger.debug.called)
492
493
    def test_allowed_pairs(self, mock_logger, m):
494
        '''Test the allowed trading pairs.'''
495
        i = 0
496
        for pair in ['btceur', 'bcheur', 'etheur', 'btgeur', 'bsveur', 'ltceur',
497
                     'iotabtc', 'dashbtc', 'gntbtc', 'ltcbtc', 'xrpeur', 'usdteur', 'btcusdt', 'ethusdt' ]:
498
            params = {'trading_pair': pair}
499
            base_url = f'https://api.bitcoin.de/v4/{pair}/rates'
500
            response = self.sampleData('showRates')
501
            m.get(requests_mock.ANY, json=response, status_code=200)
502
            self.conn.showRates(params.get('trading_pair'))
503
            history = m.request_history
504
            self.assertEqual(history[i].method, "GET")
505
            self.assertEqual(history[i].url, base_url)
506
            self.assertTrue(mock_logger.debug.called)
507
            i += 1
508
509
    def test_allowed_currency(self, mock_logger, m):
510
        '''Test the allowed currencies.'''
511
        i = 0
512
        for curr in ['btc', 'bch', 'eth', 'btg', 'bsv', 'ltc',
513
                     'iota', 'dash', 'gnt', 'xrp', 'usdt']:
514
            base_url = f'https://api.bitcoin.de/v4/{curr}/account/ledger'
515
            url_args = '?currency={}'.format(curr)
516
            response = self.sampleData('showAccountLedger')
517
            m.get(requests_mock.ANY, json=response, status_code=200)
518
            self.conn.showAccountLedger(curr)
519
            history = m.request_history
520
            self.assertEqual(history[i].method, "GET")
521
            self.assertEqual(history[i].url, base_url)
522
            self.assertTrue(mock_logger.debug.called)
523
            i += 1
524
525
    def test_decimal_parsing(self, mock_logger, m):
526
        '''Test if the decimal parsing calculates correctly.'''
527
        params = {'type': 'buy',
528
                  'trading_pair': 'btceur',
529
                  'max_amount': 10,
530
                  'price': 1337}
531
        response = self.sampleData('showOrderbook_buy')
532
        m.get(requests_mock.ANY, json=response, status_code=200)
533
        data = self.conn.showOrderbook(params.get('type'),
534
                                       params.get('trading_pair'),
535
                                       price=params.get('price'))
536
        price = data.get('orders')[0].get('price')
537
        self.assertIsInstance(price, Decimal)
538
        self.assertEqual(price + Decimal('22.3'), Decimal('252.85'))
539
        self.assertNotEqual(float(price) + float('22.3'), float('252.85'))
540
541
542
class TestBtcdeExceptions(TestCase):
543
    '''Test for Exception Handling.'''
544
545
    def sampleData(self, file):
546
        '''Retrieve sample data from json files.'''
547
        filepath = 'tests/resources/{}.json'.format(file)
548
        data = json.load(open(filepath))
549
        return data
550
551
    def setUp(self):
552
        self.XAPIKEY = 'f00b4r'
553
        self.XAPISECRET = 'b4rf00'
554
        self.conn = btcde.Connection(self.XAPIKEY, self.XAPISECRET, ssl_verify=True)
555
        self.XAPINONCE = self.conn.nonce
556
557
    def tearDown(self):
558
        del self.XAPIKEY
559
        del self.XAPISECRET
560
        del self.conn
561
562
    @requests_mock.Mocker()
563
    def test_dont_fail_on_non_utf8(self, m):
564
        '''Test if no exception raises with a non-utf8 response.
565
        https://github.com/peshay/btcde/issues/12'''
566
        filepath = 'tests/resources/NonUTF8'
567
        with open(filepath, 'r') as f:
568
            m.post(requests_mock.ANY, content=f.read().encode('utf-16', 'replace'), status_code=403)
569
        try:
570
            self.conn.executeTrade('btceur', 'foobar', 'buy', 42)
571
            self.assertTrue(True)
572
        except UnicodeDecodeError:
573
            self.assertTrue(False)
574
575
    @requests_mock.Mocker()
576
    def test_APIException(self, m):
577
        '''Test API Exception.'''
578
        trading_pair = 'btceur'
579
        params = {'max_amount_currency_to_trade': 10,
580
                  'price': 13,
581
                  'type': 'buy' }
582
        base_url = f'https://api.bitcoin.de/v4/{trading_pair}/orders'
583
        url_args = '?' + urlencode(params)
584
        response = self.sampleData('error')
585
        m.post(requests_mock.ANY, json=response, status_code=400)
586
        self.conn.createOrder(params['type'], trading_pair,
587
                              params['max_amount_currency_to_trade'],
588
                              price=params['price'])
589
        history = m.request_history
590
        self.assertEqual(history[0].method, "POST")
591
        self.assertEqual(history[0].url, base_url + url_args)
592
593
    @patch('btcde.log')
594
    def test_RequestException(self, mock_logger):
595
        '''Test Requests Exception.'''
596
        params = {'type': 'buy',
597
                  'trading_pair': 'btceur',
598
                  'max_amount': 10,
599
                  'price': 13}
600
        self.conn.orderuri = 'https://foo.bar'
601
        self.conn.createOrder(params.get('type'),
602
                              params.get('trading_pair'), params.get('max_amount'),
603
                              price=params.get('price'))
604
        self.assertTrue(mock_logger.warning.called)
605
606
    def test_TradingPairValueException(self):
607
        '''Test wrong traiding_pair Value Exception.'''
608
        with self.assertRaises(ValueError) as context:
609
            self.conn.deleteOrder('123', 'usdeur')
610
        self.assertTrue('usdeur is not any of' in str(context.exception))
611
612
    def test_OrderTypeValueException(self):
613
        '''Test wrong type Value Exception.'''
614
        with self.assertRaises(ValueError) as context:
615
            self.conn.createOrder('fail', 'btceur', '100', '100')
616
        self.assertTrue('fail is not any of' in str(context.exception))
617
618
    def test_CurrencyValueException(self):
619
        '''Test wrong currency Value Exception.'''
620
        with self.assertRaises(ValueError) as context:
621
            self.conn.showAccountLedger('usd')
622
        self.assertTrue('usd is not any of' in str(context.exception))
623
624
    def test_BankSeatValueException(self):
625
        '''Test wrong seat_of_bank Value Exception.'''
626
        with self.assertRaises(ValueError) as context:
627
            self.conn.showOrderbook('buy', 'btceur', seat_of_bank='SZ')
628
        self.assertTrue('SZ is not any of' in str(context.exception))
629
630
    def test_TrustLevelValueException(self):
631
        '''Test wrong trust_level Value Exception.'''
632
        with self.assertRaises(ValueError) as context:
633
            self.conn.createOrder('buy', 'btceur', '100', '100',
634
                                   min_trust_level='foo')
635
        self.assertTrue('foo is not any of' in str(context.exception))
636
637
    def test_PaymentOptionValueException(self):
638
        '''Test wrong payment_option Value Exception.'''
639
        with self.assertRaises(ValueError) as context:
640
            self.conn.createOrder('buy', 'btceur', '100', '100',
641
                                   payment_option=4)
642
        self.assertTrue('4 is not any of' in str(context.exception))
643
644
    def test_OrderStateValueException(self):
645
        '''Test wrong state Value Exception.'''
646
        with self.assertRaises(ValueError) as context:
647
            self.conn.showMyOrders(state=1)
648
        self.assertTrue('1 is not any of' in str(context.exception))
649
650
    def test_TradeStateValueException(self):
651
        '''Test wrong state Value Exception.'''
652
        with self.assertRaises(ValueError) as context:
653
            self.conn.showMyTrades(state=-2)
654
        self.assertTrue('-2 is not any of' in str(context.exception))
655
656
    def test_UnknownKeyException(self):
657
        '''Test wrong Key Exception.'''
658
        with self.assertRaises(KeyError) as context:
659
            self.conn.showMyOrders(foo=4)
660
        self.assertTrue('foo is not any of' in str(context.exception))
661