Skip to content

Commit

Permalink
variant
Browse files Browse the repository at this point in the history
  • Loading branch information
efcasado committed May 11, 2024
1 parent 45e0576 commit 84065d2
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 18 deletions.
21 changes: 21 additions & 0 deletions lib/uof/api/descriptions/market.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,27 @@ defmodule UOF.API.Descriptions.Market do
end
end

@doc """
"""
def variant(market, variant, include_mappings? \\ false, lang \\ "en") do
case UOF.API.get("/descriptions/#{lang}/markets/#{market}/variants/#{variant}",
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
Expand Down
138 changes: 138 additions & 0 deletions lib/uof/api/descriptions/variant.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
defmodule UOF.API.Descriptions.Variant do
@moduledoc """
"""
use Ecto.Schema
import Ecto.Changeset
import UOF.API.EctoHelpers

@doc """
List all variants.
"""
@spec all(lang :: String.t()) :: list(Variant.t())
def all(lang \\ "en") do
case UOF.API.get("/descriptions/#{lang}/variants.xml") do
{:ok, %_{status: 200, body: resp}} ->
resp
|> Map.get("variant_descriptions")
|> Map.get("variant")
|> Enum.map(fn x ->
{:ok, x} = changeset(x)
x
end)

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

@primary_key false

embedded_schema do
field(:id, :string)

embeds_many :outcomes, Outcome, primary_key: false do
field(:id, :string)
field(:name, :string)
end

embeds_many :mappings, Mapping, primary_key: false do
field(:product_id, :integer)
field(:product_ids, {:array, :integer})
field(:sport_id, :string)
field(:market_id, :integer)
field(:product_market_id, :string)

embeds_many :outcome_mappings, OutcomeMapping, primary_key: false do
field(:outcome_id, :string)
field(:product_outcome_id, :integer)
field(:product_outcome_name, :string)
end
end
end

def changeset(model \\ %__MODULE__{}, params) do
params = prepare(params)

model
|> cast(params, [:id])
|> cast_embed(:outcomes, with: &outcome_changeset/2)
|> cast_embed(:mappings, with: &mapping_changeset/2)
|> apply
end

defp prepare(params) do
params
|> rename_fields
|> prepare_outcomes
|> prepare_mappings
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_mappings(params) do
mappings =
params
|> Map.get("mappings", %{})
|> Map.get("mapping", [])

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

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

def outcome_changeset(model, params) do
params = prepare_outcome(params)

model
|> cast(params, [:id, :name])
end

def prepare_outcome(params) do
params
|> rename_fields
end

def mapping_changeset(model, params) do
params = prepare_mapping(params)

model
|> cast(params, [:product_id, :product_ids, :sport_id, :market_id, :product_market_id])
|> cast_embed(:outcome_mappings, with: &outcome_mapping_changeset/2)
end

def prepare_mapping(params) do
params
|> rename_fields
|> split("product_ids", "|")
|> rename("mapping_outcome", "outcome_mappings", [])
end

def outcome_mapping_changeset(model, params) do
params = prepare_outcome_mapping(params)

model
|> cast(params, [:outcome_id, :product_outcome_id, :product_outcome_name])
end

def prepare_outcome_mapping(params) do
params
|> rename_fields
end
end
19 changes: 19 additions & 0 deletions lib/uof/api/ecto_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,23 @@ defmodule UOF.API.EctoHelpers do
end)
|> Map.new()
end

def split(params, field, separator) do
values = Map.get(params, field)
values = String.split(values, separator)
Map.put(params, field, values)
end

def rename(params, old, new, default) do
{values, params} = Map.pop(params, old, default)
Map.put(params, new, values)
end

def apply(%Ecto.Changeset{valid?: true} = changeset) do
{:ok, apply_changes(changeset)}
end

def apply(%Ecto.Changeset{} = changeset) do
{:error, traverse_errors(changeset)}
end
end
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
defmodule UOF.API.Descriptions.Test do
defmodule UOF.API.Descriptions.Variant.Test do
use ExUnit.Case
import Mock

# mock http requests towards Betradar and use recorded responses instead
setup_with_mocks([
{UOF.API.Utils.HTTP, [:passthrough],
[
get: fn schema, endpoint ->
data = File.read!("test/data/" <> Enum.at(endpoint, -1))
Saxaboom.parse(data, schema)
end
]}
]) do
setup do
:ok = Application.put_env(:tesla, UOF.API, adapter: Tesla.Mock)

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

:ok
end

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

assert Enum.count(desc.variants) == 144
variant = hd(desc.variants)
assert Enum.count(resp) == 144
variant = hd(resp)
assert variant.id == "sr:correct_score:after:4"
assert Enum.count(variant.outcomes) == 5
outcome = hd(variant.outcomes)
Expand All @@ -28,14 +26,14 @@ defmodule UOF.API.Descriptions.Test do
assert Enum.count(variant.mappings) == 1
mapping = hd(variant.mappings)
assert mapping.product_id == 3
assert mapping.product_ids == "3"
assert mapping.product_ids == [3]
assert mapping.sport_id == "sr:sport:22"
assert mapping.market_id == 1262
assert mapping.product_market_id == "960"
assert Enum.count(mapping.outcome_mappings) == 5
outcome_mapping = hd(mapping.outcome_mappings)
assert outcome_mapping.outcome_id == "sr:correct_score:after:4:1530"
assert outcome_mapping.product_outcome_id == "26"
assert outcome_mapping.product_outcome_id == 26
assert outcome_mapping.product_outcome_name == "4:0"
end
end

0 comments on commit 84065d2

Please sign in to comment.