From c05af04fc59c89e26dca79c99f217f327cec0ed1 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Sun, 4 Dec 2022 04:33:10 +0000 Subject: [PATCH] Add tests for mastodonAPI hashtag follows --- lib/pleroma/user.ex | 2 +- lib/pleroma/user/hashtag_follow.ex | 7 +- .../web/api_spec/operations/tag_operation.ex | 4 +- .../controllers/tag_controller.ex | 10 +- .../web/mastodon_api/views/tag_view.ex | 2 +- test/pleroma/user_test.exs | 6 +- .../controllers/tag_controller_test.exs | 97 +++++++++++++++++++ 7 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 test/pleroma/web/mastodon_api/controllers/tag_controller_test.exs diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 5f16b1d52..b4d7aac35 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -2584,7 +2584,7 @@ defmodule Pleroma.User do Logger.debug("Unfollow hashtag #{hashtag.name} for user #{user.nickname}") user = maybe_load_followed_hashtags(user) - with {_, nil} <- HashtagFollow.delete(user, hashtag), + with {:ok, _} <- HashtagFollow.delete(user, hashtag), follows <- HashtagFollow.get_by_user(user), %User{} = user <- user |> Map.put(:followed_hashtags, follows) do user diff --git a/lib/pleroma/user/hashtag_follow.ex b/lib/pleroma/user/hashtag_follow.ex index 2fb9006ec..43ed93f4d 100644 --- a/lib/pleroma/user/hashtag_follow.ex +++ b/lib/pleroma/user/hashtag_follow.ex @@ -29,8 +29,11 @@ defmodule Pleroma.User.HashtagFollow do end def delete(%User{} = user, %Hashtag{} = hashtag) do - get(user, hashtag) - |> Repo.delete() + with %__MODULE__{} = user_hashtag_follow <- get(user, hashtag) do + Repo.delete(user_hashtag_follow) + else + _ -> {:ok, nil} + end end def get(%User{} = user, %Hashtag{} = hashtag) do diff --git a/lib/pleroma/web/api_spec/operations/tag_operation.ex b/lib/pleroma/web/api_spec/operations/tag_operation.ex index d5fd76220..e22457159 100644 --- a/lib/pleroma/web/api_spec/operations/tag_operation.ex +++ b/lib/pleroma/web/api_spec/operations/tag_operation.ex @@ -2,7 +2,7 @@ defmodule Pleroma.Web.ApiSpec.TagOperation do alias OpenApiSpex.Operation alias OpenApiSpex.Schema alias Pleroma.Web.ApiSpec.Schemas.ApiError - alias Pleroma.Web.ApiSpec.Schemas.Tag + alias Pleroma.Web.ApiSpec.Schemas.Tag def open_api_operation(action) do operation = String.to_existing_atom("#{action}_operation") @@ -29,7 +29,7 @@ defmodule Pleroma.Web.ApiSpec.TagOperation do tags: ["Tags"], summary: "Follow a hashtag", description: "Follow a hashtag", - security: [%{"oAuth" => ["write:follow"]}], + security: [%{"oAuth" => ["write:follows"]}], parameters: [id_param()], operationId: "TagController.follow", responses: %{ diff --git a/lib/pleroma/web/mastodon_api/controllers/tag_controller.ex b/lib/pleroma/web/mastodon_api/controllers/tag_controller.ex index 50455d1f7..b8995eb00 100644 --- a/lib/pleroma/web/mastodon_api/controllers/tag_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/tag_controller.ex @@ -15,7 +15,7 @@ defmodule Pleroma.Web.MastodonAPI.TagController do defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TagOperation - def show(conn, %{id: id} = params) do + def show(conn, %{id: id}) do with %Hashtag{} = hashtag <- Hashtag.get_by_name(id) do render(conn, "show.json", tag: hashtag, for_user: conn.assigns.user) else @@ -23,23 +23,23 @@ defmodule Pleroma.Web.MastodonAPI.TagController do end end - def follow(conn, %{id: id} = params) do + def follow(conn, %{id: id}) do with %Hashtag{} = hashtag <- Hashtag.get_by_name(id), %User{} = user <- conn.assigns.user, {:ok, _} <- User.follow_hashtag(user, hashtag) do - render(conn, "show.json", tag: params["tag"], for_user: user) + render(conn, "show.json", tag: hashtag, for_user: user) else _ -> render_error(conn, :not_found, "Hashtag not found") end end - def unfollow(conn, %{id: id} = params) do + def unfollow(conn, %{id: id}) do with %Hashtag{} = hashtag <- Hashtag.get_by_name(id), %User{} = user <- conn.assigns.user, {:ok, _} <- User.unfollow_hashtag(user, hashtag) do - render(conn, "show.json", tag: params["tag"], for_user: user) + render(conn, "show.json", tag: hashtag, for_user: user) else _ -> render_error(conn, :not_found, "Hashtag not found") end diff --git a/lib/pleroma/web/mastodon_api/views/tag_view.ex b/lib/pleroma/web/mastodon_api/views/tag_view.ex index 8a1c1bb8b..6e491c261 100644 --- a/lib/pleroma/web/mastodon_api/views/tag_view.ex +++ b/lib/pleroma/web/mastodon_api/views/tag_view.ex @@ -13,7 +13,7 @@ defmodule Pleroma.Web.MastodonAPI.TagView do %{ name: tag.name, - url: Helpers.tag_url(Pleroma.Web.Endpoint, :show, tag), + url: Helpers.tag_feed_url(Pleroma.Web.Endpoint, :feed, tag.name), history: [], following: following } diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index db5c753d5..cc6634aba 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -2729,7 +2729,7 @@ defmodule Pleroma.UserTest do hashtag = insert(:hashtag) assert {:ok, _} = user |> User.follow_hashtag(hashtag) - assert {1, nil} = user |> User.unfollow_hashtag(hashtag) + assert {:ok, _} = user |> User.unfollow_hashtag(hashtag) user = User.get_cached_by_ap_id(user.ap_id) @@ -2741,8 +2741,8 @@ defmodule Pleroma.UserTest do hashtag = insert(:hashtag) assert {:ok, _} = user |> User.follow_hashtag(hashtag) - assert {1, nil} = user |> User.unfollow_hashtag(hashtag) - assert {0, nil} = user |> User.unfollow_hashtag(hashtag) + assert {:ok, _} = user |> User.unfollow_hashtag(hashtag) + assert {:ok, _} = user |> User.unfollow_hashtag(hashtag) user = User.get_cached_by_ap_id(user.ap_id) diff --git a/test/pleroma/web/mastodon_api/controllers/tag_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/tag_controller_test.exs new file mode 100644 index 000000000..a1b73ad78 --- /dev/null +++ b/test/pleroma/web/mastodon_api/controllers/tag_controller_test.exs @@ -0,0 +1,97 @@ +defmodule Pleroma.Web.MastodonAPI.TagControllerTest do + use Pleroma.Web.ConnCase + + import Pleroma.Factory + import Tesla.Mock + + alias Pleroma.User + + setup do + mock(fn env -> apply(HttpRequestMock, :request, [env]) end) + :ok + end + + describe "GET /api/v1/tags/:id" do + test "returns 200 with tag" do + %{user: user, conn: conn} = oauth_access(["read"]) + + tag = insert(:hashtag, name: "jubjub") + {:ok, _user} = User.follow_hashtag(user, tag) + + response = + conn + |> get("/api/v1/tags/jubjub") + |> json_response_and_validate_schema(200) + + assert %{ + "name" => "jubjub", + "url" => "http://localhost:4001/tags/jubjub", + "history" => [], + "following" => true + } = response + end + + test "returns 404 with unknown tag" do + %{conn: conn} = oauth_access(["read"]) + + conn + |> get("/api/v1/tags/jubjub") + |> json_response_and_validate_schema(404) + end + end + + describe "POST /api/v1/tags/:id/follow" do + test "should follow a hashtag" do + %{user: user, conn: conn} = oauth_access(["write:follows"]) + hashtag = insert(:hashtag, name: "jubjub") + + response = + conn + |> post("/api/v1/tags/jubjub/follow") + |> json_response_and_validate_schema(200) + + assert response["following"] == true + user = User.get_cached_by_ap_id(user.ap_id) + assert User.following_hashtag?(user, hashtag) + end + + test "should 404 if hashtag doesn't exist" do + %{conn: conn} = oauth_access(["write:follows"]) + + response = + conn + |> post("/api/v1/tags/rubrub/follow") + |> json_response_and_validate_schema(404) + + assert response["error"] == "Hashtag not found" + end + end + + describe "POST /api/v1/tags/:id/unfollow" do + test "should unfollow a hashtag" do + %{user: user, conn: conn} = oauth_access(["write:follows"]) + hashtag = insert(:hashtag, name: "jubjub") + {:ok, user} = User.follow_hashtag(user, hashtag) + + response = + conn + |> post("/api/v1/tags/jubjub/unfollow") + |> json_response_and_validate_schema(200) + + assert response["following"] == false + user = User.get_cached_by_ap_id(user.ap_id) + refute User.following_hashtag?(user, hashtag) + end + + test "should 404 if hashtag doesn't exist" do + %{conn: conn} = oauth_access(["write:follows"]) + + response = + conn + |> post("/api/v1/tags/rubrub/unfollow") + |> json_response_and_validate_schema(404) + + assert response["error"] == "Hashtag not found" + end + end +end