2022-03-08 16:23:15 +01:00
from datetime import datetime
import json
2022-01-13 09:38:44 +01:00
import logging
2022-03-08 16:23:15 +01:00
from unittest . mock import MagicMock , patch
2022-07-18 16:54:04 +02:00
import mock
2022-03-08 16:23:15 +01:00
2022-01-13 09:38:44 +01:00
import pytest
2022-03-08 16:23:15 +01:00
from werkzeug . wrappers import Response
from cryptoadvance . specter . wallet import Wallet
2022-01-13 09:38:44 +01:00
def test_fees ( caplog , client ) :
""" The root of the app """
caplog . set_level ( logging . INFO )
caplog . set_level ( logging . DEBUG , logger = " cryptoadvance.specter " )
login ( client , " secret " )
result = client . get ( " /wallets/fees " )
assert result . status_code == 200
my_dict = json . loads ( result . data )
assert my_dict [ " result " ] [ " fastestFee " ] == 1
assert my_dict [ " error_messages " ] == [ ]
logout ( client )
2022-10-29 15:54:34 +02:00
@patch ( " cryptoadvance.specter.server_endpoints.wallets.wallets_api.get_price_at " )
@patch ( " cryptoadvance.specter.server_endpoints.wallets.wallets_api._ " )
2022-03-08 16:23:15 +01:00
def test_txlist_to_csv (
mock_babel : MagicMock ,
mock_get_price_at : MagicMock ,
caplog ,
app ,
specter_regtest_configured ,
funded_hot_wallet_1 ,
) :
caplog . set_level ( logging . DEBUG )
def fake_translate ( text ) :
return text
mock_babel . side_effect = fake_translate
mock_get_price_at . return_value = 1000000 , " $ "
assert mock_get_price_at ( ) == ( 1000000 , " $ " )
with app . test_request_context ( ) :
2022-10-29 15:54:34 +02:00
from cryptoadvance . specter . server_endpoints . wallets . wallets_api import (
txlist_to_csv ,
)
2022-03-08 16:23:15 +01:00
curr_date = datetime . now ( )
for i , tx in enumerate (
txlist_to_csv (
funded_hot_wallet_1 ,
funded_hot_wallet_1 . txlist ( ) ,
includePricesHistory = True ,
)
) :
tx = tx . split ( " , " )
print ( f " { i } { tx } " )
if i == 0 :
assert tx [ 0 ] == " Date "
assert tx [ 1 ] == " Label "
assert tx [ 2 ] == " Category "
assert tx [ 3 ] == " Amount (BTC) "
assert tx [ 4 ] == " Value (USD) "
assert tx [ 5 ] == " Rate (BTC/USD) "
assert tx [ 6 ] == " TxID "
assert tx [ 7 ] == " Address "
assert tx [ 8 ] == " Block Height "
assert tx [ 9 ] . strip ( ) == " Timestamp "
continue
assert tx [ 0 ] == curr_date . strftime ( " % Y- % m- %d " )
assert tx [ 1 ] . startswith ( " Address # " )
assert tx [ 2 ] == " receive "
assert float ( tx [ 3 ] ) > 0
assert (
float ( tx [ 4 ] ) < = 1000000 * 10
) # funded_hot_wallet_1 has no transactions >= 10 btc
assert float ( tx [ 5 ] ) == 1000000
assert tx [ 7 ] . startswith ( " bcrt1 " )
# stupid, why not simply 0:
if isinstance ( tx [ 8 ] , str ) and tx [ 8 ] == " Unconfirmed " :
pass
else :
assert int ( tx [ 8 ] ) > 0
assert (
datetime . strptime ( tx [ 9 ] . strip ( ) , " % Y- % m- %d % H: % M: % S " ) - curr_date
) . total_seconds ( ) < 120 # less than 2 minutes difference (for super slow pytesting)
# assert False
2022-10-29 15:54:34 +02:00
@patch ( " cryptoadvance.specter.server_endpoints.wallets.wallets_api.get_price_at " )
@patch ( " cryptoadvance.specter.server_endpoints.wallets.wallets_api._ " )
2022-03-08 16:23:15 +01:00
def test_addresses_list_to_csv (
mock_babel : MagicMock ,
mock_get_price_at : MagicMock ,
caplog ,
app ,
specter_regtest_configured ,
funded_hot_wallet_1 : Wallet ,
) :
""" addresses_list_to_csv does not seem to be used, though """
caplog . set_level ( logging . INFO )
def fake_translate ( text ) :
return text
mock_babel . side_effect = fake_translate
mock_get_price_at . return_value = 1000000 , " $ "
assert mock_get_price_at ( ) == ( 1000000 , " $ " )
with app . test_request_context ( ) :
2022-10-29 15:54:34 +02:00
from cryptoadvance . specter . server_endpoints . wallets . wallets_api import (
2022-03-08 16:23:15 +01:00
addresses_list_to_csv ,
)
# update balancess
funded_hot_wallet_1 . update ( )
curr_date = datetime . now ( )
for i , addr in enumerate ( addresses_list_to_csv ( funded_hot_wallet_1 ) ) :
addr = addr . split ( " , " )
print ( f " { i } { addr } " )
if i == 0 :
assert addr [ 0 ] == " Address "
assert addr [ 1 ] == " Label "
assert addr [ 2 ] == " Index "
assert addr [ 3 ] == " Used "
assert addr [ 4 ] . strip ( ) == " Current balance "
continue
assert addr [ 0 ] . startswith ( " bcrt1 " )
assert addr [ 1 ] . startswith ( " Address # " )
# assert int(addr[2]) == i
assert bool ( addr [ 3 ] )
assert float ( addr [ 4 ] . strip ( ) ) > 0
2022-07-18 16:54:04 +02:00
def test_txout_set_info ( caplog , app , client ) :
caplog . set_level ( logging . DEBUG )
caplog . set_level ( logging . DEBUG , logger = " cryptoadvance.specter " )
login ( client , " secret " )
res = client . get ( " /wallets/get_txout_set_info " )
assert res . status == " 200 OK "
print ( json . loads ( res . data ) )
assert json . loads ( res . data ) [ " total_amount " ] > 0
2022-12-19 21:30:17 +01:00
@pytest.mark.slow
def test_addressinfo ( caplog , client , funded_ghost_machine_wallet ) :
caplog . set_level ( logging . DEBUG )
caplog . set_level ( logging . DEBUG , logger = " cryptoadvance.specter " )
login ( client , " secret " )
# get loaded wallet info
response = client . get ( " /wallets/wallets_loading/ " , follow_redirects = True )
loaded_wallet_name = json . loads ( response . data ) [ " loaded_wallets " ] [ 0 ]
receive_address = funded_ghost_machine_wallet . get_address ( 0 , change = False )
url = f " /wallets/wallet/ { loaded_wallet_name } /addressinfo/ "
headers = {
" Content-Type " : " application/x-www-form-urlencoded " ,
" ACCEPT " : " application/json " ,
}
# send post request
res = client . post (
url , data = { " address " : receive_address } , follow_redirects = True , headers = headers
)
assert res . status == " 200 OK "
assert (
res . data . decode ( )
== ' { " address " : " bcrt1qvtdx75y4554ngrq6aff3xdqnvjhmct5wck95qs " , " change " :false, " derivation_path " : " m/84h/1h/0h/0/0 " , " descriptor " : " wpkh([8c24a510/84h/1h/0h/0/0]0331edcb16cfd0f8598052f7b287b07047a11c60967c1e7eb0257e02552539d984)#35zjhlhm " , " index " :0, " is_mine " :true, " label " :null, " service_id " :null, " success " :true, " used " :null, " wallet_name " : " ghost_machine " , " xpubs_descriptor " : " wpkh([8c24a510/84h/1h/0h]tpubDC4DsqH5rqHqipMNqUbDFtQT3AkKkUrvLsN6miySvortU3s1LGaNVAb7wX2No2VsuxQV82T8s3HJLv3kdx1CPjsJ3onC1Zo5mWCQzRVaWVX/0/0)#8f5u4zq2 " } \n '
)
# send post request with bad address
invalid_address = " bcrt1qvtdx7 "
res = client . post (
url , data = { " address " : invalid_address } , follow_redirects = True , headers = headers
)
assert (
res . data . decode ( )
== ' { " error " : " Request error for method getaddressinfo: Invalid address format " } \n '
)
# send post request with address, not belonging to wallet
# this recreates an edge case, see https://github.com/cryptoadvance/specter-desktop/issues/2000
valid_address_not_beloging_to_wallet = (
" bcrt1q895evdudfrmeut083vs85rc85g2wq6p6ql2hla "
)
res = client . post (
url ,
data = { " address " : valid_address_not_beloging_to_wallet } ,
follow_redirects = True ,
headers = headers ,
)
assert res . status == " 200 OK "
assert res . data . decode ( ) == ' { " success " :false} \n '
assert (
caplog . text . count (
f " No descriptor or xpubs_descriptor was found for address { valid_address_not_beloging_to_wallet } in wallet ghost_machine "
)
== 1
)
# set erronious descriptor
with mock . patch . object (
funded_ghost_machine_wallet ,
" get_descriptor " ,
return_value = " this is not a descriptor " ,
create = True ,
) as m :
res = client . post (
url ,
data = { " address " : receive_address } ,
follow_redirects = True ,
headers = headers ,
)
assert res . status == " 200 OK "
assert (
res . data . decode ( )
== ' { " address " : " bcrt1qvtdx75y4554ngrq6aff3xdqnvjhmct5wck95qs " , " change " :false, " descriptor " : " this is not a descriptor " , " index " :0, " is_mine " :true, " label " :null, " service_id " :null, " success " :false, " used " :null, " wallet_name " : " ghost_machine " , " xpubs_descriptor " : " this is not a descriptor " } \n '
)
2022-01-13 09:38:44 +01:00
# Ugly: Code duplication. Cannot import from other test_modules
def login ( client , password ) :
""" login helper-function """
result = client . post (
" auth/login " , data = dict ( password = password ) , follow_redirects = True
)
assert (
b " We could not check your password, maybe Bitcoin Core is not running or not configured? "
not in result . data
)
return result
def logout ( client ) :
""" logout helper-method """
return client . get ( " auth/logout " , follow_redirects = True )