Use lookup instead of filtering the list to get a symbol’s exchange rate

pull/173/head
Tim Mecklem 7 years ago
parent 7e03c940e7
commit 36d0fa2360
  1. 13
      apps/explorer/lib/explorer/exchange_rates/exchange_rates.ex
  2. 7
      apps/explorer/lib/explorer/market/market.ex
  3. 19
      apps/explorer/test/explorer/exchange_rates/exchange_rates_test.exs
  4. 37
      apps/explorer/test/explorer/market/market_test.exs
  5. 2
      apps/explorer_web/lib/explorer_web/controllers/chain_controller.ex

@ -90,6 +90,19 @@ defmodule Explorer.ExchangeRates do
list_from_store(store())
end
@doc """
Returns a specific rate from the tracked tickers by symbol
"""
@spec lookup(String.t()) :: Token.t()
def lookup(symbol) do
if store() == :ets do
case :ets.lookup(table_name(), symbol) do
[{_key, token} | _] -> token
_ -> nil
end
end
end
## Undocumented public functions
@doc false

@ -12,10 +12,9 @@ defmodule Explorer.Market do
@doc """
Get most recent exchange rate for the given symbol.
"""
@spec fetch_exchange_rate(String.t()) :: Token.t()
def fetch_exchange_rate(symbol) do
ExchangeRates.list()
|> Enum.find(fn token -> token.symbol == symbol end)
@spec get_exchange_rate(String.t()) :: Token.t()
def get_exchange_rate(symbol) do
ExchangeRates.lookup(symbol)
end
@doc """

@ -97,13 +97,26 @@ defmodule Explorer.ExchangeRatesTest do
ExchangeRates.init([])
rates = [
%Token{id: "z", symbol: "z"},
%Token{id: "a", symbol: "a"}
%Token{symbol: "z"},
%Token{symbol: "a"}
]
expected_rates = Enum.reverse(rates)
for rate <- rates, do: :ets.insert(ExchangeRates.table_name(), {rate.id, rate})
for rate <- rates, do: :ets.insert(ExchangeRates.table_name(), {rate.symbol, rate})
assert expected_rates == ExchangeRates.list()
end
test "lookup/1" do
ExchangeRates.init([])
z = %Token{symbol: "z"}
rates = [z, %Token{symbol: "a"}]
for rate <- rates, do: :ets.insert(ExchangeRates.table_name(), {rate.symbol, rate})
assert z == ExchangeRates.lookup("z")
assert nil == ExchangeRates.lookup("nope")
end
end

@ -1,31 +1,10 @@
defmodule Explorer.MarketTest do
use Explorer.DataCase
alias Explorer.ExchangeRates
alias Explorer.ExchangeRates.Token
alias Explorer.Market
alias Explorer.Market.MarketHistory
alias Explorer.Repo
describe "fetch_exchange_rate/1" do
setup do
use_ets_store()
{:ok, _} = ExchangeRates.start_link([])
rate = %Token{id: "POA", symbol: "POA"}
:ets.insert(ExchangeRates.table_name(), {rate.id, rate})
{:ok, %{rate: rate}}
end
test "with matching symbol", %{rate: rate} do
assert Market.fetch_exchange_rate("POA") == rate
end
test "with no matching symbol" do
assert Market.fetch_exchange_rate("ETH") == nil
end
end
test "fetch_recent_history/1" do
today = Date.utc_today()
@ -105,20 +84,4 @@ defmodule Explorer.MarketTest do
assert fetched_record.opening_price == new_record.opening_price
end
end
defp use_ets_store do
# Use ets tables as ExchangeRates store and put some test data in to
# exercise Context filtering
exchange_config = Application.get_env(:explorer, Explorer.ExchangeRates)
Application.put_env(
:explorer,
Explorer.ExchangeRates,
Keyword.put(exchange_config, :store, :ets)
)
on_exit(fn ->
Application.put_env(:explorer, Explorer.ExchangeRates, exchange_config)
end)
end
end

@ -12,7 +12,7 @@ defmodule ExplorerWeb.ChainController do
"show.html",
chain: Statistics.fetch(),
market_history_data: Market.fetch_recent_history(30),
exchange_rate: Market.fetch_exchange_rate(coin()) || Token.null()
exchange_rate: Market.get_exchange_rate(coin()) || Token.null()
)
end

Loading…
Cancel
Save