From a514f3f5b974193e324d3020b95c781b5941ee3a Mon Sep 17 00:00:00 2001 From: Stamates Date: Thu, 6 Sep 2018 11:27:14 -0400 Subject: [PATCH] Consolidate address rendering view function and partials --- .../templates/address/_link.html.eex | 6 +- .../templates/transaction/_tile.html.eex | 8 +- .../transaction/_token_transfer.html.eex | 4 +- .../templates/transaction/overview.html.eex | 4 +- .../lib/block_scout_web/views/address_view.ex | 80 ++++++++++------ .../block_scout_web/views/transaction_view.ex | 92 +++++++++---------- .../views/address_view_test.exs | 45 +++++++++ 7 files changed, 150 insertions(+), 89 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex index 8c8490a69a..463d3ba5ba 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex @@ -1,5 +1,3 @@ -<%= if @address_hash do %> - <%= link to: address_path(BlockScoutWeb.Endpoint, :show, @address_hash), "data-test": "address_hash_link" do %> - <%= render BlockScoutWeb.AddressView, "_responsive_hash.html", address_hash: @address_hash, contract: @contract, truncate: assigns[:truncate] %> - <% end %> +<%= link to: address_path(BlockScoutWeb.Endpoint, :show, @address_hash), "data-test": "address_hash_link" do %> + <%= render BlockScoutWeb.AddressView, "_responsive_hash.html", address_hash: @address_hash, contract: @contract, truncate: assigns[:truncate] %> <% end %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction/_tile.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction/_tile.html.eex index ce506dbcfb..6752ea9d77 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/transaction/_tile.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction/_tile.html.eex @@ -11,13 +11,9 @@
<%= render "_link.html", transaction_hash: @transaction.hash %> - <%= BlockScoutWeb.AddressView.display_address_hash(assigns[:current_address], @transaction.from_address) %> + <%= BlockScoutWeb.AddressView.display_address_hash(assigns[:current_address], @transaction, :from) %> → - <%= if assigns[:current_address] && assigns[:current_address].hash == to_address_hash(@transaction) do %> - <%= render BlockScoutWeb.AddressView, "_responsive_hash.html", address_hash: to_address_hash(@transaction), contract: BlockScoutWeb.AddressView.contract?(@transaction.to_address) %> - <% else %> - <%= render BlockScoutWeb.AddressView, "_link.html", address_hash: to_address_hash(@transaction), contract: BlockScoutWeb.AddressView.contract?(@transaction.to_address) %> - <% end %> + <%= BlockScoutWeb.AddressView.display_address_hash(assigns[:current_address], @transaction, :to) %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction/_token_transfer.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction/_token_transfer.html.eex index 538dab337f..11ad54a146 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/transaction/_token_transfer.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction/_token_transfer.html.eex @@ -11,9 +11,9 @@ <% end %> <% end %> - <%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer.from_address, true) %> + <%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer, :from, true) %> → - <%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer.to_address, true) %> + <%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer, :to, true) %> <%= token_transfer_amount(@token_transfer) %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex index c7255dfe82..180aa6cb86 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex @@ -15,9 +15,9 @@

<%= gettext "Transaction Details" %>

<%= @transaction %>

