diff --git a/README.md b/README.md index c3a59d5..0267212 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,35 @@ we need to create the **`sent`** schema: mix phx.gen.html Ctx Sent sent message_id:string person_id:references:people request_id:string status_id:references:status template:string ``` +When you run this command in your terminal, +you should see the following output: + +``` +* creating lib/app_web/controllers/sent_controller.ex +* creating lib/app_web/templates/sent/edit.html.eex +* creating lib/app_web/templates/sent/form.html.eex +* creating lib/app_web/templates/sent/index.html.eex +* creating lib/app_web/templates/sent/new.html.eex +* creating lib/app_web/templates/sent/show.html.eex +* creating lib/app_web/views/sent_view.ex +* creating test/app_web/controllers/sent_controller_test.exs +* creating lib/app/ctx/sent.ex +* creating priv/repo/migrations/20200224224024_create_sent.exs +* creating lib/app/ctx.ex +* injecting lib/app/ctx.ex +* creating test/app/ctx_test.exs +* injecting test/app/ctx_test.exs + +Add the resource to your browser scope in lib/app_web/router.ex: + + resources "/sent", SentController + +Remember to update your repository by running migrations: + +$ mix ecto.migrate +``` + +We will follow these instructions in the next step! In case you are wondering what the **`message_id`** and **`request_id`** fields diff --git a/lib/app/ctx.ex b/lib/app/ctx.ex new file mode 100644 index 0000000..91d4f2a --- /dev/null +++ b/lib/app/ctx.ex @@ -0,0 +1,104 @@ +defmodule App.Ctx do + @moduledoc """ + The Ctx context. + """ + + import Ecto.Query, warn: false + alias App.Repo + + alias App.Ctx.Sent + + @doc """ + Returns the list of sent. + + ## Examples + + iex> list_sent() + [%Sent{}, ...] + + """ + def list_sent do + Repo.all(Sent) + end + + @doc """ + Gets a single sent. + + Raises `Ecto.NoResultsError` if the Sent does not exist. + + ## Examples + + iex> get_sent!(123) + %Sent{} + + iex> get_sent!(456) + ** (Ecto.NoResultsError) + + """ + def get_sent!(id), do: Repo.get!(Sent, id) + + @doc """ + Creates a sent. + + ## Examples + + iex> create_sent(%{field: value}) + {:ok, %Sent{}} + + iex> create_sent(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_sent(attrs \\ %{}) do + %Sent{} + |> Sent.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a sent. + + ## Examples + + iex> update_sent(sent, %{field: new_value}) + {:ok, %Sent{}} + + iex> update_sent(sent, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_sent(%Sent{} = sent, attrs) do + sent + |> Sent.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a sent. + + ## Examples + + iex> delete_sent(sent) + {:ok, %Sent{}} + + iex> delete_sent(sent) + {:error, %Ecto.Changeset{}} + + """ + def delete_sent(%Sent{} = sent) do + Repo.delete(sent) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking sent changes. + + ## Examples + + iex> change_sent(sent) + %Ecto.Changeset{source: %Sent{}} + + """ + def change_sent(%Sent{} = sent) do + Sent.changeset(sent, %{}) + end +end diff --git a/lib/app/ctx/sent.ex b/lib/app/ctx/sent.ex new file mode 100644 index 0000000..e97f8ef --- /dev/null +++ b/lib/app/ctx/sent.ex @@ -0,0 +1,21 @@ +defmodule App.Ctx.Sent do + use Ecto.Schema + import Ecto.Changeset + + schema "sent" do + field :message_id, :string + field :request_id, :string + field :template, :string + field :person_id, :id + field :status_id, :id + + timestamps() + end + + @doc false + def changeset(sent, attrs) do + sent + |> cast(attrs, [:message_id, :request_id, :template]) + |> validate_required([:message_id, :request_id, :template]) + end +end diff --git a/lib/app_web/controllers/sent_controller.ex b/lib/app_web/controllers/sent_controller.ex new file mode 100644 index 0000000..2aa4f30 --- /dev/null +++ b/lib/app_web/controllers/sent_controller.ex @@ -0,0 +1,62 @@ +defmodule AppWeb.SentController do + use AppWeb, :controller + + alias App.Ctx + alias App.Ctx.Sent + + def index(conn, _params) do + sent = Ctx.list_sent() + render(conn, "index.html", sent: sent) + end + + def new(conn, _params) do + changeset = Ctx.change_sent(%Sent{}) + render(conn, "new.html", changeset: changeset) + end + + def create(conn, %{"sent" => sent_params}) do + case Ctx.create_sent(sent_params) do + {:ok, sent} -> + conn + |> put_flash(:info, "Sent created successfully.") + |> redirect(to: Routes.sent_path(conn, :show, sent)) + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, "new.html", changeset: changeset) + end + end + + def show(conn, %{"id" => id}) do + sent = Ctx.get_sent!(id) + render(conn, "show.html", sent: sent) + end + + def edit(conn, %{"id" => id}) do + sent = Ctx.get_sent!(id) + changeset = Ctx.change_sent(sent) + render(conn, "edit.html", sent: sent, changeset: changeset) + end + + def update(conn, %{"id" => id, "sent" => sent_params}) do + sent = Ctx.get_sent!(id) + + case Ctx.update_sent(sent, sent_params) do + {:ok, sent} -> + conn + |> put_flash(:info, "Sent updated successfully.") + |> redirect(to: Routes.sent_path(conn, :show, sent)) + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, "edit.html", sent: sent, changeset: changeset) + end + end + + def delete(conn, %{"id" => id}) do + sent = Ctx.get_sent!(id) + {:ok, _sent} = Ctx.delete_sent(sent) + + conn + |> put_flash(:info, "Sent deleted successfully.") + |> redirect(to: Routes.sent_path(conn, :index)) + end +end diff --git a/lib/app_web/templates/sent/edit.html.eex b/lib/app_web/templates/sent/edit.html.eex new file mode 100644 index 0000000..29f1a3a --- /dev/null +++ b/lib/app_web/templates/sent/edit.html.eex @@ -0,0 +1,5 @@ +

Edit Sent

+ +<%= render "form.html", Map.put(assigns, :action, Routes.sent_path(@conn, :update, @sent)) %> + +<%= link "Back", to: Routes.sent_path(@conn, :index) %> diff --git a/lib/app_web/templates/sent/form.html.eex b/lib/app_web/templates/sent/form.html.eex new file mode 100644 index 0000000..27ec585 --- /dev/null +++ b/lib/app_web/templates/sent/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, :message_id %> + <%= text_input f, :message_id %> + <%= error_tag f, :message_id %> + + <%= label f, :request_id %> + <%= text_input f, :request_id %> + <%= error_tag f, :request_id %> + + <%= label f, :template %> + <%= text_input f, :template %> + <%= error_tag f, :template %> + +
+ <%= submit "Save" %> +
+<% end %> diff --git a/lib/app_web/templates/sent/index.html.eex b/lib/app_web/templates/sent/index.html.eex new file mode 100644 index 0000000..d5b9790 --- /dev/null +++ b/lib/app_web/templates/sent/index.html.eex @@ -0,0 +1,30 @@ +

Listing Sent

+ + + + + + + + + + + + +<%= for sent <- @sent do %> + + + + + + + +<% end %> + +
MessageRequestTemplate
<%= sent.message_id %><%= sent.request_id %><%= sent.template %> + <%= link "Show", to: Routes.sent_path(@conn, :show, sent) %> + <%= link "Edit", to: Routes.sent_path(@conn, :edit, sent) %> + <%= link "Delete", to: Routes.sent_path(@conn, :delete, sent), method: :delete, data: [confirm: "Are you sure?"] %> +
+ +<%= link "New Sent", to: Routes.sent_path(@conn, :new) %> diff --git a/lib/app_web/templates/sent/new.html.eex b/lib/app_web/templates/sent/new.html.eex new file mode 100644 index 0000000..fb1d323 --- /dev/null +++ b/lib/app_web/templates/sent/new.html.eex @@ -0,0 +1,5 @@ +

New Sent

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

Show Sent

+ + + +<%= link "Edit", to: Routes.sent_path(@conn, :edit, @sent) %> +<%= link "Back", to: Routes.sent_path(@conn, :index) %> diff --git a/lib/app_web/views/sent_view.ex b/lib/app_web/views/sent_view.ex new file mode 100644 index 0000000..0c06122 --- /dev/null +++ b/lib/app_web/views/sent_view.ex @@ -0,0 +1,3 @@ +defmodule AppWeb.SentView do + use AppWeb, :view +end diff --git a/priv/repo/migrations/20200224224024_create_sent.exs b/priv/repo/migrations/20200224224024_create_sent.exs new file mode 100644 index 0000000..7c106b2 --- /dev/null +++ b/priv/repo/migrations/20200224224024_create_sent.exs @@ -0,0 +1,18 @@ +defmodule App.Repo.Migrations.CreateSent do + use Ecto.Migration + + def change do + create table(:sent) do + add :message_id, :string + add :request_id, :string + add :template, :string + add :person_id, references(:people, on_delete: :nothing) + add :status_id, references(:status, on_delete: :nothing) + + timestamps() + end + + create index(:sent, [:person_id]) + create index(:sent, [:status_id]) + end +end diff --git a/test/app/ctx_test.exs b/test/app/ctx_test.exs new file mode 100644 index 0000000..d699a55 --- /dev/null +++ b/test/app/ctx_test.exs @@ -0,0 +1,68 @@ +defmodule App.CtxTest do + use App.DataCase + + alias App.Ctx + + describe "sent" do + alias App.Ctx.Sent + + @valid_attrs %{message_id: "some message_id", request_id: "some request_id", template: "some template"} + @update_attrs %{message_id: "some updated message_id", request_id: "some updated request_id", template: "some updated template"} + @invalid_attrs %{message_id: nil, request_id: nil, template: nil} + + def sent_fixture(attrs \\ %{}) do + {:ok, sent} = + attrs + |> Enum.into(@valid_attrs) + |> Ctx.create_sent() + + sent + end + + test "list_sent/0 returns all sent" do + sent = sent_fixture() + assert Ctx.list_sent() == [sent] + end + + test "get_sent!/1 returns the sent with given id" do + sent = sent_fixture() + assert Ctx.get_sent!(sent.id) == sent + end + + test "create_sent/1 with valid data creates a sent" do + assert {:ok, %Sent{} = sent} = Ctx.create_sent(@valid_attrs) + assert sent.message_id == "some message_id" + assert sent.request_id == "some request_id" + assert sent.template == "some template" + end + + test "create_sent/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Ctx.create_sent(@invalid_attrs) + end + + test "update_sent/2 with valid data updates the sent" do + sent = sent_fixture() + assert {:ok, %Sent{} = sent} = Ctx.update_sent(sent, @update_attrs) + assert sent.message_id == "some updated message_id" + assert sent.request_id == "some updated request_id" + assert sent.template == "some updated template" + end + + test "update_sent/2 with invalid data returns error changeset" do + sent = sent_fixture() + assert {:error, %Ecto.Changeset{}} = Ctx.update_sent(sent, @invalid_attrs) + assert sent == Ctx.get_sent!(sent.id) + end + + test "delete_sent/1 deletes the sent" do + sent = sent_fixture() + assert {:ok, %Sent{}} = Ctx.delete_sent(sent) + assert_raise Ecto.NoResultsError, fn -> Ctx.get_sent!(sent.id) end + end + + test "change_sent/1 returns a sent changeset" do + sent = sent_fixture() + assert %Ecto.Changeset{} = Ctx.change_sent(sent) + end + end +end diff --git a/test/app_web/controllers/sent_controller_test.exs b/test/app_web/controllers/sent_controller_test.exs new file mode 100644 index 0000000..d18a40e --- /dev/null +++ b/test/app_web/controllers/sent_controller_test.exs @@ -0,0 +1,88 @@ +defmodule AppWeb.SentControllerTest do + use AppWeb.ConnCase + + alias App.Ctx + + @create_attrs %{message_id: "some message_id", request_id: "some request_id", template: "some template"} + @update_attrs %{message_id: "some updated message_id", request_id: "some updated request_id", template: "some updated template"} + @invalid_attrs %{message_id: nil, request_id: nil, template: nil} + + def fixture(:sent) do + {:ok, sent} = Ctx.create_sent(@create_attrs) + sent + end + + describe "index" do + test "lists all sent", %{conn: conn} do + conn = get(conn, Routes.sent_path(conn, :index)) + assert html_response(conn, 200) =~ "Listing Sent" + end + end + + describe "new sent" do + test "renders form", %{conn: conn} do + conn = get(conn, Routes.sent_path(conn, :new)) + assert html_response(conn, 200) =~ "New Sent" + end + end + + describe "create sent" do + test "redirects to show when data is valid", %{conn: conn} do + conn = post(conn, Routes.sent_path(conn, :create), sent: @create_attrs) + + assert %{id: id} = redirected_params(conn) + assert redirected_to(conn) == Routes.sent_path(conn, :show, id) + + conn = get(conn, Routes.sent_path(conn, :show, id)) + assert html_response(conn, 200) =~ "Show Sent" + end + + test "renders errors when data is invalid", %{conn: conn} do + conn = post(conn, Routes.sent_path(conn, :create), sent: @invalid_attrs) + assert html_response(conn, 200) =~ "New Sent" + end + end + + describe "edit sent" do + setup [:create_sent] + + test "renders form for editing chosen sent", %{conn: conn, sent: sent} do + conn = get(conn, Routes.sent_path(conn, :edit, sent)) + assert html_response(conn, 200) =~ "Edit Sent" + end + end + + describe "update sent" do + setup [:create_sent] + + test "redirects when data is valid", %{conn: conn, sent: sent} do + conn = put(conn, Routes.sent_path(conn, :update, sent), sent: @update_attrs) + assert redirected_to(conn) == Routes.sent_path(conn, :show, sent) + + conn = get(conn, Routes.sent_path(conn, :show, sent)) + assert html_response(conn, 200) =~ "some updated message_id" + end + + test "renders errors when data is invalid", %{conn: conn, sent: sent} do + conn = put(conn, Routes.sent_path(conn, :update, sent), sent: @invalid_attrs) + assert html_response(conn, 200) =~ "Edit Sent" + end + end + + describe "delete sent" do + setup [:create_sent] + + test "deletes chosen sent", %{conn: conn, sent: sent} do + conn = delete(conn, Routes.sent_path(conn, :delete, sent)) + assert redirected_to(conn) == Routes.sent_path(conn, :index) + assert_error_sent 404, fn -> + get(conn, Routes.sent_path(conn, :show, sent)) + end + end + end + + defp create_sent(_) do + sent = fixture(:sent) + {:ok, sent: sent} + end +end