def test_query_all_balances_with_manually_tracked_balances( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, manually_tracked_balances, ): """Test that using the query all balances endpoint also includes manually tracked balances""" # Disable caching of query results rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances( rotki=rotki, ethereum_accounts=ethereum_accounts, btc_accounts=btc_accounts, manually_tracked_balances=manually_tracked_balances, ) # now do the same but save the data in the DB and test it works # `save_data` is False by default but data will save since this is a fresh account with ExitStack() as stack: setup.enter_all_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), ) assert_proper_response(response) json_data = response.json() assert_all_balances( data=json_data, db=rotki.data.db, expected_data_in_db=True, setup=setup, )
def test_qerying_settings(rotkehlchen_api_server, username): """Make sure that querying settings works for logged in user""" response = requests.get( api_url_for(rotkehlchen_api_server, "settingsresource")) assert_proper_response(response) json_data = response.json() result = json_data['result'] assert json_data['message'] == '' assert result['version'] == ROTKEHLCHEN_DB_VERSION for setting in DBSettings._fields: assert setting in result # Logout of the active user data = {'action': 'logout'} response = requests.patch( api_url_for(rotkehlchen_api_server, "usersbynameresource", name=username), json=data, ) assert_simple_ok_response(response) # and now with no logged in user it should fail response = requests.get( api_url_for(rotkehlchen_api_server, "settingsresource")) assert_error_response( response=response, contained_in_msg='No user is currently logged in', status_code=HTTPStatus.CONFLICT, )
def test_user_creation(rotkehlchen_api_server, data_dir): """Test that PUT at user endpoint can create a new user""" # Create a user without any premium credentials username = '******' data = { 'name': username, 'password': '******', } response = requests.put(api_url_for(rotkehlchen_api_server, "usersresource"), json=data) assert_proper_response(response) check_proper_unlock_result(response.json(), {'submit_usage_analytics': True}) # Query users and make sure the new user is logged in response = requests.get( api_url_for(rotkehlchen_api_server, "usersresource")) assert_proper_response(response) json = response.json() assert json['result'][username] == 'loggedin' assert len(json['result']) == 1 # Check that the directory was created assert Path(data_dir / username / 'rotkehlchen.db').exists()
def test_query_version_when_update_required(rotkehlchen_api_server): """Test that endpoint to query version works when a new version is available""" def patched_get_latest_release(_klass): new_latest = 'v99.99.99' return new_latest, f'https://github.com/rotki/rotki/releases/tag/{new_latest}' release_patch = patch( 'rotkehlchen.externalapis.github.Github.get_latest_release', patched_get_latest_release, ) with release_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "versionresource", ), ) assert_proper_response(response) our_version = get_system_spec()['rotkehlchen'] data = response.json() assert data['message'] == '' assert len(data['result']) == 3 assert data['result']['our_version'] == our_version assert data['result']['latest_version'] == 'v99.99.99' assert 'v99.99.99' in data['result']['download_url']
def test_setup_exchange_does_not_stay_in_mapping_after_500_error( rotkehlchen_api_server): """Test that if 500 error is returned during setup of an exchange and it's stuck in the exchange mapping Rotki doesn't still think the exchange is registered. Regression test for the second part of https://github.com/rotki/rotki/issues/943 """ data = {'name': 'kraken', 'api_key': 'ddddd', 'api_secret': 'fffffff'} with API_KEYPAIR_KRAKEN_VALIDATION_FAIL_PATCH: response = requests.put( api_url_for(rotkehlchen_api_server, "exchangesresource"), json=data, ) assert_error_response( response=response, status_code=HTTPStatus.INTERNAL_SERVER_ERROR, ) # Now try to register the exchange again data = {'name': 'kraken', 'api_key': 'ddddd', 'api_secret': 'fffffff'} with API_KEYPAIR_VALIDATION_PATCH: response = requests.put( api_url_for(rotkehlchen_api_server, "exchangesresource"), json=data, ) assert_simple_ok_response(response) # and check that kraken is now registered response = requests.get( api_url_for(rotkehlchen_api_server, "exchangesresource")) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert json_data['result'] == ['kraken']
def test_query_periodic(rotkehlchen_api_server_with_exchanges): rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts=[], btc_accounts=[]) start_ts = ts_now() # Query trades of an exchange to get them saved in the DB with setup.binance_patch, setup.poloniex_patch: response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'save_data': True}, ) assert_proper_response(response) response = requests.get( api_url_for(rotkehlchen_api_server_with_exchanges, "periodicdataresource"), ) assert_proper_response(response) data = response.json() assert data['message'] == '' assert len(data['result']) == 3 assert data['result']['last_balance_save'] >= start_ts assert data['result']['eth_node_connection'] is False # Non -1 value tests for these exist in test_history.py::test_query_history_timerange assert data['result']['last_data_upload_ts'] == 0
def test_query_version_when_up_to_date(rotkehlchen_api_server): """Test that endpoint to query the rotki version works if no new version is available""" expected_version = 'v1.1.0' def patched_get_system_spec() -> Dict[str, Any]: return {'rotkehlchen': expected_version} def patched_get_latest_release(_klass): return expected_version, f'https://github.com/rotki/rotki/releases/tag/{expected_version}' release_patch = patch( 'rotkehlchen.externalapis.github.Github.get_latest_release', patched_get_latest_release, ) version_patch = patch( 'rotkehlchen.utils.version_check.get_system_spec', patched_get_system_spec, ) with version_patch, release_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "versionresource", ), ) assert_proper_response(response) data = response.json() assert data['message'] == '' assert len(data['result']) == 3 assert data['result']['our_version'] == expected_version assert data['result']['latest_version'] == expected_version assert data['result']['download_url'] is None
def test_query_statistics_renderer(rotkehlchen_api_server, start_with_valid_premium): """Test that the statistics renderer endpoint works when properly queried""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen if start_with_valid_premium: def mock_premium_get(url, *args, **kwargs): if 'last_data_metadata' in url: response = ( '{"upload_ts": 0, "last_modify_ts": 0, "data_hash": "0x0", "data_size": 0}' ) else: response = '{"data": "codegoeshere"}' return MockResponse(200, response) premium_patch = patch.object(rotki.premium.session, 'get', mock_premium_get) else: premium_patch = contextlib.nullcontext() with premium_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "statisticsrendererresource", ), ) if start_with_valid_premium: assert_proper_response(response) data = response.json() assert data['message'] == '' assert data['result'] == 'codegoeshere' else: assert_error_response( response=response, contained_in_msg='logged in user testuser does not have a premium subscription', status_code=HTTPStatus.CONFLICT, )
def test_set_rpc_endpoint_fail_not_set_others(rotkehlchen_api_server): """Test that setting a non-existing eth rpc along with other settings does not modify them""" eth_rpc_endpoint = 'http://working.nodes.com:8545' main_currency = A_JPY data = { 'settings': { 'eth_rpc_endpoint': eth_rpc_endpoint, 'main_currency': main_currency.identifier, } } response = requests.put(api_url_for(rotkehlchen_api_server, "settingsresource"), json=data) assert_error_response( response=response, contained_in_msg= (f'Failed to connect to ethereum node own node at endpoint {eth_rpc_endpoint}' ), status_code=HTTPStatus.CONFLICT, ) # Get settings and make sure they have not been modified response = requests.get( api_url_for(rotkehlchen_api_server, "settingsresource")) assert_proper_response(response) json_data = response.json() result = json_data['result'] assert json_data['message'] == '' assert result['main_currency'] != 'JPY' assert result['eth_rpc_endpoint'] != 'http://working.nodes.com:8545'
def test_removing_ethereum_tokens( rotkehlchen_api_server, ethereum_accounts, ): """Test that the rest api endpoint to add new ethereum tokens works properly""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, token_balances={ A_RDN: ['0', '0'], A_DAI: ['50000000', '0'], A_GNO: ['0', '0'], }, btc_accounts=[], ) # Remove GNO and RDN as tracked tokens and make sure that the dai balance checks out with setup.etherscan_patch, setup.alethio_patch: response = requests.delete(api_url_for( rotkehlchen_api_server, "ethereumtokensresource", ), json={'eth_tokens': ['GNO', 'RDN']}) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_modifying_ethereum_tokens( rotkehlchen_api_server, json_data, ethereum_accounts, setup, ['DAI'], )
def test_unset_rpc_endpoint(rotkehlchen_api_server): """Test the rpc endpoint can be unset""" response = requests.get( api_url_for(rotkehlchen_api_server, "settingsresource")) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' result = json_data['result'] assert result['eth_rpc_endpoint'] != '' data = { 'settings': { 'eth_rpc_endpoint': '' }, } response = requests.put(api_url_for(rotkehlchen_api_server, "settingsresource"), json=data) assert_proper_response(response) json_data = response.json() result = json_data['result'] assert json_data['message'] == '' assert result['eth_rpc_endpoint'] == ''
def test_query_owned_assets( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, number_of_eth_accounts, ): """Test that using the query all owned assets endpoint works""" # Disable caching of query results rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts, btc_accounts) # Get all our mocked balances and save them in the DB with setup.poloniex_patch, setup.binance_patch, setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'save_data': True}, ) assert_proper_response(response) # And now check that the query owned assets endpoint works with setup.poloniex_patch, setup.binance_patch, setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "ownedassetsresource", ), ) assert_proper_response(response) data = response.json() assert data['message'] == '' assert set(data['result']) == {'ETH', 'BTC', 'EUR', 'RDN'}
def test_disable_taxfree_after_period(rotkehlchen_api_server): """Test that providing -1 for the taxfree_after_period setting disables it """ data = { 'taxfree_after_period': -1, } response = requests.put(api_url_for(rotkehlchen_api_server, "settingsresource"), json=data) assert_proper_response(response) json_data = response.json() assert json_data['result']['taxfree_after_period'] is None # Test that any other negative value is refused data = { 'taxfree_after_period': -5, } response = requests.put(api_url_for(rotkehlchen_api_server, "settingsresource"), json=data) assert_error_response( response=response, contained_in_msg='The taxfree_after_period value can not be negative', status_code=HTTPStatus.BAD_REQUEST, ) # Test that zero value is refused data = { 'taxfree_after_period': 0, } response = requests.put(api_url_for(rotkehlchen_api_server, "settingsresource"), json=data) assert_error_response( response=response, contained_in_msg='The taxfree_after_period value can not be set to zero', status_code=HTTPStatus.BAD_REQUEST, )
def test_remove_exchange(rotkehlchen_api_server): """Test that removing a setup exchange via the api works""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen db = rotki.data.db # Setup coinbase exchange data = {'name': 'coinbase', 'api_key': 'ddddd', 'api_secret': 'fffffff'} with API_KEYPAIR_COINBASE_VALIDATION_PATCH: response = requests.put( api_url_for(rotkehlchen_api_server, "exchangesresource"), json=data, ) assert_simple_ok_response(response) # Add query ranges to see that they also get deleted when removing the exchange cursor = db.conn.cursor() cursor.executemany( 'INSERT OR REPLACE INTO used_query_ranges(name, start_ts, end_ts) VALUES (?, ?, ?)', [('coinbasepro_trades', 0, 1579564096), ('coinbasepro_margins', 0, 1579564096), ('coinbasepro_asset_movements', 0, 1579564096), ('coinbase_trades', 0, 1579564096), ('coinbase_margins', 0, 1579564096), ('coinbase_asset_movements', 0, 1579564096), ('binance_trades', 0, 1579564096), ('binance_margins', 0, 1579564096), ('binance_asset_movements', 0, 1579564096)], ) # Now remove the registered coinbase exchange data = {'name': 'coinbase'} response = requests.delete(api_url_for(rotkehlchen_api_server, "exchangesresource"), json=data) assert_simple_ok_response(response) # and check that it's not registered anymore response = requests.get( api_url_for(rotkehlchen_api_server, "exchangesresource")) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert json_data['result'] == [] # Also check that the coinbase query ranges have been deleted but not the other ones cursor = db.conn.cursor() result = cursor.execute('SELECT name from used_query_ranges') count = 0 for entry in result: count += 1 msg = 'only binance or coinbasepro query ranges should remain' assert 'binance' in entry[0] or 'coinbasepro' in entry[0], msg assert count == 6, 'only 6 query ranges should remain in the DB' # now try to remove a non-registered exchange data = {'name': 'binance'} response = requests.delete(api_url_for(rotkehlchen_api_server, "exchangesresource"), json=data) assert_error_response( response=response, contained_in_msg='Exchange binance is not registered', status_code=HTTPStatus.CONFLICT, )
def test_query_historical_dsr( rotkehlchen_api_server, ethereum_accounts, ): rotki = rotkehlchen_api_server.rest_api.rotkehlchen account1 = ethereum_accounts[0] account2 = ethereum_accounts[2] setup = setup_tests_for_dsr( etherscan=rotki.etherscan, account1=account1, account2=account2, original_requests_get=requests.get, ) with setup.etherscan_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "makerdaodsrhistoryresource", )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' result = json_data['result'] assert_dsr_history_result_is_correct(result, setup)
def test_query_statistics_netvalue( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, ): """Test that using the statistics netvalue over time endpoint works""" # Disable caching of query results rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts, btc_accounts) # query balances and save data in DB to have data to test the statistics endpoint with ExitStack() as stack: setup.enter_all_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'save_data': True}, ) assert_proper_response(response) # and now test that statistics work fine response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "statisticsnetvalueresource", ), ) result = assert_proper_response_with_result(response) assert len(result) == 2 assert len(result['times']) == 1 assert len(result['data']) == 1
def check_user_status(api_server) -> Dict[str, str]: # Check users status response = requests.get(api_url_for(api_server, "usersresource"), ) assert_proper_response(response) data = response.json() assert data['message'] == '' return response.json()['result']
def test_query_historical_dsr( rotkehlchen_api_server, ethereum_accounts, inquirer, # pylint: disable=unused-argument ): """Test DSR history is correctly queried This (and the async version) is a very hard to maintain test due to mocking everything. TODO: Perhaps change it to querying etherscan/chain until a given block for a given DSR account and check that until then all data match. """ rotki = rotkehlchen_api_server.rest_api.rotkehlchen account1 = ethereum_accounts[0] account2 = ethereum_accounts[2] setup = setup_tests_for_dsr( etherscan=rotki.etherscan, account1=account1, account2=account2, original_requests_get=requests.get, ) with setup.etherscan_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "makerdaodsrhistoryresource", )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' result = json_data['result'] assert_dsr_history_result_is_correct(result, setup)
def test_query_history_timerange(rotkehlchen_api_server_with_exchanges): """Same as test_query_history but on a limited timerange""" rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen start_ts = 1539713237 end_ts = 1539713238 setup = prepare_rotki_for_history_processing_test( rotki, should_mock_history_processing=False, history_start_ts=start_ts, history_end_ts=end_ts, ) # Query history processing to start the history processing with ExitStack() as stack: for manager in setup: if manager is None: continue stack.enter_context(manager) response = requests.get( api_url_for(rotkehlchen_api_server_with_exchanges, "historyprocessingresource"), json={ 'from_timestamp': start_ts, 'to_timestamp': end_ts }, ) # Simply check that the results got returned here. The actual correctness of # accounting results is checked in other tests such as test_simple_accounting assert_proper_response(response) data = response.json() assert data['message'] == '' assert len(data['result']) == 2 overview = data['result']['overview'] assert len(overview) == 11 assert overview["loan_profit"] is not None assert overview["margin_positions_profit_loss"] is not None assert overview["settlement_losses"] is not None assert overview["ethereum_transaction_gas_costs"] is not None assert overview["asset_movement_fees"] is not None assert overview["general_trade_profit_loss"] is not None assert overview["taxable_trade_profit_loss"] is not None assert overview["total_taxable_profit_loss"] is not None assert overview["total_profit_loss"] is not None assert overview["defi_profit_loss"] is not None assert overview["ledger_actions_profit_loss"] is not None all_events = data['result']['all_events'] assert isinstance(all_events, list) assert len(all_events) == 4 response = requests.get( api_url_for(rotkehlchen_api_server_with_exchanges, "periodicdataresource"), ) assert_proper_response(response) data = response.json() assert data['result']['last_balance_save'] == 0 assert data['result']['eth_node_connection'] is False assert data['result']['history_process_start_ts'] == 1428994442 assert data['result']['history_process_current_ts'] == end_ts
def assert_okay(response): """Helper function to run next query and its assertion twice""" assert_proper_response(response) data = response.json() assert data['message'] == '' assert len(data['result']) == 2 # only 2 binance trades assert_binance_trades_result( [t for t in data['result'] if t['location'] == 'binance'])
def test_history_export_csv_errors( rotkehlchen_api_server_with_exchanges, tmpdir_factory, ): """Test that errors on the csv export REST API endpoint are handled correctly""" rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen setup = prepare_rotki_for_history_processing_test( rotki, should_mock_history_processing=False, ) csv_dir = str(tmpdir_factory.mktemp('test_csv_dir')) # Query the export endpoint without first having queried the history response = requests.get( api_url_for(rotkehlchen_api_server_with_exchanges, "historyexportingresource"), json={'directory_path': csv_dir}, ) assert_error_response( response=response, contained_in_msg='No history processed in order to perform an export', status_code=HTTPStatus.CONFLICT, ) # Now, query history processing to have data for exporting with ExitStack() as stack: for manager in setup: if manager is None: continue stack.enter_context(manager) response = requests.get( api_url_for(rotkehlchen_api_server_with_exchanges, "historyprocessingresource"), ) assert_proper_response(response) # And now provide non-existing path for directory response = requests.get( api_url_for(rotkehlchen_api_server_with_exchanges, "historyexportingresource"), json={'directory_path': '/idont/exist/for/sure/'}, ) assert_error_response( response=response, contained_in_msg='"directory_path": ["Given path /idont/exist/for/sure/ does not exist', status_code=HTTPStatus.BAD_REQUEST, ) # And now provide valid path but not directory tempfile = Path(Path(csv_dir) / 'f.txt') tempfile.touch() response = requests.get( api_url_for(rotkehlchen_api_server_with_exchanges, "historyexportingresource"), json={'directory_path': str(tempfile)}, ) assert_error_response( response=response, contained_in_msg='is not a directory', status_code=HTTPStatus.BAD_REQUEST, )
def test_query_async_task_that_died(rotkehlchen_api_server_with_exchanges): """If an async task dies with an exception check that it's properly handled""" # async query balances of one specific exchange server = rotkehlchen_api_server_with_exchanges binance = server.rest_api.rotkehlchen.exchange_manager.connected_exchanges[ 'binance'] def mock_binance_asset_return(url): # pylint: disable=unused-argument raise ValueError('BOOM!') binance_patch = patch.object(binance.session, 'get', side_effect=mock_binance_asset_return) # Create an async task with binance_patch: response = requests.get(api_url_for( server, "named_exchanges_balances_resource", name='binance', ), json={'async_query': True}) task_id = assert_ok_async_response(response) # now check that there is a task response = requests.get(api_url_for(server, "asynctasksresource")) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert json_data['result'] == [task_id] while True: # and now query for the task result and assert on it response = requests.get( api_url_for(server, "specific_async_tasks_resource", task_id=task_id), ) assert_proper_response(response) json_data = response.json() if json_data['result']['status'] == 'pending': # context switch so that the greenlet to query balances can operate gevent.sleep(1) elif json_data['result']['status'] == 'completed': break else: raise AssertionError( f"Unexpected status: {json_data['result']['status']}") assert json_data['message'] == '' assert json_data['result']['status'] == 'completed' # assert that the backend task query died and we detect it assert json_data['result']['outcome'] is not None assert json_data['result']['outcome']['result'] is None msg = 'The backend query task died unexpectedly: BOOM!' assert json_data['result']['outcome']['message'] == msg
def assert_okay(response): """Helper function for DRY checking below assertions""" assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert len(json_data['result'] ) == 2, 'only two exchanges should be registered' assert_binance_trades_result(json_data['result']['binance']) assert_poloniex_trades_result(json_data['result']['poloniex'], trades_to_check=(0, ))
def assert_okay(response): """Helper function for DRY checking below assertions""" assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' result = json_data['result'] assert len(result) == 3 assert FVal(result['EUR']) > 0 assert FVal(result['USD']) > 0 assert FVal(result['KRW']) > 0
def test_loggedin_user_querying(rotkehlchen_api_server, username, data_dir): """Start with a logged in user and make sure we can query all users""" Path(data_dir / 'another_user').mkdir() Path(data_dir / 'another_user' / 'rotkehlchen.db').touch() response = requests.get(api_url_for(rotkehlchen_api_server, "usersresource")) assert_proper_response(response) json = response.json() assert json['result'][username] == 'loggedin' assert json['result']['another_user'] == 'loggedout' assert len(json['result']) == 2
def test_query_all_assets(rotkehlchen_api_server): """Test that using the query all owned assets endpoint works Compare with the contents of all_assets.json. Essentially tests that priming the DB works. That's why there is quite a few extra checks for things that changed when moving to global DB """ response = requests.get( api_url_for( rotkehlchen_api_server, "allassetsresource", ), ) assert_proper_response(response) data = response.json() assert data['message'] == '' dir_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) with open(os.path.join(dir_path, 'data', 'all_assets.json'), 'r') as f: expected_assets = json.loads(f.read()) returned_ids = set(data['result'].keys()) expected_ids = set(expected_assets.keys()) expected_missing_ids = {'XD'} assert expected_ids - returned_ids == expected_missing_ids, f'Missing ids: {expected_ids - returned_ids - expected_missing_ids}' # noqa: E501 for asset_id, entry_data in data['result'].items(): for key, val in entry_data.items(): if key in ('active', 'ended'): continue # we ignore these keys after DB insertion other_key = key if key == 'asset_type': other_key = 'type' elif key == 'decimals': other_key = 'ethereum_token_decimals' if val is not None: is_ethereum_token_and_more = ( key == 'asset_type' and val == 'ethereum token' and expected_assets[asset_id][other_key] == 'ethereum token and more' ) if is_ethereum_token_and_more: continue # we ignore this distinction in the DB expected_val = expected_assets[asset_id][other_key] if key == 'asset_type': expected_val = expected_val.lower() if expected_val == 'ethereum token and own chain': expected_val = 'own chain' assert val == expected_val, f'mismatch of {other_key} for {asset_id}' # noqa: E501 else: assert other_key not in expected_assets[asset_id]
def test_query_ping(rotkehlchen_api_server): """Test that the ping endpoint works""" expected_result = True expected_message = '' response = requests.get(api_url_for(rotkehlchen_api_server, "pingresource")) assert_proper_response(response) response_json = response.json() assert len(response_json) == 2 assert response_json['result'] == expected_result assert response_json['message'] == expected_message
def test_edit_trades(rotkehlchen_api_server_with_exchanges): """Test that editing a trade via the trades endpoint works as expected""" rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen setup = mock_history_processing_and_exchanges(rotki) # Simply get all trades without any filtering with setup.binance_patch, setup.polo_patch: response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "tradesresource", ), ) assert_proper_response(response) trades = response.json()['result']['entries'] # get the binance trades original_binance_trades = [ t['entry'] for t in trades if t['entry']['location'] == 'binance' ] for trade in original_binance_trades: # edit two fields of each binance trade trade['amount'] = '1337.5' trade['notes'] = 'edited trade' response = requests.patch( api_url_for( rotkehlchen_api_server_with_exchanges, "tradesresource", ), json=trade, ) assert_proper_response(response) data = response.json() assert data['message'] == '' # check that the returned trade is edited _check_trade_is_edited(original_trade=trade, result_trade=data['result']) # Finally also query binance trades to see they are edited with setup.binance_patch, setup.polo_patch: response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "tradesresource", ), json={'location': 'binance'}, ) trades = assert_proper_response_with_result(response)['entries'] assert len(trades) == 2 # only 2 binance trades for idx, trade in enumerate(trades): _check_trade_is_edited(original_trade=original_binance_trades[idx], result_trade=trade['entry']) # noqa: E501
def test_query_all_balances( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, number_of_eth_accounts, ): """Test that using the query all balances endpoint works Test that balances from various sources are returned. Such as exchanges, blockchain and FIAT""" # Disable caching of query results rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen rotki.chain_manager.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts, btc_accounts) # Test all balances request by requesting to not save the data with ExitStack() as stack: setup.enter_all_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'save_data': False}, ) assert_proper_response(response) json_data = response.json() assert_all_balances( data=json_data, db=rotki.data.db, expected_data_in_db=False, setup=setup, ) # now do the same but save the data in the DB and test it works # Omit the argument to test that default value of save_data is True with ExitStack() as stack: setup.enter_all_patches(stack) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), ) assert_proper_response(response) json_data = response.json() assert_all_balances( data=json_data, db=rotki.data.db, expected_data_in_db=True, setup=setup, )
def test_exchange_query_trades(rotkehlchen_api_server_with_exchanges): """Test that using the exchange trades query endpoint works fine""" server = rotkehlchen_api_server_with_exchanges setup = mock_history_processing_and_exchanges(server.rest_api.rotkehlchen) # query trades of one specific exchange with setup.binance_patch: response = requests.get( api_url_for( server, "named_exchanges_trades_resource", name='binance', )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_binance_trades_result(json_data['result']) # query trades of all exchanges with setup.binance_patch, setup.polo_patch: response = requests.get(api_url_for(server, "exchangetradesresource")) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert len( json_data['result']) == 2, 'only two exchanges should be registered' assert_binance_trades_result(json_data['result']['binance']) assert_poloniex_trades_result(json_data['result']['poloniex']) def assert_okay(response): """Helper function for DRY checking below assertions""" assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert len(json_data['result'] ) == 2, 'only two exchanges should be registered' assert_binance_trades_result(json_data['result']['binance']) assert_poloniex_trades_result(json_data['result']['poloniex'], trades_to_check=(0, )) # and now query them in a specific time range excluding two of poloniex's trades data = {'from_timestamp': 1499865548, 'to_timestamp': 1539713118} with setup.binance_patch, setup.polo_patch: response = requests.get(api_url_for(server, "exchangetradesresource"), json=data) assert_okay(response) # do the same but with query args. This serves as test of from/to timestamp with query args with setup.binance_patch, setup.polo_patch: response = requests.get( api_url_for(server, "exchangetradesresource") + '?' + urlencode(data)) assert_okay(response)