OpenAPI: MastodonAPI Status Controller
[akkoma] / test / pleroma / web / mastodon_api / controllers / status_controller_test.exs
index de542e5df8e654ea0e4994a02fe2df93b55ad62a..4c0149a4c5b822be92a179af6a380334a03e4b16 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
@@ -7,7 +7,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
   use Oban.Testing, repo: Pleroma.Repo
 
   alias Pleroma.Activity
-  alias Pleroma.Config
   alias Pleroma.Conversation.Participation
   alias Pleroma.Object
   alias Pleroma.Repo
@@ -29,7 +28,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
     setup do: oauth_access(["write:statuses"])
 
     test "posting a status does not increment reblog_count when relaying", %{conn: conn} do
-      Config.put([:instance, :federating], true)
+      clear_config([:instance, :federating], true)
       Config.get([:instance, :allow_relay], true)
 
       response =
@@ -82,6 +81,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
           "sensitive" => 0
         })
 
+      # Idempotency plug response means detection fail
       assert %{"id" => second_id} = json_response(conn_two, 200)
       assert id == second_id
 
@@ -151,8 +151,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
     end
 
     test "Get MRF reason when posting a status is rejected by one", %{conn: conn} do
-      Config.put([:mrf_keyword, :reject], ["GNO"])
-      Config.put([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
+      clear_config([:mrf_keyword, :reject], ["GNO"])
+      clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
 
       assert %{"error" => "[KeywordPolicy] Matches with rejected keyword"} =
                conn
@@ -264,6 +264,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
 
       fake_conn =
         conn
+        |> assign(:user, refresh_record(conn.assigns.user))
         |> put_req_header("content-type", "application/json")
         |> post("/api/v1/statuses", %{
           "status" =>
@@ -357,6 +358,69 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
       assert activity.data["to"] == [user2.ap_id]
       assert activity.data["cc"] == []
     end
+
+    test "discloses application metadata when enabled" do
+      user = insert(:user, disclose_client: true)
+      %{user: _user, token: token, conn: conn} = oauth_access(["write:statuses"], user: user)
+
+      %Pleroma.Web.OAuth.Token{
+        app: %Pleroma.Web.OAuth.App{
+          client_name: app_name,
+          website: app_website
+        }
+      } = token
+
+      result =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> post("/api/v1/statuses", %{
+          "status" => "cofe is my copilot"
+        })
+
+      assert %{
+               "content" => "cofe is my copilot"
+             } = json_response_and_validate_schema(result, 200)
+
+      activity = result.assigns.activity.id
+
+      result =
+        conn
+        |> get("api/v1/statuses/#{activity}")
+
+      assert %{
+               "content" => "cofe is my copilot",
+               "application" => %{
+                 "name" => ^app_name,
+                 "website" => ^app_website
+               }
+             } = json_response_and_validate_schema(result, 200)
+    end
+
+    test "hides application metadata when disabled" do
+      user = insert(:user, disclose_client: false)
+      %{user: _user, token: _token, conn: conn} = oauth_access(["write:statuses"], user: user)
+
+      result =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> post("/api/v1/statuses", %{
+          "status" => "club mate is my wingman"
+        })
+
+      assert %{"content" => "club mate is my wingman"} =
+               json_response_and_validate_schema(result, 200)
+
+      activity = result.assigns.activity.id
+
+      result =
+        conn
+        |> get("api/v1/statuses/#{activity}")
+
+      assert %{
+               "content" => "club mate is my wingman",
+               "application" => nil
+             } = json_response_and_validate_schema(result, 200)
+    end
   end
 
   describe "posting scheduled statuses" do
@@ -383,6 +447,31 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
       assert [] == Repo.all(Activity)
     end
 
+    test "with expiration" do
+      %{conn: conn} = oauth_access(["write:statuses", "read:statuses"])
+
+      scheduled_at =
+        NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(6), :millisecond)
+        |> NaiveDateTime.to_iso8601()
+        |> Kernel.<>("Z")
+
+      assert %{"id" => status_id, "params" => %{"expires_in" => 300}} =
+               conn
+               |> put_req_header("content-type", "application/json")
+               |> post("/api/v1/statuses", %{
+                 "status" => "scheduled",
+                 "scheduled_at" => scheduled_at,
+                 "expires_in" => 300
+               })
+               |> json_response_and_validate_schema(200)
+
+      assert %{"id" => ^status_id, "params" => %{"expires_in" => 300}} =
+               conn
+               |> put_req_header("content-type", "application/json")
+               |> get("/api/v1/scheduled_statuses/#{status_id}")
+               |> json_response_and_validate_schema(200)
+    end
+
     test "ignores nil values", %{conn: conn} do
       conn =
         conn
@@ -516,7 +605,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
              end)
 
       assert NaiveDateTime.diff(NaiveDateTime.from_iso8601!(response["poll"]["expires_at"]), time) in 420..430
-      refute response["poll"]["expred"]
+      assert response["poll"]["expired"] == false
 
       question = Object.get_by_id(response["poll"]["id"])
 
@@ -592,6 +681,44 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
       %{"error" => error} = json_response_and_validate_schema(conn, 422)
       assert error == "Expiration date is too far in the future"
     end
+
+    test "scheduled poll", %{conn: conn} do
+      clear_config([ScheduledActivity, :enabled], true)
+
+      scheduled_at =
+        NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(6), :millisecond)
+        |> NaiveDateTime.to_iso8601()
+        |> Kernel.<>("Z")
+
+      %{"id" => scheduled_id} =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> post("/api/v1/statuses", %{
+          "status" => "very cool poll",
+          "poll" => %{
+            "options" => ~w(a b c),
+            "expires_in" => 420
+          },
+          "scheduled_at" => scheduled_at
+        })
+        |> json_response_and_validate_schema(200)
+
+      assert {:ok, %{id: activity_id}} =
+               perform_job(Pleroma.Workers.ScheduledActivityWorker, %{
+                 activity_id: scheduled_id
+               })
+
+      assert Repo.all(Oban.Job) == []
+
+      object =
+        Activity
+        |> Repo.get(activity_id)
+        |> Object.normalize()
+
+      assert object.data["content"] == "very cool poll"
+      assert object.data["type"] == "Question"
+      assert length(object.data["oneOf"]) == 3
+    end
   end
 
   test "get a status" do
@@ -800,7 +927,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
     test "when you created it" do
       %{user: author, conn: conn} = oauth_access(["write:statuses"])
       activity = insert(:note_activity, user: author)
-      object = Object.normalize(activity)
+      object = Object.normalize(activity, fetch: false)
 
       content = object.data["content"]
       source = object.data["source"]
@@ -954,6 +1081,23 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
 
       assert to_string(activity.id) == id
     end
+
+    test "author can reblog own private status", %{conn: conn, user: user} do
+      {:ok, activity} = CommonAPI.post(user, %{status: "cofe", visibility: "private"})
+
+      conn =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> post("/api/v1/statuses/#{activity.id}/reblog")
+
+      assert %{
+               "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1},
+               "reblogged" => true,
+               "visibility" => "private"
+             } = json_response_and_validate_schema(conn, 200)
+
+      assert to_string(activity.id) == id
+    end
   end
 
   describe "unreblogging" do
@@ -1187,7 +1331,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
 
   describe "cards" do
     setup do
-      Config.put([:rich_media, :enabled], true)
+      clear_config([:rich_media, :enabled], true)
 
       oauth_access(["read:statuses"])
     end
@@ -1374,7 +1518,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
 
     activity = Activity.get_by_id_with_object(id)
 
-    assert Object.normalize(activity).data["inReplyTo"] == Object.normalize(replied_to).data["id"]
+    assert Object.normalize(activity, fetch: false).data["inReplyTo"] ==
+             Object.normalize(replied_to, fetch: false).data["id"]
+
     assert Activity.get_in_reply_to_activity(activity).id == replied_to.id
 
     # Reblog from the third user
@@ -1397,7 +1543,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
       |> assign(:token, insert(:oauth_token, user: user3, scopes: ["read:statuses"]))
       |> get("api/v1/timelines/home")
 
-    [reblogged_activity] = json_response(conn3, 200)
+    [reblogged_activity] = json_response_and_validate_schema(conn3, 200)
 
     assert reblogged_activity["reblog"]["in_reply_to_id"] == replied_to.id
 
@@ -1751,7 +1897,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
     local = Pleroma.Constants.as_local_public()
 
     assert %{"content" => "cofe", "id" => id, "visibility" => "local"} =
-             json_response(conn_one, 200)
+             json_response_and_validate_schema(conn_one, 200)
 
     assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id)
   end