@ -7,6 +7,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
Address ,
Address.CoinBalance ,
Block ,
Data ,
InternalTransaction ,
Log ,
Token ,
@ -36,7 +37,6 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
correct_reponse = %{
" hash " = > Address . checksum ( address . hash ) ,
" implementation_name " = > nil ,
" is_contract " = > false ,
" is_verified " = > false ,
" name " = > nil ,
@ -50,7 +50,18 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
" exchange_rate " = > nil ,
" implementation_name " = > nil ,
" implementation_address " = > nil ,
" block_number_balance_updated_at " = > nil
" block_number_balance_updated_at " = > nil ,
" has_custom_methods_read " = > false ,
" has_custom_methods_write " = > false ,
" has_methods_read " = > false ,
" has_methods_write " = > false ,
" has_methods_read_proxy " = > false ,
" has_methods_write_proxy " = > false ,
" has_decompiled_code " = > false ,
" has_validated_blocks " = > false ,
" has_logs " = > false ,
" has_tokens " = > false ,
" has_token_transfers " = > false
}
request = get ( conn , " /api/v2/addresses/ #{ Address . checksum ( address . hash ) } " )
@ -135,9 +146,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /transactions " )
assert response = json_response ( request , 200 )
assert response [ " items " ] == [ ]
assert response [ " next_page_params " ] == nil
assert %{ " message " = > " Not found " } = json_response ( request , 404 )
end
test " get 422 on invalid address " , %{ conn : conn } do
@ -331,14 +340,12 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
end
describe " /addresses/{address_hash}/token-transfers " do
test " get empty list on non existing address " , %{ conn : conn } do
test " get 404 on non existing address " , %{ conn : conn } do
address = build ( :address )
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /token-transfers " )
assert response = json_response ( request , 200 )
assert response [ " items " ] == [ ]
assert response [ " next_page_params " ] == nil
assert %{ " message " = > " Not found " } = json_response ( request , 404 )
end
test " get 422 on invalid address " , %{ conn : conn } do
@ -347,10 +354,28 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
assert %{ " message " = > " Invalid parameter(s) " } = json_response ( request , 422 )
end
test " get 404 on non existing address of token " , %{ conn : conn } do
address = insert ( :address )
token = build ( :address )
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /token-transfers " , %{ " token " = > to_string ( token . hash ) } )
assert %{ " message " = > " Not found " } = json_response ( request , 404 )
end
test " get 422 on invalid token address hash " , %{ conn : conn } do
address = insert ( :address )
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /token-transfers " , %{ " token " = > " 0x " } )
assert %{ " message " = > " Invalid parameter(s) " } = json_response ( request , 422 )
end
test " get relevant token transfer " , %{ conn : conn } do
address = insert ( :address )
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number )
@ -365,10 +390,115 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
compare_item ( token_transfer , Enum . at ( response [ " items " ] , 0 ) )
end
test " method in token transer could be decoded " , %{ conn : conn } do
insert ( :contract_method ,
identifier : Base . decode16! ( " 731133e9 " , case : :lower ) ,
abi : %{
" constant " = > false ,
" inputs " = > [
%{ " name " = > " account " , " type " = > " address " } ,
%{ " name " = > " id " , " type " = > " uint256 " } ,
%{ " name " = > " amount " , " type " = > " uint256 " } ,
%{ " name " = > " data " , " type " = > " bytes " }
] ,
" name " = > " mint " ,
" outputs " = > [ ] ,
" payable " = > false ,
" stateMutability " = > " nonpayable " ,
" type " = > " function "
}
)
address = insert ( :address )
tx =
insert ( :transaction ,
input :
" 0x731133e9000000000000000000000000bb36c792b9b45aaf8b848a1392b0d6559202729e000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000 "
)
|> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number )
token_transfer =
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , from_address : address )
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /token-transfers " )
assert response = json_response ( request , 200 )
assert Enum . count ( response [ " items " ] ) == 1
assert response [ " next_page_params " ] == nil
compare_item ( token_transfer , Enum . at ( response [ " items " ] , 0 ) )
assert Enum . at ( response [ " items " ] , 0 ) [ " method " ] == " mint "
end
test " get relevant token transfer filtered by token " , %{ conn : conn } do
token = insert ( :token )
address = insert ( :address )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , from_address : address )
token_transfer =
insert ( :token_transfer ,
transaction : tx ,
block : tx . block ,
block_number : tx . block_number ,
from_address : address ,
token_contract_address : token . contract_address
)
request =
get ( conn , " /api/v2/addresses/ #{ address . hash } /token-transfers " , %{
" token " = > to_string ( token . contract_address )
} )
assert response = json_response ( request , 200 )
assert Enum . count ( response [ " items " ] ) == 1
assert response [ " next_page_params " ] == nil
compare_item ( token_transfer , Enum . at ( response [ " items " ] , 0 ) )
end
test " token transfers by token can paginate " , %{ conn : conn } do
address = insert ( :address )
token = insert ( :token )
token_tranfers =
for _ <- 0 . . 50 do
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , from_address : address )
insert ( :token_transfer ,
transaction : tx ,
block : tx . block ,
block_number : tx . block_number ,
from_address : address ,
token_contract_address : token . contract_address
)
end
params = %{ " token " = > to_string ( token . contract_address ) }
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /token-transfers " , params )
assert response = json_response ( request , 200 )
request_2nd_page =
get ( conn , " /api/v2/addresses/ #{ address . hash } /token-transfers " , Map . merge ( params , response [ " next_page_params " ] ) )
assert response_2nd_page = json_response ( request_2nd_page , 200 )
check_paginated_response ( response , response_2nd_page , token_tranfers )
end
test " get only :to token transfer " , %{ conn : conn } do
address = insert ( :address )
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , from_address : address )
@ -386,7 +516,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
test " get only :from token transfer " , %{ conn : conn } do
address = insert ( :address )
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
token_transfer =
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , from_address : address )
@ -405,7 +535,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
token_tranfers =
for _ <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , from_address : address )
end
@ -423,13 +553,13 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
address = insert ( :address )
for _ <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , from_address : address )
end
token_tranfers =
for _ <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , to_address : address )
end
@ -450,13 +580,13 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
token_tranfers =
for _ <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , from_address : address )
end
for _ <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , to_address : address )
end
@ -477,14 +607,14 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
tt_from =
for _ <- 0 . . 49 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , from_address : address )
end
tt_to =
for _ <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer , transaction : tx , block : tx . block , block_number : tx . block_number , to_address : address )
end
@ -518,7 +648,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
erc_20_tt =
for _ <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer ,
transaction : tx ,
@ -533,7 +663,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
erc_721_tt =
for x <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer ,
transaction : tx ,
@ -549,7 +679,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
erc_1155_tt =
for x <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer ,
transaction : tx ,
@ -643,7 +773,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
erc_20_tt =
for _ <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer ,
transaction : tx ,
@ -658,7 +788,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
erc_721_tt =
for x <- 0 . . 50 do
tx = insert ( :transaction ) |> with_block ( )
tx = insert ( :transaction , input : " 0xabcd010203040506 " ) |> with_block ( )
insert ( :token_transfer ,
transaction : tx ,
@ -717,9 +847,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /internal-transactions " )
assert response = json_response ( request , 200 )
assert response [ " items " ] == [ ]
assert response [ " next_page_params " ] == nil
assert %{ " message " = > " Not found " } = json_response ( request , 404 )
end
test " get 422 on invalid address " , %{ conn : conn } do
@ -864,9 +992,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /blocks-validated " )
assert response = json_response ( request , 200 )
assert response [ " items " ] == [ ]
assert response [ " next_page_params " ] == nil
assert %{ " message " = > " Not found " } = json_response ( request , 404 )
end
test " get 422 on invalid address " , %{ conn : conn } do
@ -910,8 +1036,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /token-balances " )
assert response = json_response ( request , 200 )
assert response == [ ]
assert %{ " message " = > " Not found " } = json_response ( request , 404 )
end
test " get 422 on invalid address " , %{ conn : conn } do
@ -945,9 +1070,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /coin-balance-history " )
assert response = json_response ( request , 200 )
assert response [ " items " ] == [ ]
assert response [ " next_page_params " ] == nil
assert %{ " message " = > " Not found " } = json_response ( request , 404 )
end
test " get 422 on invalid address " , %{ conn : conn } do
@ -994,8 +1117,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /coin-balance-history-by-day " )
assert response = json_response ( request , 200 )
assert response == [ ]
assert %{ " message " = > " Not found " } = json_response ( request , 404 )
end
test " get 422 on invalid address " , %{ conn : conn } do
@ -1032,9 +1154,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /logs " )
assert response = json_response ( request , 200 )
assert response [ " items " ] == [ ]
assert response [ " next_page_params " ] == nil
assert %{ " message " = > " Not found " } = json_response ( request , 404 )
end
test " get 422 on invalid address " , %{ conn : conn } do
@ -1136,6 +1256,129 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
end
end
describe " /addresses/{address_hash}/tokens " do
test " get empty list on non existing address " , %{ conn : conn } do
address = build ( :address )
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /tokens " )
assert %{ " message " = > " Not found " } = json_response ( request , 404 )
end
test " get 422 on invalid address " , %{ conn : conn } do
request = get ( conn , " /api/v2/addresses/0x/tokens " )
assert %{ " message " = > " Invalid parameter(s) " } = json_response ( request , 422 )
end
test " get tokens " , %{ conn : conn } do
address = insert ( :address )
ctbs_erc_20 =
for _ <- 0 . . 50 do
insert ( :address_current_token_balance_with_token_id , address : address , token_type : " ERC-20 " , token_id : nil )
|> Repo . preload ( [ :token ] )
end
|> Enum . sort_by ( fn x -> x . value end , :asc )
ctbs_erc_721 =
for _ <- 0 . . 50 do
insert ( :address_current_token_balance_with_token_id , address : address , token_type : " ERC-721 " , token_id : nil )
|> Repo . preload ( [ :token ] )
end
|> Enum . sort_by ( fn x -> x . value end , :asc )
ctbs_erc_1155 =
for _ <- 0 . . 50 do
insert ( :address_current_token_balance_with_token_id ,
address : address ,
token_type : " ERC-1155 " ,
token_id : Enum . random ( 1 . . 100_000 )
)
|> Repo . preload ( [ :token ] )
end
|> Enum . sort_by ( fn x -> x . value end , :asc )
filter = %{ " type " = > " ERC-20 " }
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /tokens " , filter )
assert response = json_response ( request , 200 )
request_2nd_page =
get ( conn , " /api/v2/addresses/ #{ address . hash } /tokens " , Map . merge ( response [ " next_page_params " ] , filter ) )
assert response_2nd_page = json_response ( request_2nd_page , 200 )
check_paginated_response ( response , response_2nd_page , ctbs_erc_20 )
filter = %{ " type " = > " ERC-721 " }
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /tokens " , filter )
assert response = json_response ( request , 200 )
request_2nd_page =
get ( conn , " /api/v2/addresses/ #{ address . hash } /tokens " , Map . merge ( response [ " next_page_params " ] , filter ) )
assert response_2nd_page = json_response ( request_2nd_page , 200 )
check_paginated_response ( response , response_2nd_page , ctbs_erc_721 )
filter = %{ " type " = > " ERC-1155 " }
request = get ( conn , " /api/v2/addresses/ #{ address . hash } /tokens " , filter )
assert response = json_response ( request , 200 )
request_2nd_page =
get ( conn , " /api/v2/addresses/ #{ address . hash } /tokens " , Map . merge ( response [ " next_page_params " ] , filter ) )
assert response_2nd_page = json_response ( request_2nd_page , 200 )
check_paginated_response ( response , response_2nd_page , ctbs_erc_1155 )
end
end
describe " /addresses " do
test " get empty list " , %{ conn : conn } do
request = get ( conn , " /api/v2/addresses " )
total_supply = to_string ( Chain . total_supply ( ) )
assert %{ " items " = > [ ] , " next_page_params " = > nil , " exchange_rate " = > nil , " total_supply " = > ^ total_supply } =
json_response ( request , 200 )
end
test " check pagination " , %{ conn : conn } do
addresses =
for i <- 0 . . 50 do
insert ( :address , nonce : i , fetched_coin_balance : i + 1 )
end
request = get ( conn , " /api/v2/addresses " )
assert response = json_response ( request , 200 )
request_2nd_page = get ( conn , " /api/v2/addresses " , response [ " next_page_params " ] )
assert response_2nd_page = json_response ( request_2nd_page , 200 )
check_paginated_response ( response , response_2nd_page , addresses )
assert Enum . at ( response [ " items " ] , 0 ) [ " coin_balance " ] ==
to_string ( Enum . at ( addresses , 50 ) . fetched_coin_balance . value )
end
test " check nil " , %{ conn : conn } do
address = insert ( :address , nonce : 1 , fetched_coin_balance : 1 )
request = get ( conn , " /api/v2/addresses " )
assert %{ " items " = > [ address_json ] , " next_page_params " = > nil } = json_response ( request , 200 )
compare_item ( address , address_json )
end
end
defp compare_item ( % Address { } = address , json ) do
assert Address . checksum ( address . hash ) == json [ " hash " ]
assert to_string ( address . nonce + 1 ) == json [ " tx_count " ]
end
defp compare_item ( % Transaction { } = transaction , json ) do
assert to_string ( transaction . hash ) == json [ " hash " ]
assert transaction . block_number == json [ " block " ]
@ -1148,6 +1391,10 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
assert Address . checksum ( token_transfer . from_address_hash ) == json [ " from " ] [ " hash " ]
assert Address . checksum ( token_transfer . to_address_hash ) == json [ " to " ] [ " hash " ]
assert to_string ( token_transfer . transaction_hash ) == json [ " tx_hash " ]
assert json [ " timestamp " ] != nil
assert json [ " method " ] != nil
assert to_string ( token_transfer . block_hash ) == json [ " block_hash " ]
assert to_string ( token_transfer . log_index ) == json [ " log_index " ]
end
defp compare_item ( % InternalTransaction { } = internal_tx , json ) do
@ -1189,9 +1436,10 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
end
defp compare_item ( % Log { } = log , json ) do
assert to_string ( log . data ) == json [ " data " ]
assert log . index == json [ " index " ]
assert to_string ( log . data ) == json [ " data " ]
assert Address . checksum ( log . address_hash ) == json [ " address " ] [ " hash " ]
assert to_string ( log . transaction_hash ) == json [ " tx_hash " ]
end
defp check_paginated_response ( first_page_resp , second_page_resp , list ) do