Skip to content

Commit

Permalink
markets
Browse files Browse the repository at this point in the history
  • Loading branch information
efcasado committed May 11, 2024
1 parent 14e6794 commit 147387b
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 48 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ erl_crash.dump
hex.config
*.ez
uof_messages-*.tar
*~
*~
\#*
.\#*
10 changes: 0 additions & 10 deletions lib/uof/api/descriptions.ex
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
defmodule UOF.API.Descriptions do
alias UOF.API.Utils.HTTP

@doc """
Describe all currently available markets.
"""
def markets(lang \\ "en") do
# TO-DO: Optional mappings
endpoint = ["descriptions", lang, "markets.xml"]

HTTP.get(%UOF.API.Mappings.MarketDescriptions{}, endpoint)
end

@doc """
Get a list of all variants and which markets they are used for.
"""
Expand Down
147 changes: 147 additions & 0 deletions lib/uof/api/descriptions/market.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
defmodule UOF.API.Descriptions.Market do
@moduledoc """
"""
use Ecto.Schema
import Ecto.Changeset
import UOF.API.EctoHelpers

@doc """
List all supported markets.
"""
@spec all(include_mappings? :: boolean(), lang :: String.t()) :: list(Market.t())
def all(include_mappings? \\ false, lang \\ "en") do
case UOF.API.get("/descriptions/#{lang}/markets.xml",
query: [include_mappings: include_mappings?]
) do
{:ok, %_{status: 200, body: resp}} ->
resp
|> Map.get("market_descriptions")
|> Map.get("market")
|> Enum.map(fn x ->
{:ok, x} = changeset(x)
x
end)

{:error, _} = error ->
error
end
end

defmodule Outcome do
@moduledoc false
use Ecto.Schema
import Ecto.Changeset
import UOF.API.EctoHelpers

@primary_key false

embedded_schema do
field(:id, :integer)
field(:name, :string)
end

def changeset(model \\ %__MODULE__{}, params) do
cast(model, prepare(params), [:id, :name])
end

defp prepare(params) do
params
|> rename_fields
end
end

defmodule Specifier do
@moduledoc false
use Ecto.Schema
import Ecto.Changeset
import UOF.API.EctoHelpers

@primary_key false

embedded_schema do
# ["decimal", "integer", "string", "variable_text"]
field(:type, :string)
field(:name, :string)
end

def changeset(model \\ %__MODULE__{}, params) do
cast(model, prepare(params), [:name, :type])
end

defp prepare(params) do
params
|> rename_fields
end
end

@primary_key false

embedded_schema do
field(:id, :integer)
field(:name, :string)
field(:groups, {:array, :string})
# ["player", "competitor", "free_text"]
field(:outcome_type, :string)
field(:includes_outcomes_of_type, :string)
embeds_many(:outcomes, Outcome)
embeds_many(:specifiers, Specifier)
# TO-DO: embeds_many(:mappings, Mapping)
end

def changeset(model \\ %__MODULE__{}, params) do
model
|> cast(prepare(params), [:id, :name, :groups, :outcome_type, :includes_outcomes_of_type])
|> cast_embed(:outcomes)
|> cast_embed(:specifiers)
|> case do
%Ecto.Changeset{valid?: true} = changeset ->
{:ok, apply_changes(changeset)}

%Ecto.Changeset{} = changeset ->
{:error, {params, traverse_errors(changeset)}}
end
end

defp prepare(params) do
params
|> rename_fields
|> prepare_outcomes
|> prepare_specifiers
|> split_groups
end

defp prepare_outcomes(params) do
outcomes =
params
|> Map.get("outcomes", %{})
|> Map.get("outcome", [])

case outcomes do
outcome when not is_list(outcome) ->
Map.put(params, "outcomes", [outcome])

_ ->
Map.put(params, "outcomes", outcomes)
end
end

defp prepare_specifiers(params) do
specifiers =
params
|> Map.get("specifiers", %{})
|> Map.get("specifier", [])

case specifiers do
specifier when not is_list(specifier) ->
Map.put(params, "specifiers", [specifier])

_ ->
Map.put(params, "specifiers", specifiers)
end
end

defp split_groups(params) do
scope = String.split(params["groups"], "|")
Map.put(params, "groups", scope)
end
end
15 changes: 0 additions & 15 deletions lib/uof/api/mappings/market.ex

This file was deleted.

10 changes: 0 additions & 10 deletions lib/uof/api/mappings/market_descriptions.ex

This file was deleted.

25 changes: 25 additions & 0 deletions test/uof/api/descriptions/market_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defmodule UOF.API.Descriptions.Market.Test do
use ExUnit.Case

setup do
:ok = Application.put_env(:tesla, UOF.API, adapter: Tesla.Mock)

Tesla.Mock.mock(fn
%{method: :get} ->
resp = File.read!("test/data/markets.xml")
%Tesla.Env{status: 200, headers: [{"content-type", "application/xml"}], body: resp}
end)

:ok
end

test "can parse UOF.API.Descriptions.Market.all/0 response" do
resp = UOF.API.Descriptions.Market.all()

assert Enum.count(resp) == 1172
assert hd(resp).id == 282
assert hd(resp).name == "Innings 1 to 5th top - {$competitor1} total"
assert hd(resp).groups == ["all", "score", "4.5_innings"]
assert Enum.map(hd(resp).outcomes, & &1.id) == [13, 12]
end
end
12 changes: 0 additions & 12 deletions test/uof/api/descriptions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,6 @@ defmodule UOF.API.Descriptions.Test do
:ok
end

test "can parse UOF.API.Descriptions.markets/{0, 1} response" do
{:ok, desc} = UOF.API.Descriptions.markets()

market = hd(desc.markets)

assert Enum.count(desc.markets) == 1172
assert market.id == 282
assert market.name == "Innings 1 to 5th top - {$competitor1} total"
assert market.groups == "all|score|4.5_innings"
assert Enum.map(market.outcomes, & &1.id) == ["13", "12"]
end

test "can parse UOF.API.Descriptions.variants/{0, 1} response" do
{:ok, desc} = UOF.API.Descriptions.variants()

Expand Down

0 comments on commit 147387b

Please sign in to comment.