- <%= BlockScoutWeb.AddressView.display_address_hash(assigns[:current_address], @transaction.from_address) %> + <%= BlockScoutWeb.AddressView.display_address_hash(nil, @transaction, :from) %> - <%= BlockScoutWeb.AddressView.display_address_hash(assigns[:current_address], @transaction.to_address) %> + <%= BlockScoutWeb.AddressView.display_address_hash(nil, @transaction, :to) %>
<%= BlockScoutWeb.TransactionView.transaction_display_type(@transaction) %> diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_view.ex index a35ce8d907..9d88532d95 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/address_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/address_view.ex @@ -1,7 +1,7 @@ defmodule BlockScoutWeb.AddressView do use BlockScoutWeb, :view - alias Explorer.Chain.{Address, Hash, SmartContract} + alias Explorer.Chain.{Address, Hash, SmartContract, TokenTransfer, Transaction} @dialyzer :no_match @@ -34,35 +34,30 @@ defmodule BlockScoutWeb.AddressView do def contract?(nil), do: true - def display_address_hash(current_address, target_address, truncate \\ false) + def display_address_hash(current_address, struct_to_render_from, direction, truncate \\ false) - def display_address_hash(nil, nil, _truncate), do: gettext("Contract Address Pending") + def display_address_hash(current_address, %TokenTransfer{to_address: address}, :to, truncate) do + display_hash(current_address, address.hash, contract?(address), truncate) + end - def display_address_hash(nil, target_address, truncate) do - render( - "_link.html", - address_hash: target_address.hash, - contract: contract?(target_address), - truncate: truncate - ) + def display_address_hash(current_address, %TokenTransfer{from_address: address}, :from, truncate) do + display_hash(current_address, address.hash, contract?(address), truncate) end - def display_address_hash(current_address, target_address, truncate) do - if current_address.hash == target_address.hash do - render( - "_responsive_hash.html", - address_hash: current_address.hash, - contract: contract?(current_address), - truncate: truncate - ) - else - render( - "_link.html", - address_hash: target_address.hash, - contract: contract?(target_address), - truncate: truncate - ) - end + def display_address_hash(_current_address, %Transaction{to_address_hash: nil, created_contract_address_hash: nil}, :to, _truncate) do + gettext("Contract Address Pending") + end + + def display_address_hash(current_address, %Transaction{to_address_hash: nil, created_contract_address_hash: hash}, :to, truncate) do + display_hash(current_address, hash, true, truncate) + end + + def display_address_hash(current_address, %Transaction{to_address: address}, :to, truncate) do + display_hash(current_address, address.hash, contract?(address), truncate) + end + + def display_address_hash(current_address, %Transaction{from_address: address}, :from, truncate) do + display_hash(current_address, address.hash, contract?(address), truncate) end def hash(%Address{hash: hash}) do @@ -80,6 +75,12 @@ defmodule BlockScoutWeb.AddressView do def smart_contract_verified?(%Address{smart_contract: nil}), do: false + def smart_contract_with_read_only_functions?(%Address{smart_contract: %SmartContract{}} = address) do + Enum.any?(address.smart_contract.abi, & &1["constant"]) + end + + def smart_contract_with_read_only_functions?(%Address{smart_contract: nil}), do: false + def trimmed_hash(%Hash{} = hash) do string_hash = to_string(hash) "#{String.slice(string_hash, 0..5)}–#{String.slice(string_hash, -6..-1)}" @@ -87,9 +88,30 @@ defmodule BlockScoutWeb.AddressView do def trimmed_hash(_), do: "" - def smart_contract_with_read_only_functions?(%Address{smart_contract: %SmartContract{}} = address) do - Enum.any?(address.smart_contract.abi, & &1["constant"]) + defp display_hash(nil, hash, contract?, truncate) do + render( + "_link.html", + address_hash: hash, + contract: contract?, + truncate: truncate + ) end - def smart_contract_with_read_only_functions?(%Address{smart_contract: nil}), do: false + defp display_hash(current_address, hash, contract?, truncate) do + if current_address.hash == hash do + render( + "_responsive_hash.html", + address_hash: hash, + contract: contract?, + truncate: truncate + ) + else + render( + "_link.html", + address_hash: hash, + contract: contract?, + truncate: truncate + ) + end + end end diff --git a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex index 402352dd95..05f79f9f6e 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex @@ -10,6 +10,8 @@ defmodule BlockScoutWeb.TransactionView do defguardp is_transaction_type(mod) when mod in [InternalTransaction, Transaction] + defdelegate formatted_timestamp(block), to: BlockView + def confirmations(%Transaction{block: block}, named_arguments) when is_list(named_arguments) do case block do nil -> 0 @@ -17,22 +19,19 @@ defmodule BlockScoutWeb.TransactionView do end end - def from_or_to_address?(_token_transfer, nil), do: false - - def from_or_to_address?(%{from_address_hash: from_hash, to_address_hash: to_hash}, %Address{hash: hash}) do - from_hash == hash || to_hash == hash - end - - # This is the address to be shown in the to field - def to_address_hash(%Transaction{to_address_hash: nil, created_contract_address_hash: address_hash}), do: address_hash + def contract_creation?(%Transaction{to_address: nil}), do: true - def to_address_hash(%Transaction{to_address: %Address{hash: address_hash}}), do: address_hash + def contract_creation?(_), do: false def fee(%Transaction{} = transaction) do {_, value} = Chain.fee(transaction, :wei) value end + def format_gas_limit(gas) do + Number.to_string!(gas) + end + def formatted_fee(%Transaction{} = transaction, opts) do transaction |> Chain.fee(:wei) @@ -43,34 +42,6 @@ defmodule BlockScoutWeb.TransactionView do end end - def gas_used(%Transaction{gas_used: nil}), do: gettext("Pending") - - def gas_used(%Transaction{gas_used: gas_used}) do - Number.to_string!(gas_used) - end - - def involves_contract?(%Transaction{from_address: from_address, to_address: to_address}) do - AddressView.contract?(from_address) || AddressView.contract?(to_address) - end - - def involves_token_transfers?(%Transaction{token_transfers: []}), do: false - def involves_token_transfers?(%Transaction{token_transfers: transfers}) when is_list(transfers), do: true - - def contract_creation?(%Transaction{to_address: nil}), do: true - - def contract_creation?(_), do: false - - def qr_code(%Transaction{hash: hash}) do - hash - |> to_string() - |> QRCode.to_png() - |> Base.encode64() - end - - def format_gas_limit(gas) do - Number.to_string!(gas) - end - def formatted_status(transaction) do transaction |> Chain.transaction_to_status() @@ -82,7 +53,11 @@ defmodule BlockScoutWeb.TransactionView do end end - defdelegate formatted_timestamp(block), to: BlockView + def from_or_to_address?(_token_transfer, nil), do: false + + def from_or_to_address?(%{from_address_hash: from_hash, to_address_hash: to_hash}, %Address{hash: hash}) do + from_hash == hash || to_hash == hash + end def gas(%type{gas: gas}) when is_transaction_type(type) do Cldr.Number.to_string!(gas) @@ -95,22 +70,38 @@ defmodule BlockScoutWeb.TransactionView do format_wei_value(gas_price, unit) end + def gas_used(%Transaction{gas_used: nil}), do: gettext("Pending") + + def gas_used(%Transaction{gas_used: gas_used}) do + Number.to_string!(gas_used) + end + def hash(%Transaction{hash: hash}) do to_string(hash) end + def involves_contract?(%Transaction{from_address: from_address, to_address: to_address}) do + AddressView.contract?(from_address) || AddressView.contract?(to_address) + end + + def involves_token_transfers?(%Transaction{token_transfers: []}), do: false + def involves_token_transfers?(%Transaction{token_transfers: transfers}) when is_list(transfers), do: true + + def qr_code(%Transaction{hash: hash}) do + hash + |> to_string() + |> QRCode.to_png() + |> Base.encode64() + end + def status(transaction) do Chain.transaction_to_status(transaction) end - def type_suffix(%Transaction{} = transaction) do - cond do - involves_token_transfers?(transaction) -> "token-transfer" - contract_creation?(transaction) -> "contract-creation" - involves_contract?(transaction) -> "contract-call" - true -> "transaction" - end - end + # This is the address to be shown in the to field + def to_address_hash(%Transaction{to_address_hash: nil, created_contract_address_hash: address_hash}), do: address_hash |> IO.inspect + + def to_address_hash(%Transaction{to_address: %Address{hash: address_hash}}), do: address_hash def transaction_display_type(%Transaction{} = transaction) do cond do @@ -121,6 +112,15 @@ defmodule BlockScoutWeb.TransactionView do end end + def type_suffix(%Transaction{} = transaction) do + cond do + involves_token_transfers?(transaction) -> "token-transfer" + contract_creation?(transaction) -> "contract-creation" + involves_contract?(transaction) -> "contract-call" + true -> "transaction" + end + end + @doc """ Converts a transaction's Wei value to Ether and returns a formatted display value. diff --git a/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs index 7ba5c71171..310edc23d3 100644 --- a/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/address_view_test.exs @@ -15,6 +15,51 @@ defmodule BlockScoutWeb.AddressViewTest do address = insert(:address, contract_code: nil) refute AddressView.contract?(address) end + + test "with nil address" do + assert AddressView.contract?(nil) + end + end + + describe "display_address_hash/3" do + test "for a pending contract creation to address" do + transaction = insert(:transaction, to_address: nil, created_contract_address_hash: nil) + assert AddressView.display_address_hash(nil, transaction, :to) == "Contract Address Pending" + end + + test "for a non-contract to address not on address page" do + transaction = insert(:transaction) + rendered_string = + nil + |> AddressView.display_address_hash(transaction, :to) + |> Phoenix.HTML.safe_to_string() + assert rendered_string =~ "responsive_hash" + assert rendered_string =~ "address_hash_link" + refute rendered_string =~ "contract-address" + end + + test "for a non-contract to address non matching address page" do + transaction = insert(:transaction) + rendered_string = + :address + |> insert() + |> AddressView.display_address_hash(transaction, :to) + |> Phoenix.HTML.safe_to_string() + assert rendered_string =~ "responsive_hash" + assert rendered_string =~ "address_hash_link" + refute rendered_string =~ "contract-address" + end + + test "for a non-contract to address matching address page" do + transaction = insert(:transaction) + rendered_string = + transaction.to_address + |> AddressView.display_address_hash(transaction, :to) + |> Phoenix.HTML.safe_to_string() + assert rendered_string =~ "responsive_hash" + refute rendered_string =~ "address_hash_link" + refute rendered_string =~ "contract-address" + end end describe "qr_code/1" do