diff --git a/lib/runosaari/schedule.ex b/lib/runosaari/schedule.ex new file mode 100644 index 0000000..facda3a --- /dev/null +++ b/lib/runosaari/schedule.ex @@ -0,0 +1,104 @@ +defmodule Runosaari.Schedule do + @moduledoc """ + The Schedule context. + """ + + import Ecto.Query, warn: false + alias Runosaari.Repo + + alias Runosaari.Schedule.Performance + + @doc """ + Returns the list of performances. + + ## Examples + + iex> list_performances() + [%Performance{}, ...] + + """ + def list_performances do + Repo.all(Performance) + end + + @doc """ + Gets a single performance. + + Raises `Ecto.NoResultsError` if the Performance does not exist. + + ## Examples + + iex> get_performance!(123) + %Performance{} + + iex> get_performance!(456) + ** (Ecto.NoResultsError) + + """ + def get_performance!(id), do: Repo.get!(Performance, id) + + @doc """ + Creates a performance. + + ## Examples + + iex> create_performance(%{field: value}) + {:ok, %Performance{}} + + iex> create_performance(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_performance(attrs \\ %{}) do + %Performance{} + |> Performance.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a performance. + + ## Examples + + iex> update_performance(performance, %{field: new_value}) + {:ok, %Performance{}} + + iex> update_performance(performance, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_performance(%Performance{} = performance, attrs) do + performance + |> Performance.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a performance. + + ## Examples + + iex> delete_performance(performance) + {:ok, %Performance{}} + + iex> delete_performance(performance) + {:error, %Ecto.Changeset{}} + + """ + def delete_performance(%Performance{} = performance) do + Repo.delete(performance) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking performance changes. + + ## Examples + + iex> change_performance(performance) + %Ecto.Changeset{data: %Performance{}} + + """ + def change_performance(%Performance{} = performance, attrs \\ %{}) do + Performance.changeset(performance, attrs) + end +end diff --git a/lib/runosaari/schedule/performance.ex b/lib/runosaari/schedule/performance.ex new file mode 100644 index 0000000..5d27a0c --- /dev/null +++ b/lib/runosaari/schedule/performance.ex @@ -0,0 +1,21 @@ +defmodule Runosaari.Schedule.Performance do + use Ecto.Schema + import Ecto.Changeset + + schema "performances" do + field :description, :string + field :notes, :string + field :time, :naive_datetime + field :location_id, :id + field :performer_id, :id + + timestamps() + end + + @doc false + def changeset(performance, attrs) do + performance + |> cast(attrs, [:time, :description, :notes]) + |> validate_required([:time, :description, :notes]) + end +end diff --git a/lib/runosaari_web/controllers/performance_controller.ex b/lib/runosaari_web/controllers/performance_controller.ex new file mode 100644 index 0000000..e4bc80d --- /dev/null +++ b/lib/runosaari_web/controllers/performance_controller.ex @@ -0,0 +1,62 @@ +defmodule RunosaariWeb.PerformanceController do + use RunosaariWeb, :controller + + alias Runosaari.Schedule + alias Runosaari.Schedule.Performance + + def index(conn, _params) do + performances = Schedule.list_performances() + render(conn, "index.html", performances: performances) + end + + def new(conn, _params) do + changeset = Schedule.change_performance(%Performance{}) + render(conn, "new.html", changeset: changeset) + end + + def create(conn, %{"performance" => performance_params}) do + case Schedule.create_performance(performance_params) do + {:ok, performance} -> + conn + |> put_flash(:info, "Performance created successfully.") + |> redirect(to: Routes.performance_path(conn, :show, performance)) + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, "new.html", changeset: changeset) + end + end + + def show(conn, %{"id" => id}) do + performance = Schedule.get_performance!(id) + render(conn, "show.html", performance: performance) + end + + def edit(conn, %{"id" => id}) do + performance = Schedule.get_performance!(id) + changeset = Schedule.change_performance(performance) + render(conn, "edit.html", performance: performance, changeset: changeset) + end + + def update(conn, %{"id" => id, "performance" => performance_params}) do + performance = Schedule.get_performance!(id) + + case Schedule.update_performance(performance, performance_params) do + {:ok, performance} -> + conn + |> put_flash(:info, "Performance updated successfully.") + |> redirect(to: Routes.performance_path(conn, :show, performance)) + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, "edit.html", performance: performance, changeset: changeset) + end + end + + def delete(conn, %{"id" => id}) do + performance = Schedule.get_performance!(id) + {:ok, _performance} = Schedule.delete_performance(performance) + + conn + |> put_flash(:info, "Performance deleted successfully.") + |> redirect(to: Routes.performance_path(conn, :index)) + end +end diff --git a/lib/runosaari_web/templates/performance/edit.html.eex b/lib/runosaari_web/templates/performance/edit.html.eex new file mode 100644 index 0000000..7efad9d --- /dev/null +++ b/lib/runosaari_web/templates/performance/edit.html.eex @@ -0,0 +1,5 @@ +

