diff --git a/config/test.exs b/config/test.exs index 195cda9..37b361c 100644 --- a/config/test.exs +++ b/config/test.exs @@ -6,7 +6,7 @@ import Config # to provide built-in test partitioning in CI environment. # Run `mix help test` for more information. config :boardwise, BoardWise.Repo, - username: "postgres", + username: "jrpotter", password: "postgres", hostname: "localhost", database: "boardwise_test#{System.get_env("MIX_TEST_PARTITION")}", diff --git a/lib/boardwise/coach.ex b/lib/boardwise/coach.ex new file mode 100644 index 0000000..04df005 --- /dev/null +++ b/lib/boardwise/coach.ex @@ -0,0 +1,21 @@ +defmodule BoardWise.Coach do + use Ecto.Schema + import Ecto.Changeset + + schema "coaches" do + field :blitz, :integer + field :bullet, :integer + field :rapid, :integer + field :site, :string + field :username, :string + + timestamps(type: :utc_datetime) + end + + @doc false + def changeset(coach, attrs) do + coach + |> cast(attrs, [:site, :username, :rapid, :blitz, :bullet]) + |> validate_required([:site, :username, :rapid, :blitz, :bullet]) + end +end diff --git a/lib/boardwise/coaches.ex b/lib/boardwise/coaches.ex new file mode 100644 index 0000000..2c92183 --- /dev/null +++ b/lib/boardwise/coaches.ex @@ -0,0 +1,106 @@ +defmodule BoardWise.Coaches do + @moduledoc """ + The Coaches context. + """ + + import Ecto.Query, warn: false + alias BoardWise.Repo + + alias BoardWise.Coaches.Coach + + @prefix "coach_scraper" + + @doc """ + Returns the list of coaches. + + ## Examples + + iex> list_coaches() + [%Coach{}, ...] + + """ + def list_coaches do + Repo.all(Coach, prefix: @prefix) + end + + @doc """ + Gets a single coach. + + Raises `Ecto.NoResultsError` if the Coach does not exist. + + ## Examples + + iex> get_coach!(123) + %Coach{} + + iex> get_coach!(456) + ** (Ecto.NoResultsError) + + """ + def get_coach!(id), do: Repo.get!(Coach, id, prefix: @prefix) + + @doc """ + Creates a coach. + + ## Examples + + iex> create_coach(%{field: value}) + {:ok, %Coach{}} + + iex> create_coach(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_coach(attrs \\ %{}) do + %Coach{} + |> Coach.changeset(attrs) + |> Repo.insert(prefix: @prefix) + end + + @doc """ + Updates a coach. + + ## Examples + + iex> update_coach(coach, %{field: new_value}) + {:ok, %Coach{}} + + iex> update_coach(coach, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_coach(%Coach{} = coach, attrs) do + coach + |> Coach.changeset(attrs) + |> Repo.update(prefix: @prefix) + end + + @doc """ + Deletes a coach. + + ## Examples + + iex> delete_coach(coach) + {:ok, %Coach{}} + + iex> delete_coach(coach) + {:error, %Ecto.Changeset{}} + + """ + def delete_coach(%Coach{} = coach) do + Repo.delete(coach, prefix: @prefix) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking coach changes. + + ## Examples + + iex> change_coach(coach) + %Ecto.Changeset{data: %Coach{}} + + """ + def change_coach(%Coach{} = coach, attrs \\ %{}) do + Coach.changeset(coach, attrs) + end +end diff --git a/lib/boardwise/coaches/coach.ex b/lib/boardwise/coaches/coach.ex new file mode 100644 index 0000000..146fc23 --- /dev/null +++ b/lib/boardwise/coaches/coach.ex @@ -0,0 +1,30 @@ +defmodule BoardWise.Coaches.Coach do + @moduledoc """ + Table `coach_scraper.export` containing all scraped coach information. + + Notice this table does not exist in the `public` schema. + + This table is managed by an external utility [coach-scraper](https://github.com/boardwise-gg/coach-scraper). + Said utility is responsible for periodically rewriting the entries in the + table with fresh data. For the time-being, avoid using any of the mutative + functions found in the `Coach` context. + """ + + use Ecto.Schema + import Ecto.Changeset + + schema "export" do + field :blitz, :integer + field :bullet, :integer + field :rapid, :integer + field :site, :string + field :username, :string + end + + @doc false + def changeset(coach, attrs) do + coach + |> cast(attrs, [:rapid, :blitz, :bullet, :site, :username]) + |> validate_required([:rapid, :blitz, :bullet, :site, :username]) + end +end diff --git a/priv/repo/migrations/20231204141656_create_coaches.exs b/priv/repo/migrations/20231204141656_create_coaches.exs new file mode 100644 index 0000000..374e478 --- /dev/null +++ b/priv/repo/migrations/20231204141656_create_coaches.exs @@ -0,0 +1,17 @@ +defmodule BoardWise.Repo.Migrations.CreateCoaches do + use Ecto.Migration + + # We are not responsible for generating this table in production. This + # migration exists for testing purposes + def change do + execute "CREATE SCHEMA IF NOT EXISTS coach_scraper" + + create_if_not_exists table(:export, prefix: "coach_scraper") do + add :site, :string + add :username, :string + add :rapid, :integer + add :blitz, :integer + add :bullet, :integer + end + end +end diff --git a/test/boardwise/coaches_test.exs b/test/boardwise/coaches_test.exs new file mode 100644 index 0000000..7c9ce6d --- /dev/null +++ b/test/boardwise/coaches_test.exs @@ -0,0 +1,80 @@ +defmodule BoardWise.CoachesTest do + use BoardWise.DataCase + + alias BoardWise.Coaches + + describe "coaches" do + alias BoardWise.Coaches.Coach + + import BoardWise.CoachesFixtures + + @invalid_attrs %{blitz: nil, bullet: nil, rapid: nil, site: nil, username: nil} + + test "list_coaches/0 returns all coaches" do + coach = coach_fixture() + assert Coaches.list_coaches() == [coach] + end + + test "get_coach!/1 returns the coach with given id" do + coach = coach_fixture() + assert Coaches.get_coach!(coach.id) == coach + end + + test "create_coach/1 with valid data creates a coach" do + valid_attrs = %{ + blitz: 42, + bullet: 42, + rapid: 42, + site: "some site", + username: "some username" + } + + assert {:ok, %Coach{} = coach} = Coaches.create_coach(valid_attrs) + assert coach.blitz == 42 + assert coach.bullet == 42 + assert coach.rapid == 42 + assert coach.site == "some site" + assert coach.username == "some username" + end + + test "create_coach/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Coaches.create_coach(@invalid_attrs) + end + + test "update_coach/2 with valid data updates the coach" do + coach = coach_fixture() + + update_attrs = %{ + blitz: 43, + bullet: 43, + rapid: 43, + site: "some updated site", + username: "some updated username" + } + + assert {:ok, %Coach{} = coach} = Coaches.update_coach(coach, update_attrs) + assert coach.blitz == 43 + assert coach.bullet == 43 + assert coach.rapid == 43 + assert coach.site == "some updated site" + assert coach.username == "some updated username" + end + + test "update_coach/2 with invalid data returns error changeset" do + coach = coach_fixture() + assert {:error, %Ecto.Changeset{}} = Coaches.update_coach(coach, @invalid_attrs) + assert coach == Coaches.get_coach!(coach.id) + end + + test "delete_coach/1 deletes the coach" do + coach = coach_fixture() + assert {:ok, %Coach{}} = Coaches.delete_coach(coach) + assert_raise Ecto.NoResultsError, fn -> Coaches.get_coach!(coach.id) end + end + + test "change_coach/1 returns a coach changeset" do + coach = coach_fixture() + assert %Ecto.Changeset{} = Coaches.change_coach(coach) + end + end +end diff --git a/test/boardwise_web/controllers/page_controller_test.exs b/test/boardwise_web/controllers/page_controller_test.exs deleted file mode 100644 index 796bf0a..0000000 --- a/test/boardwise_web/controllers/page_controller_test.exs +++ /dev/null @@ -1,8 +0,0 @@ -defmodule BoardWiseWeb.PageControllerTest do - use BoardWiseWeb.ConnCase - - test "GET /", %{conn: conn} do - conn = get(conn, ~p"/") - assert html_response(conn, 200) =~ "Peace of mind from prototype to production" - end -end diff --git a/test/support/fixtures/coaches_fixtures.ex b/test/support/fixtures/coaches_fixtures.ex new file mode 100644 index 0000000..afd78ca --- /dev/null +++ b/test/support/fixtures/coaches_fixtures.ex @@ -0,0 +1,24 @@ +defmodule BoardWise.CoachesFixtures do + @moduledoc """ + This module defines test helpers for creating + entities via the `BoardWise.Coaches` context. + """ + + @doc """ + Generate a coach. + """ + def coach_fixture(attrs \\ %{}) do + {:ok, coach} = + attrs + |> Enum.into(%{ + blitz: 42, + bullet: 42, + rapid: 42, + site: "some site", + username: "some username" + }) + |> BoardWise.Coaches.create_coach() + + coach + end +end