def mock_requests_get(url, *_args, **_kwargs): if not use_alethio: response = '{"message": "fail so that test switches to etherscan"}' return MockResponse(400, response) if 'tokenBalances' in url: addr = url[33:75] assert addr in eth_map, f'Queried alethio for {addr} which is not in the eth_map' response = '{"meta":{"page":{"hasNext": false}},"data":[' for symbol, balance in eth_map[addr].items(): if symbol == 'ETH': continue token = symbol if FVal(balance) == ZERO: continue if 'TokenBalance' in response: # if it's not the first response response += ',' response += f"""{{ "type":"TokenBalance","id":"foo", "attributes":{{"balance":"{balance}"}}, "relationships":{{ "account":{{ "data":{{"type":"Account","id":"foo"}}, "links":{{"related":"https://api.aleth.io/v1/token-balances/0x9531c059098e3d194ff87febb587ab07b30b13066b175474e89094c44da98b954eedeac495271d0f/account"}} }}, "token":{{"data":{{"type":"Token","id":"{token.ethereum_address}"}}}} }} }}""" response += ']}' else: raise AssertionError(f'Unimplemented alethio mock for url: {url}') return MockResponse(200, response)
def mock_binance_asset_return(url, timeout, *args): # pylint: disable=unused-argument if 'futures' in url: response = '{"crossCollaterals":[]}' elif 'lending' in url: response = '{"positionAmountVos":[]}' elif 'https://fapi' in url: response = '[]' elif 'https://dapi' in url: response = '[]' elif 'bswap/liquidity' in url: response = '[]' else: response = BINANCE_BALANCES_RESPONSE return MockResponse(200, response)
def mock_unknown_asset_return(url): # pylint: disable=unused-argument response = MockResponse( 200, """ { "success": true, "message": "''", "result": [ { "Currency": "BTC", "Balance": "5.0", "Available": "5.0", "Pending": 0, "CryptoAddress": "DLxcEt3AatMyr2NTatzjsfHNoB9NT62HiF", "Requested": false, "Uuid": null }, { "Currency": "ETH", "Balance": "10.0", "Available": "10.0", "Pending": 0, "CryptoAddress": "0xb55a183bf5db01665f9fc5dfba71fc6f8b5e42e6", "Requested": false, "Uuid": null }, { "Currency": "IDONTEXIST", "Balance": "15.0", "Available": "15.0", "Pending": 0, "CryptoAddress": "0xb55a183bf5db01665f9fc5dfba71fc6f8b5e42e6", "Requested": false, "Uuid": null }, { "Currency": "PTON", "Balance": "15.0", "Available": "15.0", "Pending": 0, "CryptoAddress": "0xb55a183bf5db01665f9fc5dfba71fc6f8b5e42e6", "Requested": false, "Uuid": null } ] } """, ) return response
def mock_binance_api_queries(url, timeout): # pylint: disable=unused-argument if remote_errors: payload = invalid_payload elif 'myTrades' in url: # Can't mock unknown assets in binance trade query since # only all known pairs are queried payload = '[]' if 'symbol=ETHBTC' in url: payload = """[{ "symbol": "ETHBTC", "id": 1, "orderId": 1, "price": "0.0063213", "qty": "5.0", "commission": "0.005", "commissionAsset": "ETH", "time": 1512561941000, "isBuyer": true, "isMaker": false, "isBestMatch": true }]""" elif 'symbol=RDNETH' in url: payload = """[{ "symbol": "RDNETH", "id": 2, "orderId": 2, "price": "0.0063213", "qty": "5.0", "commission": "0.005", "commissionAsset": "RDN", "time": 1512561942000, "isBuyer": false, "isMaker": false, "isBestMatch": true }]""" elif 'capital/deposit' in url: payload = '[]' elif 'capital/withdraw' in url: payload = '[]' elif 'fiat/orders' in url: payload = '[]' elif 'fiat/payments' in url: payload = '[]' else: raise RuntimeError( f'Binance test mock got unexpected/unmocked url {url}') return MockResponse(200, payload)
def mock_succesfull_upload_data_to_server( url, # pylint: disable=unused-argument data, timeout, # pylint: disable=unused-argument ): # Can't compare data blobs as they are encrypted and as such can be # different each time assert 'data_blob' in data assert data['original_hash'] == our_hash assert data['last_modify_ts'] == last_write_ts assert 'index' in data assert len(data['data_blob']) == data['length'] assert 'nonce' in data assert data['compression'] == 'zlib' return MockResponse(200, '{"success": true}')
def mock_requests_get(url, *args, **kwargs): # pylint: disable=unused-argument if 'github' not in url: return original_requests_get(url, *args, **kwargs) if 'updates/info.json' in url: response = f'{{"latest": {latest}, "updates": {json.dumps(updates)}}}' elif 'updates.sql' in url: match = re.search(r'.*/(\d+)/updates.sql', url) assert match, f'Couldnt extract version from {url}' version = match.group(1) action = sql_actions.get(version) assert action is not None, f'Could not find SQL action for version {version}' response = action else: raise AssertionError(f'Unrecognized argument url for assets update mock in tests: {url}') # noqa: E501 return MockResponse(200, response)
def mock_get_deposit_withdrawal(url, **kwargs): # pylint: disable=unused-argument if 'capital/deposit' in url: response_str = next(get_deposit_result) elif 'capital/withdraw' in url: response_str = next(get_withdraw_result) elif 'fiat/orders' in url: if 'transactionType=0' in url: response_str = next(get_fiat_deposit_result()) elif 'transactionType=1' in url: response_str = next(get_fiat_withdraw_result()) else: raise AssertionError('Unexpected binance request in test') else: raise AssertionError('Unexpected binance request in test') return MockResponse(200, response_str)
def mock_binance_api_queries(url): if remote_errors: payload = invalid_payload elif 'myTrades' in url: # Can't mock unknown assets in binance trade query since # only all known pairs are queried payload = '[]' if 'symbol=ETHBTC' in url: payload = """[{ "symbol": "ETHBTC", "id": 1, "orderId": 1, "price": "0.0063213", "qty": "5.0", "commission": "0.005", "commissionAsset": "ETH", "time": 1512561941000, "isBuyer": true, "isMaker": false, "isBestMatch": true }]""" elif 'symbol=RDNETH' in url: payload = """[{ "symbol": "RDNETH", "id": 2, "orderId": 2, "price": "0.0063213", "qty": "5.0", "commission": "0.005", "commissionAsset": "RDN", "time": 1512561942000, "isBuyer": false, "isMaker": false, "isBestMatch": true }]""" elif 'depositHistory.html' in url: payload = '{"success": true, "depositList": []}' elif 'withdrawHistory.html' in url: payload = '{"success": true, "withdrawList": []}' else: raise RuntimeError( f'Binance test mock got unexpected/unmocked url {url}') return MockResponse(200, payload)
def mock_binance_balance_response(url, **kwargs): # pylint: disable=unused-argument if 'futures' in url: return MockResponse(200, BINANCE_FUTURES_WALLET_RESPONSE) if 'lending' in url: return MockResponse(200, BINANCE_LENDING_WALLET_RESPONSE) if 'https://fapi' in url: return MockResponse(200, BINANCE_USDT_FUTURES_BALANCES_RESPONSE) if 'https://dapi' in url: return MockResponse(200, BINANCE_COIN_FUTURES_BALANCES_RESPONSE) if 'bswap/liquidity' in url: return MockResponse(200, BINANCE_POOL_BALANCES_RESPONSE) # else return MockResponse(200, BINANCE_BALANCES_RESPONSE)
def mock_binance_balance_response(url): if 'futures' in url: return MockResponse(200, BINANCE_FUTURES_WALLET_RESPONSE) if 'lending' in url: return MockResponse(200, BINANCE_LENDING_WALLET_RESPONSE) if 'https://fapi' in url: return MockResponse(200, BINANCE_USDT_FUTURES_BALANCES_RESPONSE) if 'https://dapi' in url: return MockResponse(200, BINANCE_COIN_FUTURES_BALANCES_RESPONSE) if 'bswap/liquidity' in url: return MockResponse(200, BINANCE_POOL_BALANCES_RESPONSE) # else return MockResponse(200, BINANCE_BALANCES_RESPONSE)
def mock_requests_get(url, *args, **kwargs): if 'etherscan.io/api?module=account&action=balance&address' in url: addr = url[67:109] value = eth_map[addr].get('ETH', '0') response = f'{{"status":"1","message":"OK","result":{value}}}' elif 'etherscan.io/api?module=account&action=balancemulti' in url: queried_accounts = [] length = 72 # process url and get the accounts while True: if len(url) < length: break potential_address = url[length:length + 42] if 'apikey=' in potential_address: break queried_accounts.append(potential_address) length += 43 accounts = [] for addr in queried_accounts: value = eth_map[addr].get('ETH', '0') accounts.append({ 'account': addr, 'balance': eth_map[addr]['ETH'] }) response = f'{{"status":"1","message":"OK","result":{json.dumps(accounts)}}}' elif 'api.etherscan.io/api?module=account&action=tokenbalance' in url: token_address = url[80:122] msg = 'token address missing from test mapping' assert token_address in CONTRACT_ADDRESS_TO_TOKEN, msg response = '{"status":"1","message":"OK","result":"0"}' token = CONTRACT_ADDRESS_TO_TOKEN[token_address] account = url[131:173] value = eth_map[account].get(token.identifier, 0) response = f'{{"status":"1","message":"OK","result":"{value}"}}' else: return original_requests_get(url, *args, **kwargs) return MockResponse(200, response)
def mock_requests_get(url, *args, **kwargs): if 'blockchain.info' in url: addresses = url.split('multiaddr?active=')[1].split('|') response = '{"addresses":[' for idx, address in enumerate(addresses): balance = btc_map.get(address, '0') response += f'{{"address":"{address}", "final_balance":{balance}}}' if idx < len(addresses) - 1: response += ',' response += ']}' elif 'blockstream.info' in url: split_result = url.rsplit('/', 1) if len(split_result) != 2: raise AssertionError(f'Could not find bitcoin address at url {url}') address = split_result[1] balance = btc_map.get(address, '0') response = f"""{{"address":"{address}","chain_stats":{{"funded_txo_count":1,"funded_txo_sum":{balance},"spent_txo_count":0,"spent_txo_sum":0,"tx_count":1}},"mempool_stats":{{"funded_txo_count":0,"funded_txo_sum":0,"spent_txo_count":0,"spent_txo_sum":0,"tx_count":0}}}}""" # noqa: E501 else: return original_requests_get(url, *args, **kwargs) return MockResponse(200, response)
def mock_coinbasepro_request( request_method: Literal['get', 'post'], # pylint: disable=unused-argument url: str, data: str = '', # pylint: disable=unused-argument allow_redirects: bool = True, # pylint: disable=unused-argument ) -> MockResponse: if 'products' in url: # just return one product so not too many requests happen during tests text = PRODUCTS_RESPONSE elif 'accounts' in url: if emulate_errors == ErrorEmulation.UNKNOWN_ASSET: text = UNKNOWN_ASSET_ACCOUNTS_RESPONSE elif emulate_errors == ErrorEmulation.INVALID_RESPONSE: text = INVALID_ACCOUNTS_RESPONSE elif emulate_errors == ErrorEmulation.KEY_ERROR: text = KEYERROR_ACCOUNTS_RESPONSE else: text = ACCOUNTS_RESPONSE else: raise AssertionError(f'Unknown url: {url} encountered during CoinbasePro mocking') return MockResponse(200, text)
def mock_normal_coinbase_query(url, **kwargs): # pylint: disable=unused-argument if 'buys' in url: return MockResponse(200, BUYS_RESPONSE) if 'sells' in url: return MockResponse(200, SELLS_RESPONSE) if 'deposits' in url: return MockResponse(200, DEPOSITS_RESPONSE) if 'withdrawals' in url: return MockResponse(200, WITHDRAWALS_RESPONSE) if 'transactions' in url: return MockResponse(200, TRANSACTIONS_RESPONSE) if 'accounts' in url: # keep it simple just return a single ID and ignore the rest of the fields return MockResponse(200, '{"data": [{"id": "5fs23"}]}') # else raise AssertionError(f'Unexpected url {url} for test')
def mock_coinbase_query(url): # pylint: disable=unused-argument if 'buys' in url: if 'next-page' in url: return MockResponse(200, buys_paginated_end) # else return MockResponse(200, buys_response) if 'sells' in url: if 'next-page' in url: return MockResponse(200, sells_paginated_end) # else return MockResponse(200, sells_response) if 'deposits' in url: return MockResponse(200, deposits_response) if 'withdrawals' in url: return MockResponse(200, withdrawals_response) if 'accounts' in url: # keep it simple just return a single ID and ignore the rest of the fields return MockResponse(200, '{"data": [{"id": "5fs23"}]}') # else raise AssertionError(f'Unexpected url {url} for test')
def mocked_request_dict(url, *_args, **_kwargs): addr1_tx = f"""{{"blockNumber":"1","timeStamp":"1","hash":"0x9c81f44c29ff0226f835cd0a8a2f2a7eca6db52a711f8211b566fd15d3e0e8d4","nonce":"0","blockHash":"0xd3cabad6adab0b52ea632c386ea19403680571e682c62cb589b5abcd76de2159","transactionIndex":"0","from":"{eth_accounts[0]}","to":"{eth_accounts[1]}","value":"1","gas":"2000000","gasPrice":"10000000000000","isError":"0","txreceipt_status":"","input":"0x","contractAddress":"","cumulativeGasUsed":"1436963","gasUsed":"1436963","confirmations":"1"}}""" # noqa: E501 addr2_txs = f"""{addr1_tx}, {{"blockNumber":"2","timeStamp":"2","hash":"0x1c81f54c29ff0226f835cd0a2a2f2a7eca6db52a711f8211b566fd15d3e0e8d4","nonce":"1","blockHash":"0xd1cabad2adab0b56ea632c386ea19403680571e682c62cb589b5abcd76de2159","transactionIndex":"0","from":"{eth_accounts[1]}","to":"{make_ethereum_address()}","value":"1","gas":"2000000","gasPrice":"10000000000000","isError":"0","txreceipt_status":"","input":"0x","contractAddress":"","cumulativeGasUsed":"1436963","gasUsed":"1436963","confirmations":"1"}}""" # noqa: E501 if '=txlistinternal&' in url: # don't return any internal transactions payload = '{"status":"1","message":"OK","result":[]}' elif '=txlist&' in url: if eth_accounts[0] in url: tx_str = addr1_tx elif eth_accounts[1] in url: tx_str = addr2_txs else: raise AssertionError( 'Requested etherscan transactions for unknown address in tests', ) payload = f'{{"status":"1","message":"OK","result":[{tx_str}]}}' elif '=getblocknobytime&' in url: # we don't really care about this so just return whatever payload = '{"status":"1","message":"OK","result": "1"}' return MockResponse(200, payload)
def mocked_get(url, *args, **kwargs): if consider_authentication_invalid: return MockResponse( HTTPStatus.UNAUTHORIZED, {'error': 'API KEY signature mismatch'}, ) if 'last_data_metadata' in url: assert metadata_last_modify_ts is not None assert metadata_data_hash is not None assert metadata_data_size is not None implementation = mock_query_last_metadata( last_modify_ts=metadata_last_modify_ts, data_hash=metadata_data_hash, data_size=metadata_data_size, ) elif 'get_saved_data' in url: implementation = mock_get_saved_data(saved_data=saved_data) else: raise ValueError('Unmocked url in session get for premium') return implementation(url, *args, **kwargs)
def mock_response(url, *args): # pylint: disable=unused-argument if 'tokenBalances' in url: if '0x9531C059098e3d194fF87FebB587aB07B30B1306' in url: data = ALETHIO_SIMPLE_TOKEN_BALANCES elif '0xa57Bd00134B2850B2a1c55860c9e9ea100fDd6CF' in url: data = ALETHIO_MULTIPAGE_TOKEN_BALANCES1 else: raise AssertionError( 'Unexpected Alethio tokenBalance call during mocking in tests', ) elif 'token-balances?filter' in url: if 'f432555e5c898f83fc5f00df631bd9c2801fea289' in url: data = ALETHIO_MULTIPAGE_TOKEN_BALANCES2 elif 'fac9bb427953ac7fddc562adca86cf42d988047fd' in url: data = ALETHIO_MULTIPAGE_TOKEN_BALANCES3 else: raise AssertionError( 'Unexpected Alethio tokenBalance call during mocking in tests', ) else: raise AssertionError( 'Unexpected Alethio call during mocking in tests') return MockResponse(200, data)
def mock_api_return(url, req): # pylint: disable=unused-argument contents = """{ "BTC_BCH": [ { "globalTradeID": 394131412, "tradeID": "5455033", "date": "2018-10-16 18:05:17", "rate": "0.06935244", "amount": "1.40308443", "total": "0.09730732", "fee": "0.00100000", "orderNumber": "104768235081", "type": "sell", "category": "exchange" }], "BTC_ETH": [{ "globalTradeID": 394127361, "tradeID": "13536350", "date": "2018-10-16 17:03:43", "rate": "0.00003432", "amount": "3600.53748129", "total": "0.12357044", "fee": "0.00200000", "orderNumber": "96238912841", "type": "buy", "category": "exchange"}]}""" return MockResponse(200, contents)
def mock_api_return(method, url, **kwargs): # pylint: disable=unused-argument assert method == 'post' response = """{"Data": [ {"AvgPrice": 603.7, "CreatedTimestampUtc": "2017-11-22T22:54:40.3249401Z", "FeePercent": 0.005, "OrderGuid": "foo1", "OrderType": "MarketOffer", "Original": {"Outstanding": 0.0, "Volume": 0.5, "VolumeCurrencyType": "Primary"}, "Outstanding": 0.0, "Price": null, "PrimaryCurrencyCode": "Eth", "SecondaryCurrencyCode": "Aud", "Status": "Filled", "Value": 301.85, "Volume": 0.5 }, { "AvgPrice": 257.25, "CreatedTimestampUtc": "2017-07-28T09:39:19.8799244Z", "FeePercent": 0.005, "OrderGuid": "foo2", "OrderType": "MarketBid", "Original": {"Outstanding": 0.0, "Volume": 2.64117379, "VolumeCurrencyType": "Primary"}, "Outstanding": 0.0, "Price": null, "PrimaryCurrencyCode": "Eth", "SecondaryCurrencyCode": "Aud", "Status": "Filled", "Value": 679.44, "Volume": 2.64117379 }], "PageSize": 50, "TotalItems": 2, "TotalPages": 1} """ # noqa: E501 return MockResponse(200, response)
def do_mock_get_saved_data(url, data, timeout): # pylint: disable=unused-argument assert len(data) == 1 assert 'nonce' in data assert timeout == ROTKEHLCHEN_SERVER_TIMEOUT payload = f'{{"data": "{saved_data.decode()}"}}' return MockResponse(200, payload)
def mock_get_deposit_withdrawal(url, data): # pylint: disable=unused-argument return MockResponse(200, input_str)
def mock_poloniex_asset_return(url, *args): # pylint: disable=unused-argument return MockResponse(200, POLONIEX_BALANCES_RESPONSE)
def mock_api_remote_fail(url, timeout): # pylint: disable=unused-argument return MockResponse(500, '{"msg": "shit hit the fan"')
def mock_currency_converter_api(url, timeout): # pylint: disable=unused-argument return MockResponse(200, '{"results": {"USD_EUR": {"val": 1.1543, "id": "USD_EUR"}}}')
def mock_exchanges_rateapi_fail(url, timeout): # pylint: disable=unused-argument nonlocal count count += 1 if 'exchangeratesapi' in url: return MockResponse(501, '{"msg": "some error")') return original_get(url)
def mock_response(url, method, json): # pylint: disable=unused-argument response = MockResponse(HTTPStatus.UNAUTHORIZED, '{"code": "INVALID_TIMESTAMP"}') return response
def mock_order_history(url, method, json): # pylint: disable=unused-argument response = MockResponse(200, BITTREX_ORDER_HISTORY_RESPONSE) return response
"currencySymbol": "BTC", "confirmations": 2, "completedAt": "2014-07-09T04:24:47.217Z", "txId": "e26d3b33fcfc2cb0c74d0938034956ea590339170bf4102f080eab4b85da9bde", "cryptoAddress": "1DeaaFBdbB5nrHj87x3NHS4onvw1GPNyAu", "source": "foo" }]""" check_permutations_of_input_invalid_data( deposits=input_deposits, withdrawals=empty_response, ) @pytest.mark.parametrize('response, exception', [ ( MockResponse(HTTPStatus.OK, '{"result": "a result"}'), None, ), ( MockResponse(HTTPStatus.UNAUTHORIZED, 'this is not a dict'), RemoteError, ), ( MockResponse(HTTPStatus.UNAUTHORIZED, '{"code": "NOT_THE_EXPECTED_CODE"}'), None, ), ( MockResponse(HTTPStatus.UNAUTHORIZED, '{"not_code": "INVALID_TIMESTAMP"}'), None,
def mock_requests_requests(method, url, *args, **kwargs): if 'transfers' not in url: return original_requests_request(method, url, *args, **kwargs) return MockResponse(200, TRANSFERS_RESPONSE)