diff --git a/lib/uof/api/mappings/sport_categories.ex b/lib/uof/api/mappings/sport_categories.ex deleted file mode 100644 index 6ea1812..0000000 --- a/lib/uof/api/mappings/sport_categories.ex +++ /dev/null @@ -1,11 +0,0 @@ -defmodule UOF.API.Mappings.SportCategories do - @moduledoc false - use Saxaboom.Mapper - - alias UOF.API.Mappings.{Category, Sport} - - document do - element(:sport, into: %Sport{}) - elements(:category, as: :categories, into: %Category{}) - end -end diff --git a/lib/uof/api/sports.ex b/lib/uof/api/sports.ex index c564424..c45a213 100644 --- a/lib/uof/api/sports.ex +++ b/lib/uof/api/sports.ex @@ -139,15 +139,6 @@ defmodule UOF.API.Sports do HTTP.get(%UOF.API.Mappings.Sports{}, endpoint) end - @doc """ - List all the available categories for the given sport. - """ - def categories(sport, lang \\ "en") do - endpoint = ["sports", lang, "sports", sport, "categories.xml"] - - HTTP.get(%UOF.API.Mappings.SportCategories{}, endpoint) - end - def tournaments(lang \\ "en") do endpoint = ["sports", lang, "tournaments.xml"] diff --git a/lib/uof/api/sports/category.ex b/lib/uof/api/sports/category.ex new file mode 100644 index 0000000..976dcd7 --- /dev/null +++ b/lib/uof/api/sports/category.ex @@ -0,0 +1,85 @@ +# https://docs.betradar.com/pages/viewpage.action?pageId=116065083 +defmodule UOF.API.Sports.Category do + @moduledoc """ + Categories are a generic classification term Betradar uses to subclassify a + particular sport (e.g. for Tennis the categories can be ATP-Tour, WTA-Tour, + David Cup, etc., for soccer the categories are the various countries). + """ + use Ecto.Schema + import Ecto.Changeset + import UOF.API.EctoHelpers + + @doc """ + List all the available categories for the given sport. + """ + @spec by_sport(sport :: String.t(), lang :: String.t()) :: list(__MODULE__.t()) + def by_sport(sport, lang \\ "en") do + case UOF.API.get("/sports/#{lang}/sports/#{sport}/categories.xml") do + {:ok, %_{status: 200, body: resp}} -> + resp + |> Map.get("sport_categories") + |> changeset + + {:error, _} = error -> + error + end + end + + @type sport :: %UOF.API.Sports.Category.Sport{ + id: String.t(), + name: String.t() + } + + @type category :: %UOF.API.Sports.Category.Category{ + id: String.t(), + name: String.t(), + country_code: String.t() + } + + @type t :: %__MODULE__{ + sport: sport(), + categories: list(category()) + } + + @primary_key false + + embedded_schema do + embeds_one :sport, Sport, primary_key: false do + field :id, :string + field :name, :string + end + + embeds_many :categories, Category, primary_key: false do + field :id, :string + field :name, :string + field :country_code, :string + end + end + + @doc false + def changeset(model \\ %__MODULE__{}, params) + + def changeset(%__MODULE__{} = model, params) do + params = bubble_up(params, "categories", "category") + + model + |> cast(params, []) + |> cast_embed(:sport, with: &changeset/2) + |> cast_embed(:categories, with: &changeset/2) + |> apply + end + + def changeset(%UOF.API.Sports.Category.Sport{} = model, params) do + params = sanitize(params) + + model + |> cast(params, [:id, :name]) + end + + def changeset(%UOF.API.Sports.Category.Category{} = model, params) do + params = sanitize(params) + + model + |> cast(params, [:id, :name, :country_code]) + end +end diff --git a/test/uof/api/sports/category_test.exs b/test/uof/api/sports/category_test.exs new file mode 100644 index 0000000..9b9a08e --- /dev/null +++ b/test/uof/api/sports/category_test.exs @@ -0,0 +1,31 @@ +defmodule UOF.API.Sports.Category.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/categories.xml") + %Tesla.Env{status: 200, headers: [{"content-type", "application/xml"}], body: resp} + end) + + :ok + end + + test "can parse UOF.API.Sports.Category.by_sport/{1, 2} response" do + {:ok, sport_categories} = UOF.API.Sports.Category.by_sport("sr:sport:1") + + # sport + sport = sport_categories.sport + assert sport.id == "sr:sport:1" + assert sport.name == "Soccer" + # categories + categories = sport_categories.categories + category = hd(categories) + assert Enum.count(categories) == 224 + assert category.id == "sr:category:1" + assert category.name == "England" + assert category.country_code == "ENG" + end +end diff --git a/test/uof/api/sports_test.exs b/test/uof/api/sports_test.exs index c9b8641..7842346 100644 --- a/test/uof/api/sports_test.exs +++ b/test/uof/api/sports_test.exs @@ -35,10 +35,6 @@ defmodule UOF.API.Sports.Test do {:ok, File.read!("test/data/timeline.xml")} end - defp fetch_mock_data(["sports", _lang, "sports", _sport, "categories.xml"]) do - {:ok, File.read!("test/data/categories.xml")} - end - defp fetch_mock_data(["sports", _lang, "tournaments.xml"]) do {:ok, File.read!("test/data/tournaments.xml")} end @@ -422,22 +418,6 @@ defmodule UOF.API.Sports.Test do assert match_ended_event.match_clock == "60:00" end - test "can parse UOF.API.Sports.categories/{1, 2} response" do - {:ok, sport_categories} = UOF.API.Sports.categories("sr:sport:1") - - # sport - sport = sport_categories.sport - assert sport.id == "sr:sport:1" - assert sport.name == "Soccer" - # categories - categories = sport_categories.categories - category = hd(categories) - assert Enum.count(categories) == 224 - assert category.id == "sr:category:1" - assert category.name == "England" - assert category.country_code == "ENG" - end - test "can parse UOF.API.Sports.tournaments/{0, 1} response" do {:ok, data} = UOF.API.Sports.tournaments()