Edit Performance

+ +<%= render "form.html", Map.put(assigns, :action, Routes.performance_path(@conn, :update, @performance)) %> + +<%= link "Back", to: Routes.performance_path(@conn, :index) %> diff --git a/lib/runosaari_web/templates/performance/form.html.eex b/lib/runosaari_web/templates/performance/form.html.eex new file mode 100644 index 0000000..9805aae --- /dev/null +++ b/lib/runosaari_web/templates/performance/form.html.eex @@ -0,0 +1,23 @@ +<%= form_for @changeset, @action, fn f -> %> + <%= if @changeset.action do %> +
+

Oops, something went wrong! Please check the errors below.

+
+ <% end %> + + <%= label f, :time %> + <%= datetime_select f, :time %> + <%= error_tag f, :time %> + + <%= label f, :description %> + <%= text_input f, :description %> + <%= error_tag f, :description %> + + <%= label f, :notes %> + <%= text_input f, :notes %> + <%= error_tag f, :notes %> + +
+ <%= submit "Save" %> +
+<% end %> diff --git a/lib/runosaari_web/templates/performance/index.html.eex b/lib/runosaari_web/templates/performance/index.html.eex new file mode 100644 index 0000000..b37e197 --- /dev/null +++ b/lib/runosaari_web/templates/performance/index.html.eex @@ -0,0 +1,30 @@ +

Listing Performances

+ + + + + + + + + + + + +<%= for performance <- @performances do %> + + + + + + + +<% end %> + +
TimeDescriptionNotes
<%= performance.time %><%= performance.description %><%= performance.notes %> + <%= link "Show", to: Routes.performance_path(@conn, :show, performance) %> + <%= link "Edit", to: Routes.performance_path(@conn, :edit, performance) %> + <%= link "Delete", to: Routes.performance_path(@conn, :delete, performance), method: :delete, data: [confirm: "Are you sure?"] %> +
+ +<%= link "New Performance", to: Routes.performance_path(@conn, :new) %> diff --git a/lib/runosaari_web/templates/performance/new.html.eex b/lib/runosaari_web/templates/performance/new.html.eex new file mode 100644 index 0000000..bbd61b7 --- /dev/null +++ b/lib/runosaari_web/templates/performance/new.html.eex @@ -0,0 +1,5 @@ +

New Performance

+ +<%= render "form.html", Map.put(assigns, :action, Routes.performance_path(@conn, :create)) %> + +<%= link "Back", to: Routes.performance_path(@conn, :index) %> diff --git a/lib/runosaari_web/templates/performance/show.html.eex b/lib/runosaari_web/templates/performance/show.html.eex new file mode 100644 index 0000000..fd2dd3c --- /dev/null +++ b/lib/runosaari_web/templates/performance/show.html.eex @@ -0,0 +1,23 @@ +

Show Performance

