From 14f04befd009f34ae2a3b432d48947939b319616 Mon Sep 17 00:00:00 2001 From: Bent Witthold Date: Wed, 11 Feb 2026 10:57:27 +0100 Subject: [PATCH] After "mix phx.gen.json BiddingRounds BiddingRound bidding_rounds round_number:integer running:boolean --no-scope". --- lib/beet_round_server/bidding_rounds.ex | 104 ++++++++++++++++++ .../bidding_rounds/bidding_round.ex | 20 ++++ .../controllers/bidding_round_controller.ex | 43 ++++++++ .../controllers/bidding_round_json.ex | 25 +++++ .../controllers/changeset_json.ex | 25 +++++ .../controllers/fallback_controller.ex | 24 ++++ lib/beet_round_server_web/router.ex | 8 +- .../20260122104608_create_bidding_rounds.exs | 13 +++ .../beet_round_server/bidding_rounds_test.exs | 61 ++++++++++ .../bidding_round_controller_test.exs | 88 +++++++++++++++ .../fixtures/bidding_rounds_fixtures.ex | 21 ++++ 11 files changed, 429 insertions(+), 3 deletions(-) create mode 100644 lib/beet_round_server/bidding_rounds.ex create mode 100644 lib/beet_round_server/bidding_rounds/bidding_round.ex create mode 100644 lib/beet_round_server_web/controllers/bidding_round_controller.ex create mode 100644 lib/beet_round_server_web/controllers/bidding_round_json.ex create mode 100644 lib/beet_round_server_web/controllers/changeset_json.ex create mode 100644 lib/beet_round_server_web/controllers/fallback_controller.ex create mode 100644 priv/repo/migrations/20260122104608_create_bidding_rounds.exs create mode 100644 test/beet_round_server/bidding_rounds_test.exs create mode 100644 test/beet_round_server_web/controllers/bidding_round_controller_test.exs create mode 100644 test/support/fixtures/bidding_rounds_fixtures.ex diff --git a/lib/beet_round_server/bidding_rounds.ex b/lib/beet_round_server/bidding_rounds.ex new file mode 100644 index 0000000..b1613ce --- /dev/null +++ b/lib/beet_round_server/bidding_rounds.ex @@ -0,0 +1,104 @@ +defmodule BeetRoundServer.BiddingRounds do + @moduledoc """ + The BiddingRounds context. + """ + + import Ecto.Query, warn: false + alias BeetRoundServer.Repo + + alias BeetRoundServer.BiddingRounds.BiddingRound + + @doc """ + Returns the list of bidding_rounds. + + ## Examples + + iex> list_bidding_rounds() + [%BiddingRound{}, ...] + + """ + def list_bidding_rounds do + Repo.all(BiddingRound) + end + + @doc """ + Gets a single bidding_round. + + Raises `Ecto.NoResultsError` if the Bidding round does not exist. + + ## Examples + + iex> get_bidding_round!(123) + %BiddingRound{} + + iex> get_bidding_round!(456) + ** (Ecto.NoResultsError) + + """ + def get_bidding_round!(id), do: Repo.get!(BiddingRound, id) + + @doc """ + Creates a bidding_round. + + ## Examples + + iex> create_bidding_round(%{field: value}) + {:ok, %BiddingRound{}} + + iex> create_bidding_round(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_bidding_round(attrs) do + %BiddingRound{} + |> BiddingRound.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a bidding_round. + + ## Examples + + iex> update_bidding_round(bidding_round, %{field: new_value}) + {:ok, %BiddingRound{}} + + iex> update_bidding_round(bidding_round, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_bidding_round(%BiddingRound{} = bidding_round, attrs) do + bidding_round + |> BiddingRound.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a bidding_round. + + ## Examples + + iex> delete_bidding_round(bidding_round) + {:ok, %BiddingRound{}} + + iex> delete_bidding_round(bidding_round) + {:error, %Ecto.Changeset{}} + + """ + def delete_bidding_round(%BiddingRound{} = bidding_round) do + Repo.delete(bidding_round) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking bidding_round changes. + + ## Examples + + iex> change_bidding_round(bidding_round) + %Ecto.Changeset{data: %BiddingRound{}} + + """ + def change_bidding_round(%BiddingRound{} = bidding_round, attrs \\ %{}) do + BiddingRound.changeset(bidding_round, attrs) + end +end diff --git a/lib/beet_round_server/bidding_rounds/bidding_round.ex b/lib/beet_round_server/bidding_rounds/bidding_round.ex new file mode 100644 index 0000000..155dbd8 --- /dev/null +++ b/lib/beet_round_server/bidding_rounds/bidding_round.ex @@ -0,0 +1,20 @@ +defmodule BeetRoundServer.BiddingRounds.BiddingRound do + use Ecto.Schema + import Ecto.Changeset + + @primary_key {:id, :binary_id, autogenerate: true} + @foreign_key_type :binary_id + schema "bidding_rounds" do + field :round_number, :integer + field :running, :boolean, default: false + + timestamps(type: :utc_datetime) + end + + @doc false + def changeset(bidding_round, attrs) do + bidding_round + |> cast(attrs, [:round_number, :running]) + |> validate_required([:round_number, :running]) + end +end diff --git a/lib/beet_round_server_web/controllers/bidding_round_controller.ex b/lib/beet_round_server_web/controllers/bidding_round_controller.ex new file mode 100644 index 0000000..0b884bb --- /dev/null +++ b/lib/beet_round_server_web/controllers/bidding_round_controller.ex @@ -0,0 +1,43 @@ +defmodule BeetRoundServerWeb.BiddingRoundController do + use BeetRoundServerWeb, :controller + + alias BeetRoundServer.BiddingRounds + alias BeetRoundServer.BiddingRounds.BiddingRound + + action_fallback BeetRoundServerWeb.FallbackController + + def index(conn, _params) do + bidding_rounds = BiddingRounds.list_bidding_rounds() + render(conn, :index, bidding_rounds: bidding_rounds) + end + + def create(conn, %{"bidding_round" => bidding_round_params}) do + with {:ok, %BiddingRound{} = bidding_round} <- BiddingRounds.create_bidding_round(bidding_round_params) do + conn + |> put_status(:created) + |> put_resp_header("location", ~p"/api/bidding_rounds/#{bidding_round}") + |> render(:show, bidding_round: bidding_round) + end + end + + def show(conn, %{"id" => id}) do + bidding_round = BiddingRounds.get_bidding_round!(id) + render(conn, :show, bidding_round: bidding_round) + end + + def update(conn, %{"id" => id, "bidding_round" => bidding_round_params}) do + bidding_round = BiddingRounds.get_bidding_round!(id) + + with {:ok, %BiddingRound{} = bidding_round} <- BiddingRounds.update_bidding_round(bidding_round, bidding_round_params) do + render(conn, :show, bidding_round: bidding_round) + end + end + + def delete(conn, %{"id" => id}) do + bidding_round = BiddingRounds.get_bidding_round!(id) + + with {:ok, %BiddingRound{}} <- BiddingRounds.delete_bidding_round(bidding_round) do + send_resp(conn, :no_content, "") + end + end +end diff --git a/lib/beet_round_server_web/controllers/bidding_round_json.ex b/lib/beet_round_server_web/controllers/bidding_round_json.ex new file mode 100644 index 0000000..9960607 --- /dev/null +++ b/lib/beet_round_server_web/controllers/bidding_round_json.ex @@ -0,0 +1,25 @@ +defmodule BeetRoundServerWeb.BiddingRoundJSON do + alias BeetRoundServer.BiddingRounds.BiddingRound + + @doc """ + Renders a list of bidding_rounds. + """ + def index(%{bidding_rounds: bidding_rounds}) do + %{data: for(bidding_round <- bidding_rounds, do: data(bidding_round))} + end + + @doc """ + Renders a single bidding_round. + """ + def show(%{bidding_round: bidding_round}) do + %{data: data(bidding_round)} + end + + defp data(%BiddingRound{} = bidding_round) do + %{ + id: bidding_round.id, + round_number: bidding_round.round_number, + running: bidding_round.running + } + end +end diff --git a/lib/beet_round_server_web/controllers/changeset_json.ex b/lib/beet_round_server_web/controllers/changeset_json.ex new file mode 100644 index 0000000..d5e85d9 --- /dev/null +++ b/lib/beet_round_server_web/controllers/changeset_json.ex @@ -0,0 +1,25 @@ +defmodule BeetRoundServerWeb.ChangesetJSON do + @doc """ + Renders changeset errors. + """ + def error(%{changeset: changeset}) do + # When encoded, the changeset returns its errors + # as a JSON object. So we just pass it forward. + %{errors: Ecto.Changeset.traverse_errors(changeset, &translate_error/1)} + end + + defp translate_error({msg, opts}) do + # You can make use of gettext to translate error messages by + # uncommenting and adjusting the following code: + + # if count = opts[:count] do + # Gettext.dngettext(BeetRoundServerWeb.Gettext, "errors", msg, msg, count, opts) + # else + # Gettext.dgettext(BeetRoundServerWeb.Gettext, "errors", msg, opts) + # end + + Enum.reduce(opts, msg, fn {key, value}, acc -> + String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end) + end) + end +end diff --git a/lib/beet_round_server_web/controllers/fallback_controller.ex b/lib/beet_round_server_web/controllers/fallback_controller.ex new file mode 100644 index 0000000..eb929e9 --- /dev/null +++ b/lib/beet_round_server_web/controllers/fallback_controller.ex @@ -0,0 +1,24 @@ +defmodule BeetRoundServerWeb.FallbackController do + @moduledoc """ + Translates controller action results into valid `Plug.Conn` responses. + + See `Phoenix.Controller.action_fallback/1` for more details. + """ + use BeetRoundServerWeb, :controller + + # This clause handles errors returned by Ecto's insert/update/delete. + def call(conn, {:error, %Ecto.Changeset{} = changeset}) do + conn + |> put_status(:unprocessable_entity) + |> put_view(json: BeetRoundServerWeb.ChangesetJSON) + |> render(:error, changeset: changeset) + end + + # This clause is an example of how to handle resources that cannot be found. + def call(conn, {:error, :not_found}) do + conn + |> put_status(:not_found) + |> put_view(html: BeetRoundServerWeb.ErrorHTML, json: BeetRoundServerWeb.ErrorJSON) + |> render(:"404") + end +end diff --git a/lib/beet_round_server_web/router.ex b/lib/beet_round_server_web/router.ex index 0d56990..f4f8e61 100644 --- a/lib/beet_round_server_web/router.ex +++ b/lib/beet_round_server_web/router.ex @@ -24,9 +24,11 @@ defmodule BeetRoundServerWeb.Router do end # Other scopes may use custom stacks. - # scope "/api", BeetRoundServerWeb do - # pipe_through :api - # end + scope "/api", BeetRoundServerWeb do + pipe_through :api + + resources "/bidding_rounds", BiddingRoundController, except: [:new, :edit] + end # Enable LiveDashboard and Swoosh mailbox preview in development if Application.compile_env(:beet_round_server, :dev_routes) do diff --git a/priv/repo/migrations/20260122104608_create_bidding_rounds.exs b/priv/repo/migrations/20260122104608_create_bidding_rounds.exs new file mode 100644 index 0000000..c139b0a --- /dev/null +++ b/priv/repo/migrations/20260122104608_create_bidding_rounds.exs @@ -0,0 +1,13 @@ +defmodule BeetRoundServer.Repo.Migrations.CreateBiddingRounds do + use Ecto.Migration + + def change do + create table(:bidding_rounds, primary_key: false) do + add :id, :binary_id, primary_key: true + add :round_number, :integer + add :running, :boolean, default: false, null: false + + timestamps(type: :utc_datetime) + end + end +end diff --git a/test/beet_round_server/bidding_rounds_test.exs b/test/beet_round_server/bidding_rounds_test.exs new file mode 100644 index 0000000..602b0b1 --- /dev/null +++ b/test/beet_round_server/bidding_rounds_test.exs @@ -0,0 +1,61 @@ +defmodule BeetRoundServer.BiddingRoundsTest do + use BeetRoundServer.DataCase + + alias BeetRoundServer.BiddingRounds + + describe "bidding_rounds" do + alias BeetRoundServer.BiddingRounds.BiddingRound + + import BeetRoundServer.BiddingRoundsFixtures + + @invalid_attrs %{running: nil, round_number: nil} + + test "list_bidding_rounds/0 returns all bidding_rounds" do + bidding_round = bidding_round_fixture() + assert BiddingRounds.list_bidding_rounds() == [bidding_round] + end + + test "get_bidding_round!/1 returns the bidding_round with given id" do + bidding_round = bidding_round_fixture() + assert BiddingRounds.get_bidding_round!(bidding_round.id) == bidding_round + end + + test "create_bidding_round/1 with valid data creates a bidding_round" do + valid_attrs = %{running: true, round_number: 42} + + assert {:ok, %BiddingRound{} = bidding_round} = BiddingRounds.create_bidding_round(valid_attrs) + assert bidding_round.running == true + assert bidding_round.round_number == 42 + end + + test "create_bidding_round/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = BiddingRounds.create_bidding_round(@invalid_attrs) + end + + test "update_bidding_round/2 with valid data updates the bidding_round" do + bidding_round = bidding_round_fixture() + update_attrs = %{running: false, round_number: 43} + + assert {:ok, %BiddingRound{} = bidding_round} = BiddingRounds.update_bidding_round(bidding_round, update_attrs) + assert bidding_round.running == false + assert bidding_round.round_number == 43 + end + + test "update_bidding_round/2 with invalid data returns error changeset" do + bidding_round = bidding_round_fixture() + assert {:error, %Ecto.Changeset{}} = BiddingRounds.update_bidding_round(bidding_round, @invalid_attrs) + assert bidding_round == BiddingRounds.get_bidding_round!(bidding_round.id) + end + + test "delete_bidding_round/1 deletes the bidding_round" do + bidding_round = bidding_round_fixture() + assert {:ok, %BiddingRound{}} = BiddingRounds.delete_bidding_round(bidding_round) + assert_raise Ecto.NoResultsError, fn -> BiddingRounds.get_bidding_round!(bidding_round.id) end + end + + test "change_bidding_round/1 returns a bidding_round changeset" do + bidding_round = bidding_round_fixture() + assert %Ecto.Changeset{} = BiddingRounds.change_bidding_round(bidding_round) + end + end +end diff --git a/test/beet_round_server_web/controllers/bidding_round_controller_test.exs b/test/beet_round_server_web/controllers/bidding_round_controller_test.exs new file mode 100644 index 0000000..317af7d --- /dev/null +++ b/test/beet_round_server_web/controllers/bidding_round_controller_test.exs @@ -0,0 +1,88 @@ +defmodule BeetRoundServerWeb.BiddingRoundControllerTest do + use BeetRoundServerWeb.ConnCase + + import BeetRoundServer.BiddingRoundsFixtures + alias BeetRoundServer.BiddingRounds.BiddingRound + + @create_attrs %{ + running: true, + round_number: 42 + } + @update_attrs %{ + running: false, + round_number: 43 + } + @invalid_attrs %{running: nil, round_number: nil} + + setup %{conn: conn} do + {:ok, conn: put_req_header(conn, "accept", "application/json")} + end + + describe "index" do + test "lists all bidding_rounds", %{conn: conn} do + conn = get(conn, ~p"/api/bidding_rounds") + assert json_response(conn, 200)["data"] == [] + end + end + + describe "create bidding_round" do + test "renders bidding_round when data is valid", %{conn: conn} do + conn = post(conn, ~p"/api/bidding_rounds", bidding_round: @create_attrs) + assert %{"id" => id} = json_response(conn, 201)["data"] + + conn = get(conn, ~p"/api/bidding_rounds/#{id}") + + assert %{ + "id" => ^id, + "round_number" => 42, + "running" => true + } = json_response(conn, 200)["data"] + end + + test "renders errors when data is invalid", %{conn: conn} do + conn = post(conn, ~p"/api/bidding_rounds", bidding_round: @invalid_attrs) + assert json_response(conn, 422)["errors"] != %{} + end + end + + describe "update bidding_round" do + setup [:create_bidding_round] + + test "renders bidding_round when data is valid", %{conn: conn, bidding_round: %BiddingRound{id: id} = bidding_round} do + conn = put(conn, ~p"/api/bidding_rounds/#{bidding_round}", bidding_round: @update_attrs) + assert %{"id" => ^id} = json_response(conn, 200)["data"] + + conn = get(conn, ~p"/api/bidding_rounds/#{id}") + + assert %{ + "id" => ^id, + "round_number" => 43, + "running" => false + } = json_response(conn, 200)["data"] + end + + test "renders errors when data is invalid", %{conn: conn, bidding_round: bidding_round} do + conn = put(conn, ~p"/api/bidding_rounds/#{bidding_round}", bidding_round: @invalid_attrs) + assert json_response(conn, 422)["errors"] != %{} + end + end + + describe "delete bidding_round" do + setup [:create_bidding_round] + + test "deletes chosen bidding_round", %{conn: conn, bidding_round: bidding_round} do + conn = delete(conn, ~p"/api/bidding_rounds/#{bidding_round}") + assert response(conn, 204) + + assert_error_sent 404, fn -> + get(conn, ~p"/api/bidding_rounds/#{bidding_round}") + end + end + end + + defp create_bidding_round(_) do + bidding_round = bidding_round_fixture() + + %{bidding_round: bidding_round} + end +end diff --git a/test/support/fixtures/bidding_rounds_fixtures.ex b/test/support/fixtures/bidding_rounds_fixtures.ex new file mode 100644 index 0000000..1dcb09f --- /dev/null +++ b/test/support/fixtures/bidding_rounds_fixtures.ex @@ -0,0 +1,21 @@ +defmodule BeetRoundServer.BiddingRoundsFixtures do + @moduledoc """ + This module defines test helpers for creating + entities via the `BeetRoundServer.BiddingRounds` context. + """ + + @doc """ + Generate a bidding_round. + """ + def bidding_round_fixture(attrs \\ %{}) do + {:ok, bidding_round} = + attrs + |> Enum.into(%{ + round_number: 42, + running: true + }) + |> BeetRoundServer.BiddingRounds.create_bidding_round() + + bidding_round + end +end