From bd43a1f7bdd34e49370649339f49fd8f2f015258 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Thu, 7 Mar 2024 13:33:52 -1000 Subject: [PATCH 1/7] feat(post-draft): add initial model for post drafts --- .iex.exs | 1 + lib/epochtalk_server/models/post_draft.ex | 29 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 lib/epochtalk_server/models/post_draft.ex diff --git a/.iex.exs b/.iex.exs index 3d76b6b3..8f7059e6 100644 --- a/.iex.exs +++ b/.iex.exs @@ -22,6 +22,7 @@ alias EpochtalkServer.Models.{ Notification, Permission, Post, + PostDraft, Poll, PollAnswer, PollResponse, diff --git a/lib/epochtalk_server/models/post_draft.ex b/lib/epochtalk_server/models/post_draft.ex new file mode 100644 index 00000000..109ccb93 --- /dev/null +++ b/lib/epochtalk_server/models/post_draft.ex @@ -0,0 +1,29 @@ +defmodule EpochtalkServer.Models.PostDraft do + use Ecto.Schema + # alias EpochtalkServer.Repo + alias EpochtalkServer.Models.User + + @moduledoc """ + `PostDraft` model, for performing actions relating to a `User`'s `Post` draft + """ + @type t :: %__MODULE__{ + user_id: non_neg_integer | nil, + draft: String.t() | nil, + updated_at: NaiveDateTime.t() | nil + } + @derive {Jason.Encoder, + only: [ + :user_id, + :draft, + :updated_at + ]} + @schema_prefix "posts" + @primary_key false + schema "user_drafts" do + belongs_to :user, User + field :draft, :string + field :updated_at, :naive_datetime + end + + ## === Database Functions === +end From 844777112b51fd102a23ba0fec560afb99cdefe3 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Mon, 11 Mar 2024 14:43:11 -1000 Subject: [PATCH 2/7] feat(post-draft): implement db create function --- lib/epochtalk_server/models/post_draft.ex | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/epochtalk_server/models/post_draft.ex b/lib/epochtalk_server/models/post_draft.ex index 109ccb93..e2a373ac 100644 --- a/lib/epochtalk_server/models/post_draft.ex +++ b/lib/epochtalk_server/models/post_draft.ex @@ -1,7 +1,9 @@ defmodule EpochtalkServer.Models.PostDraft do use Ecto.Schema - # alias EpochtalkServer.Repo + import Ecto.Query + alias EpochtalkServer.Repo alias EpochtalkServer.Models.User + alias EpochtalkServer.Models.PostDraft @moduledoc """ `PostDraft` model, for performing actions relating to a `User`'s `Post` draft @@ -26,4 +28,17 @@ defmodule EpochtalkServer.Models.PostDraft do end ## === Database Functions === + + @doc """ + Returns `PostDraft` Data given a `User` id + """ + @spec by_user_id(user_id :: integer) :: t() | nil + def by_user_id(user_id) do + query = + from p in PostDraft, + where: p.user_id == ^user_id + + Repo.one(query) + end + end From 0a108d21fdb617af84d973e0a25fdb344226e3ae Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Mon, 11 Mar 2024 14:44:07 -1000 Subject: [PATCH 3/7] feat(post-drafts): implement db upsert function --- lib/epochtalk_server/models/post_draft.ex | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/epochtalk_server/models/post_draft.ex b/lib/epochtalk_server/models/post_draft.ex index e2a373ac..5d1f8c60 100644 --- a/lib/epochtalk_server/models/post_draft.ex +++ b/lib/epochtalk_server/models/post_draft.ex @@ -41,4 +41,19 @@ defmodule EpochtalkServer.Models.PostDraft do Repo.one(query) end + @doc """ + Used to upsert a `PostDraft` for a specific `User` + """ + @spec upsert(user_id :: non_neg_integer, draft :: String.t()) :: + {:ok, t()} | {:error, Ecto.Changeset.t()} + def upsert(user_id, draft) when is_integer(user_id) and is_binary(draft) do + now = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + + Repo.insert( + %PostDraft{user_id: user_id, draft: draft, updated_at: now}, + on_conflict: [set: [draft: draft, updated_at: now]], + conflict_target: [:user_id] + ) + end + end From e86ab2f159fc10d06776f2012e4545387b11885a Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Tue, 12 Mar 2024 15:29:23 -1000 Subject: [PATCH 4/7] feat(post-drafts): full implement post drafts with testing --- lib/epochtalk_server/models/poll_answer.ex | 1 - lib/epochtalk_server/models/post_draft.ex | 38 ++++++-- .../controllers/mention.ex | 2 +- .../controllers/notification.ex | 6 +- lib/epochtalk_server_web/controllers/post.ex | 4 +- .../controllers/post_draft.ex | 41 +++++++++ .../controllers/preference.ex | 2 +- lib/epochtalk_server_web/controllers/role.ex | 4 +- .../controllers/thread.ex | 2 +- .../json/post_draft_json.ex | 38 ++++++++ lib/epochtalk_server_web/router.ex | 2 + .../controllers/post_draft_test.exs | 91 +++++++++++++++++++ .../json/post_draft_json_test.exs | 7 ++ test/support/factories/post_draft.ex | 22 +++++ test/support/factory.ex | 1 + 15 files changed, 244 insertions(+), 17 deletions(-) create mode 100644 lib/epochtalk_server_web/controllers/post_draft.ex create mode 100644 lib/epochtalk_server_web/json/post_draft_json.ex create mode 100644 test/epochtalk_server_web/controllers/post_draft_test.exs create mode 100644 test/epochtalk_server_web/json/post_draft_json_test.exs create mode 100644 test/support/factories/post_draft.ex diff --git a/lib/epochtalk_server/models/poll_answer.ex b/lib/epochtalk_server/models/poll_answer.ex index 0574dab1..e92f6dab 100644 --- a/lib/epochtalk_server/models/poll_answer.ex +++ b/lib/epochtalk_server/models/poll_answer.ex @@ -1,7 +1,6 @@ defmodule EpochtalkServer.Models.PollAnswer do use Ecto.Schema import Ecto.Changeset - # import Ecto.Query alias EpochtalkServer.Repo alias EpochtalkServer.Models.PollAnswer alias EpochtalkServer.Models.Poll diff --git a/lib/epochtalk_server/models/post_draft.ex b/lib/epochtalk_server/models/post_draft.ex index 5d1f8c60..d1600a33 100644 --- a/lib/epochtalk_server/models/post_draft.ex +++ b/lib/epochtalk_server/models/post_draft.ex @@ -1,6 +1,7 @@ defmodule EpochtalkServer.Models.PostDraft do use Ecto.Schema import Ecto.Query + import Ecto.Changeset alias EpochtalkServer.Repo alias EpochtalkServer.Models.User alias EpochtalkServer.Models.PostDraft @@ -27,6 +28,27 @@ defmodule EpochtalkServer.Models.PostDraft do field :updated_at, :naive_datetime end + ## === Changeset Functions === + + @doc """ + Create a changeset for upserting a `PostDraft` + """ + @spec upsert_changeset(draft :: PostDraft.t(), attrs :: map() | nil) :: Ecto.Changeset.t() + def upsert_changeset(draft, attrs \\ %{}) do + updated_at = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + + draft = + draft + |> Map.put(:updated_at, updated_at) + + draft + |> cast(attrs, [:user_id, :draft, :updated_at]) + |> validate_required([:user_id, :updated_at]) + |> validate_length(:draft, min: 1, max: 64_000) + |> unique_constraint(:user_id, name: :user_drafts_user_id_index) + |> foreign_key_constraint(:user_id, name: :user_drafts_user_id_fkey) + end + ## === Database Functions === @doc """ @@ -44,16 +66,20 @@ defmodule EpochtalkServer.Models.PostDraft do @doc """ Used to upsert a `PostDraft` for a specific `User` """ - @spec upsert(user_id :: non_neg_integer, draft :: String.t()) :: + @spec upsert(user_id :: non_neg_integer, attrs :: map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()} - def upsert(user_id, draft) when is_integer(user_id) and is_binary(draft) do - now = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + def upsert(user_id, attrs) when is_integer(user_id) do + post_draft_cs = upsert_changeset(%PostDraft{user_id: user_id}, attrs) Repo.insert( - %PostDraft{user_id: user_id, draft: draft, updated_at: now}, - on_conflict: [set: [draft: draft, updated_at: now]], + post_draft_cs, + on_conflict: [ + set: [ + draft: Map.get(post_draft_cs.changes, :draft), + updated_at: Map.get(post_draft_cs.data, :updated_at) + ] + ], conflict_target: [:user_id] ) end - end diff --git a/lib/epochtalk_server_web/controllers/mention.ex b/lib/epochtalk_server_web/controllers/mention.ex index 1e0aa15d..6a683cdc 100644 --- a/lib/epochtalk_server_web/controllers/mention.ex +++ b/lib/epochtalk_server_web/controllers/mention.ex @@ -18,7 +18,7 @@ defmodule EpochtalkServerWeb.Controllers.Mention do limit <- Validate.cast(attrs, "limit", :integer, min: 1), extended <- Validate.cast(attrs, "extended", :boolean), :ok <- ACL.allow!(conn, "mentions.page"), - {:auth, user} <- {:auth, Guardian.Plug.current_resource(conn)}, + {:auth, %{} = user} <- {:auth, Guardian.Plug.current_resource(conn)}, {:ok, mentions, data} <- Mention.page_by_user_id(user.id, page, per_page: limit, extended: extended), do: diff --git a/lib/epochtalk_server_web/controllers/notification.ex b/lib/epochtalk_server_web/controllers/notification.ex index 618f1f4e..8a9ffbdf 100644 --- a/lib/epochtalk_server_web/controllers/notification.ex +++ b/lib/epochtalk_server_web/controllers/notification.ex @@ -14,7 +14,7 @@ defmodule EpochtalkServerWeb.Controllers.Notification do Used to retrieve `Notification` counts for a specific `User` """ def counts(conn, attrs) do - with {:auth, user} <- {:auth, Guardian.Plug.current_resource(conn)}, + with {:auth, %{} = user} <- {:auth, Guardian.Plug.current_resource(conn)}, :ok <- ACL.allow!(conn, "notifications.counts"), max <- Validate.cast(attrs, "max", :integer, min: 1) do render(conn, :counts, data: Notification.counts_by_user_id(user.id, max: max || 99)) @@ -39,7 +39,7 @@ defmodule EpochtalkServerWeb.Controllers.Notification do Used to dismiss `Notification` counts for a specific `User` """ def dismiss(conn, %{"id" => id}) do - with {:auth, user} <- {:auth, Guardian.Plug.current_resource(conn)}, + with {:auth, %{} = user} <- {:auth, Guardian.Plug.current_resource(conn)}, :ok <- ACL.allow!(conn, "notifications.dismiss"), {_count, nil} <- Notification.dismiss(id) do EpochtalkServerWeb.Endpoint.broadcast("user:#{user.id}", "refreshMentions", %{}) @@ -62,7 +62,7 @@ defmodule EpochtalkServerWeb.Controllers.Notification do end def dismiss(conn, %{"type" => type}) do - with {:auth, user} <- {:auth, Guardian.Plug.current_resource(conn)}, + with {:auth, %{} = user} <- {:auth, Guardian.Plug.current_resource(conn)}, :ok <- ACL.allow!(conn, "notifications.dismiss"), {_count, nil} <- Notification.dismiss_type_by_user_id(user.id, type) do EpochtalkServerWeb.Endpoint.broadcast("user:#{user.id}", "refreshMentions", %{}) diff --git a/lib/epochtalk_server_web/controllers/post.ex b/lib/epochtalk_server_web/controllers/post.ex index 54be894c..e93728a3 100644 --- a/lib/epochtalk_server_web/controllers/post.ex +++ b/lib/epochtalk_server_web/controllers/post.ex @@ -40,7 +40,7 @@ defmodule EpochtalkServerWeb.Controllers.Post do # * Ensure mentions and notifications are created def create(conn, attrs) do # Authorizations Checks - with {:auth, user} <- {:auth, Guardian.Plug.current_resource(conn)}, + with {:auth, %{} = user} <- {:auth, Guardian.Plug.current_resource(conn)}, :ok <- ACL.allow!(conn, "posts.create"), # normally we use model changesets for validating POST requests parameters, # this is an exception to save us from doing excessive processing between here @@ -144,7 +144,7 @@ defmodule EpochtalkServerWeb.Controllers.Post do """ def update(conn, attrs) do # Authorizations Checks - with {:auth, user} <- {:auth, Guardian.Plug.current_resource(conn)}, + with {:auth, %{} = user} <- {:auth, Guardian.Plug.current_resource(conn)}, :ok <- ACL.allow!(conn, "posts.update"), # normally we use model changesets for validating POST requests parameters, # this is an exception to save us from doing excessive processing between here diff --git a/lib/epochtalk_server_web/controllers/post_draft.ex b/lib/epochtalk_server_web/controllers/post_draft.ex new file mode 100644 index 00000000..2bfabf21 --- /dev/null +++ b/lib/epochtalk_server_web/controllers/post_draft.ex @@ -0,0 +1,41 @@ +defmodule EpochtalkServerWeb.Controllers.PostDraft do + use EpochtalkServerWeb, :controller + + @moduledoc """ + Controller for `PostDraft` related API requests + """ + alias EpochtalkServer.Auth.Guardian + alias EpochtalkServerWeb.ErrorHelpers + alias EpochtalkServer.Models.PostDraft + + @doc """ + Used to upsert a specific `PostDraft` + + Returns `PostDraft` on success + """ + def upsert(conn, attrs) do + with {:auth, %{} = user} <- {:auth, Guardian.Plug.current_resource(conn)}, + {:ok, draft_data} <- PostDraft.upsert(user.id, attrs) do + render(conn, :upsert, %{draft_data: draft_data, user_id: user.id}) + else + {:auth, nil} -> + ErrorHelpers.render_json_error(conn, 400, "Not logged in, cannot upsert post draft") + + {:error, data} -> + ErrorHelpers.render_json_error(conn, 400, data) + end + end + + @doc """ + Get `PostDraft` by `User` id + """ + def by_user_id(conn, _) do + with {:auth, %{} = user} <- {:auth, Guardian.Plug.current_resource(conn)}, + draft_data <- PostDraft.by_user_id(user.id) do + render(conn, :by_user_id, %{draft_data: draft_data, user_id: user.id}) + else + {:auth, nil} -> + ErrorHelpers.render_json_error(conn, 400, "Not logged in, cannot get post draft") + end + end +end diff --git a/lib/epochtalk_server_web/controllers/preference.ex b/lib/epochtalk_server_web/controllers/preference.ex index f2f22222..0e7405a2 100644 --- a/lib/epochtalk_server_web/controllers/preference.ex +++ b/lib/epochtalk_server_web/controllers/preference.ex @@ -12,7 +12,7 @@ defmodule EpochtalkServerWeb.Controllers.Preference do Used to retrieve preferences of a specific `User` """ def preferences(conn, _attrs) do - with {:auth, user} <- {:auth, Guardian.Plug.current_resource(conn)}, + with {:auth, %{} = user} <- {:auth, Guardian.Plug.current_resource(conn)}, do: render(conn, :preferences, preferences: Preference.by_user_id(user.id)), else: ({:auth, nil} -> diff --git a/lib/epochtalk_server_web/controllers/role.ex b/lib/epochtalk_server_web/controllers/role.ex index bfb560ce..17fa61dd 100644 --- a/lib/epochtalk_server_web/controllers/role.ex +++ b/lib/epochtalk_server_web/controllers/role.ex @@ -16,7 +16,7 @@ defmodule EpochtalkServerWeb.Controllers.Role do Returns id of `Role` on success """ def update(conn, attrs) do - with {:auth, _user} <- {:auth, Guardian.Plug.current_resource(conn)}, + with {:auth, %{} = _user} <- {:auth, Guardian.Plug.current_resource(conn)}, :ok <- ACL.allow!(conn, "roles.update"), {:ok, _role_permission_data} <- RolePermission.modify_by_role(attrs), {:ok, _role_data} <- Role.update(attrs) do @@ -34,7 +34,7 @@ defmodule EpochtalkServerWeb.Controllers.Role do Get all `Role`s """ def all(conn, _) do - with {:auth, _user} <- {:auth, Guardian.Plug.current_resource(conn)}, + with {:auth, %{} = _user} <- {:auth, Guardian.Plug.current_resource(conn)}, roles <- Role.all() do render(conn, :all, roles: roles) else diff --git a/lib/epochtalk_server_web/controllers/thread.ex b/lib/epochtalk_server_web/controllers/thread.ex index 8a389c1d..6988697f 100644 --- a/lib/epochtalk_server_web/controllers/thread.ex +++ b/lib/epochtalk_server_web/controllers/thread.ex @@ -52,7 +52,7 @@ defmodule EpochtalkServerWeb.Controllers.Thread do # authorization checks with :ok <- ACL.allow!(conn, "threads.create"), board_id <- Validate.cast(attrs, "board_id", :integer, required: true), - {:auth, user} <- {:auth, Guardian.Plug.current_resource(conn)}, + {:auth, %{} = user} <- {:auth, Guardian.Plug.current_resource(conn)}, user_priority <- ACL.get_user_priority(conn), {:can_read, {:ok, true}} <- {:can_read, Board.get_read_access_by_id(board_id, user_priority)}, diff --git a/lib/epochtalk_server_web/json/post_draft_json.ex b/lib/epochtalk_server_web/json/post_draft_json.ex new file mode 100644 index 00000000..5645b3c6 --- /dev/null +++ b/lib/epochtalk_server_web/json/post_draft_json.ex @@ -0,0 +1,38 @@ +defmodule EpochtalkServerWeb.Controllers.PostDraftJSON do + @moduledoc """ + Renders and formats `PostDraft` data, in JSON format for frontend + """ + + @doc """ + Renders `PostDraft` upsert result data in JSON + + ## Example + iex> draft_data = %{ + iex> user_id: 99, + iex> draft: "Hello world", + iex> updated_at: ~N[2024-03-12 01:28:15] + iex> } + iex> EpochtalkServerWeb.Controllers.PostDraftJSON.upsert(%{draft_data: draft_data}) + draft_data + """ + def upsert(%{draft_data: draft_data}), do: draft_data + + @doc """ + Renders `PostDraft` by_user_id result data in JSON + + ## Example + iex> EpochtalkServerWeb.Controllers.PostDraftJSON.by_user_id(%{draft_data: nil, user_id: 98}) + %{user_id: 98, draft: nil, updated_at: nil} + iex> draft_data = %{ + iex> user_id: 98, + iex> draft: "Hello world", + iex> updated_at: ~N[2024-03-12 01:28:15] + iex> } + iex> EpochtalkServerWeb.Controllers.PostDraftJSON.by_user_id(%{draft_data: draft_data, user_id: 98}) + draft_data + """ + def by_user_id(%{draft_data: nil, user_id: user_id}), + do: %{user_id: user_id, draft: nil, updated_at: nil} + + def by_user_id(%{draft_data: draft_data, user_id: _user_id}), do: draft_data +end diff --git a/lib/epochtalk_server_web/router.ex b/lib/epochtalk_server_web/router.ex index 4ba044e3..116ab89b 100644 --- a/lib/epochtalk_server_web/router.ex +++ b/lib/epochtalk_server_web/router.ex @@ -64,6 +64,8 @@ defmodule EpochtalkServerWeb.Router do get "/register/username/:username", User, :username get "/register/email/:email", User, :email get "/posts", Post, :by_thread + get "/posts/draft", PostDraft, :by_user_id + put "/posts/draft", PostDraft, :upsert post "/posts", Post, :create post "/posts/:id", Post, :update post "/register", User, :register diff --git a/test/epochtalk_server_web/controllers/post_draft_test.exs b/test/epochtalk_server_web/controllers/post_draft_test.exs new file mode 100644 index 00000000..73e62cfb --- /dev/null +++ b/test/epochtalk_server_web/controllers/post_draft_test.exs @@ -0,0 +1,91 @@ +defmodule Test.EpochtalkServerWeb.Controllers.PostDraft do + use Test.Support.ConnCase, async: true + import Test.Support.Factory + + setup %{users: %{admin_user: admin_user}} do + draft_data = + build(:post_draft, %{ + user_id: admin_user.id, + draft: "draft test" + }) + + {:ok, draft_data: draft_data} + end + + describe "by_user_id/1" do + test "when unauthenticated, returns Unauthorized error", %{conn: conn} do + response = + conn + |> get(Routes.post_draft_path(conn, :by_user_id)) + |> json_response(400) + + assert response["error"] == "Bad Request" + assert response["message"] == "Not logged in, cannot get post draft" + end + + @tag :authenticated + test "when authenticated with no existing post draft, returns empty post draft", + %{conn: conn, users: %{user: user}} do + response = + conn + |> get(Routes.post_draft_path(conn, :by_user_id)) + |> json_response(200) + + assert response["user_id"] == user.id + assert response["draft"] == nil + assert response["updated_at"] == nil + end + + @tag authenticated: :admin + test "when authenticated with an existing post draft, returns existing post draft", + %{conn: conn, users: %{admin_user: admin_user}, draft_data: draft_data} do + response = + conn + |> get(Routes.post_draft_path(conn, :by_user_id)) + |> json_response(200) + + assert response["user_id"] == admin_user.id + assert response["draft"] == draft_data.draft + assert response["updated_at"] != nil + end + end + + describe "upsert/1" do + test "when unauthenticated, returns Unauthorized error", %{conn: conn} do + response = + conn + |> put(Routes.post_draft_path(conn, :upsert), %{"draft" => "Hello World"}) + |> json_response(400) + + assert response["error"] == "Bad Request" + assert response["message"] == "Not logged in, cannot upsert post draft" + end + + @tag :authenticated + test "when authenticated with no existing post draft, creates and returns new post draft", + %{conn: conn, users: %{user: user}} do + response = + conn + |> put(Routes.post_draft_path(conn, :upsert), %{"draft" => "Hello World"}) + |> json_response(200) + + assert response["user_id"] == user.id + assert response["draft"] == "Hello World" + assert response["updated_at"] != nil + end + + @tag authenticated: :admin + test "when authenticated with an existing post draft, overrides existing and reutnrs new post draft", + %{conn: conn, users: %{admin_user: admin_user}, draft_data: draft_data} do + response = + conn + |> put(Routes.post_draft_path(conn, :upsert), %{"draft" => "Hello World"}) + |> json_response(200) + + assert response["user_id"] == admin_user.id + assert response["draft"] != draft_data.draft + assert response["draft"] == "Hello World" + assert response["updated_at"] != nil + end + end +end diff --git a/test/epochtalk_server_web/json/post_draft_json_test.exs b/test/epochtalk_server_web/json/post_draft_json_test.exs new file mode 100644 index 00000000..d1120a70 --- /dev/null +++ b/test/epochtalk_server_web/json/post_draft_json_test.exs @@ -0,0 +1,7 @@ +defmodule Test.EpochtalkServerWeb.Controllers.PostDraftJSON do + use Test.Support.ConnCase, async: true + alias EpochtalkServerWeb.Controllers.PostDraftJSON + + # Specify that we want to use doctests: + doctest PostDraftJSON +end diff --git a/test/support/factories/post_draft.ex b/test/support/factories/post_draft.ex new file mode 100644 index 00000000..8b809a4f --- /dev/null +++ b/test/support/factories/post_draft.ex @@ -0,0 +1,22 @@ +defmodule Test.Support.Factories.PostDraft do + @moduledoc """ + Factory for `PostDraft` + """ + alias EpochtalkServer.Models.PostDraft + + defmacro __using__(_opts) do + quote do + def post_draft_factory( + %{ + user_id: user_id, + draft: draft + } = attrs + ) do + PostDraft.upsert(user_id, %{"draft" => draft}) + |> case do + {:ok, draft} -> draft + end + end + end + end +end diff --git a/test/support/factory.ex b/test/support/factory.ex index 14f4022f..5fe4c778 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -14,6 +14,7 @@ defmodule Test.Support.Factory do use Test.Support.Factories.Thread use Test.Support.Factories.Mention use Test.Support.Factories.Notification + use Test.Support.Factories.PostDraft use Test.Support.Factories.BannedAddress use Test.Support.Factories.ModerationLog end From 922174a68dd555a27930f4f0e5c3c486d739aa26 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Tue, 19 Mar 2024 11:02:53 -1000 Subject: [PATCH 5/7] test(post-draft): fix spelling for post-draft test --- test/epochtalk_server_web/controllers/post_draft_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/epochtalk_server_web/controllers/post_draft_test.exs b/test/epochtalk_server_web/controllers/post_draft_test.exs index 73e62cfb..d60dc32b 100644 --- a/test/epochtalk_server_web/controllers/post_draft_test.exs +++ b/test/epochtalk_server_web/controllers/post_draft_test.exs @@ -75,7 +75,7 @@ defmodule Test.EpochtalkServerWeb.Controllers.PostDraft do end @tag authenticated: :admin - test "when authenticated with an existing post draft, overrides existing and reutnrs new post draft", + test "when authenticated with an existing post draft, overrides existing and returns new post draft", %{conn: conn, users: %{admin_user: admin_user}, draft_data: draft_data} do response = conn From c2c1222c743b584ae24e8cc31248e8c7e0d19bb9 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Tue, 19 Mar 2024 11:06:58 -1000 Subject: [PATCH 6/7] fix(correct-status-code): use correct status code for not logged in post draft routes --- lib/epochtalk_server_web/controllers/post_draft.ex | 4 ++-- test/epochtalk_server_web/controllers/post_draft_test.exs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/epochtalk_server_web/controllers/post_draft.ex b/lib/epochtalk_server_web/controllers/post_draft.ex index 2bfabf21..3c7a88b5 100644 --- a/lib/epochtalk_server_web/controllers/post_draft.ex +++ b/lib/epochtalk_server_web/controllers/post_draft.ex @@ -19,7 +19,7 @@ defmodule EpochtalkServerWeb.Controllers.PostDraft do render(conn, :upsert, %{draft_data: draft_data, user_id: user.id}) else {:auth, nil} -> - ErrorHelpers.render_json_error(conn, 400, "Not logged in, cannot upsert post draft") + ErrorHelpers.render_json_error(conn, 403, "Not logged in, cannot upsert post draft") {:error, data} -> ErrorHelpers.render_json_error(conn, 400, data) @@ -35,7 +35,7 @@ defmodule EpochtalkServerWeb.Controllers.PostDraft do render(conn, :by_user_id, %{draft_data: draft_data, user_id: user.id}) else {:auth, nil} -> - ErrorHelpers.render_json_error(conn, 400, "Not logged in, cannot get post draft") + ErrorHelpers.render_json_error(conn, 403, "Not logged in, cannot get post draft") end end end diff --git a/test/epochtalk_server_web/controllers/post_draft_test.exs b/test/epochtalk_server_web/controllers/post_draft_test.exs index d60dc32b..6c29e987 100644 --- a/test/epochtalk_server_web/controllers/post_draft_test.exs +++ b/test/epochtalk_server_web/controllers/post_draft_test.exs @@ -17,7 +17,7 @@ defmodule Test.EpochtalkServerWeb.Controllers.PostDraft do response = conn |> get(Routes.post_draft_path(conn, :by_user_id)) - |> json_response(400) + |> json_response(403) assert response["error"] == "Bad Request" assert response["message"] == "Not logged in, cannot get post draft" @@ -55,7 +55,7 @@ defmodule Test.EpochtalkServerWeb.Controllers.PostDraft do response = conn |> put(Routes.post_draft_path(conn, :upsert), %{"draft" => "Hello World"}) - |> json_response(400) + |> json_response(403) assert response["error"] == "Bad Request" assert response["message"] == "Not logged in, cannot upsert post draft" From 181bc9077f6f3de2f2e73e0c6b873ad09a772b1b Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Tue, 19 Mar 2024 11:13:58 -1000 Subject: [PATCH 7/7] fix(correct-status-msg): use correct status message for not logged in post draft routes --- test/epochtalk_server_web/controllers/post_draft_test.exs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/epochtalk_server_web/controllers/post_draft_test.exs b/test/epochtalk_server_web/controllers/post_draft_test.exs index 6c29e987..a77270af 100644 --- a/test/epochtalk_server_web/controllers/post_draft_test.exs +++ b/test/epochtalk_server_web/controllers/post_draft_test.exs @@ -19,7 +19,7 @@ defmodule Test.EpochtalkServerWeb.Controllers.PostDraft do |> get(Routes.post_draft_path(conn, :by_user_id)) |> json_response(403) - assert response["error"] == "Bad Request" + assert response["error"] == "Forbidden" assert response["message"] == "Not logged in, cannot get post draft" end @@ -57,7 +57,7 @@ defmodule Test.EpochtalkServerWeb.Controllers.PostDraft do |> put(Routes.post_draft_path(conn, :upsert), %{"draft" => "Hello World"}) |> json_response(403) - assert response["error"] == "Bad Request" + assert response["error"] == "Forbidden" assert response["message"] == "Not logged in, cannot upsert post draft" end