+ + + +<%= link "Edit", to: Routes.performance_path(@conn, :edit, @performance) %> +<%= link "Back", to: Routes.performance_path(@conn, :index) %> diff --git a/lib/runosaari_web/views/performance_view.ex b/lib/runosaari_web/views/performance_view.ex new file mode 100644 index 0000000..da21160 --- /dev/null +++ b/lib/runosaari_web/views/performance_view.ex @@ -0,0 +1,3 @@ +defmodule RunosaariWeb.PerformanceView do + use RunosaariWeb, :view +end diff --git a/priv/repo/migrations/20210330194953_create_performances.exs b/priv/repo/migrations/20210330194953_create_performances.exs new file mode 100644 index 0000000..dd64b66 --- /dev/null +++ b/priv/repo/migrations/20210330194953_create_performances.exs @@ -0,0 +1,18 @@ +defmodule Runosaari.Repo.Migrations.CreatePerformances do + use Ecto.Migration + + def change do + create table(:performances) do + add :time, :naive_datetime + add :description, :string + add :notes, :string + add :location_id, references(:locations, on_delete: :nothing) + add :performer_id, references(:performers, on_delete: :nothing) + + timestamps() + end + + create index(:performances, [:location_id]) + create index(:performances, [:performer_id]) + end +end diff --git a/test/runosaari/schedule_test.exs b/test/runosaari/schedule_test.exs new file mode 100644 index 0000000..146f968 --- /dev/null +++ b/test/runosaari/schedule_test.exs @@ -0,0 +1,68 @@ +defmodule Runosaari.ScheduleTest do + use Runosaari.DataCase + + alias Runosaari.Schedule + + describe "performances" do + alias Runosaari.Schedule.Performance + + @valid_attrs %{description: "some description", notes: "some notes", time: ~N[2010-04-17 14:00:00]} + @update_attrs %{description: "some updated description", notes: "some updated notes", time: ~N[2011-05-18 15:01:01]} + @invalid_attrs %{description: nil, notes: nil, time: nil} + + def performance_fixture(attrs \\ %{}) do + {:ok, performance} = + attrs + |> Enum.into(@valid_attrs) + |> Schedule.create_performance() + + performance + end + + test "list_performances/0 returns all performances" do + performance = performance_fixture() + assert Schedule.list_performances() == [performance] + end + + test "get_performance!/1 returns the performance with given id" do + performance = performance_fixture() + assert Schedule.get_performance!(performance.id) == performance + end + + test "create_performance/1 with valid data creates a performance" do + assert {:ok, %Performance{} = performance} = Schedule.create_performance(@valid_attrs) + assert performance.description == "some description" + assert performance.notes == "some notes" + assert performance.time == ~N[2010-04-17 14:00:00] + end + + test "create_performance/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Schedule.create_performance(@invalid_attrs) + end + + test "update_performance/2 with valid data updates the performance" do + performance = performance_fixture() + assert {:ok, %Performance{} = performance} = Schedule.update_performance(performance, @update_attrs) + assert performance.description == "some updated description" + assert performance.notes == "some updated notes" + assert performance.time == ~N[2011-05-18 15:01:01] + end + + test "update_performance/2 with invalid data returns error changeset" do + performance = performance_fixture() + assert {:error, %Ecto.Changeset{}} = Schedule.update_performance(performance, @invalid_attrs) + assert performance == Schedule.get_performance!(performance.id) + end + + test "delete_performance/1 deletes the performance" do + performance = performance_fixture() + assert {:ok, %Performance{}} = Schedule.delete_performance(performance) + assert_raise Ecto.NoResultsError, fn -> Schedule.get_performance!(performance.id) end + end + + test "change_performance/1 returns a performance changeset" do + performance = performance_fixture() + assert %Ecto.Changeset{} = Schedule.change_performance(performance) + end + end +end diff --git a/test/runosaari_web/controllers/performance_controller_test.exs b/test/runosaari_web/controllers/performance_controller_test.exs new file mode 100644 index 0000000..d7f7e7a --- /dev/null +++ b/test/runosaari_web/controllers/performance_controller_test.exs @@ -0,0 +1,88 @@ +defmodule RunosaariWeb.PerformanceControllerTest do + use RunosaariWeb.ConnCase + + alias Runosaari.Schedule + + @create_attrs %{description: "some description", notes: "some notes", time: ~N[2010-04-17 14:00:00]} + @update_attrs %{description: "some updated description", notes: "some updated notes", time: ~N[2011-05-18 15:01:01]} + @invalid_attrs %{description: nil, notes: nil, time: nil} + + def fixture(:performance) do + {:ok, performance} = Schedule.create_performance(@create_attrs) + performance + end + + describe "index" do + test "lists all performances", %{conn: conn} do + conn = get(conn, Routes.performance_path(conn, :index)) + assert html_response(conn, 200) =~ "Listing Performances" + end + end + + describe "new performance" do + test "renders form", %{conn: conn} do + conn = get(conn, Routes.performance_path(conn, :new)) + assert html_response(conn, 200) =~ "New Performance" + end + end + + describe "create performance" do + test "redirects to show when data is valid", %{conn: conn} do + conn = post(conn, Routes.performance_path(conn, :create), performance: @create_attrs) + + assert %{id: id} = redirected_params(conn) + assert redirected_to(conn) == Routes.performance_path(conn, :show, id) + + conn = get(conn, Routes.performance_path(conn, :show, id)) + assert html_response(conn, 200) =~ "Show Performance" + end + + test "renders errors when data is invalid", %{conn: conn} do + conn = post(conn, Routes.performance_path(conn, :create), performance: @invalid_attrs) + assert html_response(conn, 200) =~ "New Performance" + end + end + + describe "edit performance" do + setup [:create_performance] + + test "renders form for editing chosen performance", %{conn: conn, performance: performance} do + conn = get(conn, Routes.performance_path(conn, :edit, performance)) + assert html_response(conn, 200) =~ "Edit Performance" + end + end + + describe "update performance" do + setup [:create_performance] + + test "redirects when data is valid", %{conn: conn, performance: performance} do + conn = put(conn, Routes.performance_path(conn, :update, performance), performance: @update_attrs) + assert redirected_to(conn) == Routes.performance_path(conn, :show, performance) + + conn = get(conn, Routes.performance_path(conn, :show, performance)) + assert html_response(conn, 200) =~ "some updated description" + end + + test "renders errors when data is invalid", %{conn: conn, performance: performance} do + conn = put(conn, Routes.performance_path(conn, :update, performance), performance: @invalid_attrs) + assert html_response(conn, 200) =~ "Edit Performance" + end + end + + describe "delete performance" do + setup [:create_performance] + + test "deletes chosen performance", %{conn: conn, performance: performance} do + conn = delete(conn, Routes.performance_path(conn, :delete, performance)) + assert redirected_to(conn) == Routes.performance_path(conn, :index) + assert_error_sent 404, fn -> + get(conn, Routes.performance_path(conn, :show, performance)) + end + end + end + + defp create_performance(_) do + performance = fixture(:performance) + %{performance: performance} + end +end