Merge develop
[akkoma] / test / web / feed / user_controller_test.exs
index 00712ab5a9f3272d9c8b056e39a9817457661207..9a5610baa9bd78ae47cbfe3ef8e232e81dad7030 100644 (file)
@@ -11,15 +11,14 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
   alias Pleroma.Config
   alias Pleroma.Object
   alias Pleroma.User
+  alias Pleroma.Web.CommonAPI
 
-  clear_config_all([:instance, :federating]) do
-    Config.put([:instance, :federating], true)
-  end
+  setup do: clear_config([:instance, :federating], true)
 
   describe "feed" do
-    clear_config([:feed])
+    setup do: clear_config([:feed])
 
-    test "gets a feed", %{conn: conn} do
+    test "gets an atom feed", %{conn: conn} do
       Config.put(
         [:feed, :post_title],
         %{max_length: 10, omission: "..."}
@@ -54,12 +53,12 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
           }
         )
 
-      _note_activity2 = insert(:note_activity, note: note2)
+      note_activity2 = insert(:note_activity, note: note2)
       object = Object.normalize(note_activity)
 
       resp =
         conn
-        |> put_req_header("content-type", "application/atom+xml")
+        |> put_req_header("accept", "application/atom+xml")
         |> get(user_feed_path(conn, :feed, user.nickname))
         |> response(200)
 
@@ -70,172 +69,134 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
 
       assert activity_titles == ['42 This...', 'This is...']
       assert resp =~ object.data["content"]
-    end
 
-    test "returns 404 for a missing feed", %{conn: conn} do
-      conn =
+      resp =
         conn
-        |> put_req_header("content-type", "application/atom+xml")
-        |> get(user_feed_path(conn, :feed, "nonexisting"))
+        |> put_req_header("accept", "application/atom+xml")
+        |> get("/users/#{user.nickname}/feed", %{"max_id" => note_activity2.id})
+        |> response(200)
 
-      assert response(conn, 404)
+      activity_titles =
+        resp
+        |> SweetXml.parse()
+        |> SweetXml.xpath(~x"//entry/title/text()"l)
+
+      assert activity_titles == ['This is...']
     end
-  end
 
-  describe "feed_redirect" do
-    test "undefined format. it redirects to feed", %{conn: conn} do
-      note_activity = insert(:note_activity)
+    test "gets a rss feed", %{conn: conn} do
+      Pleroma.Config.put(
+        [:feed, :post_title],
+        %{max_length: 10, omission: "..."}
+      )
+
+      activity = insert(:note_activity)
+
+      note =
+        insert(:note,
+          data: %{
+            "content" => "This is :moominmamma: note ",
+            "attachment" => [
+              %{
+                "url" => [
+                  %{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}
+                ]
+              }
+            ],
+            "inReplyTo" => activity.data["id"]
+          }
+        )
+
+      note_activity = insert(:note_activity, note: note)
       user = User.get_cached_by_ap_id(note_activity.data["actor"])
 
-      response =
-        conn
-        |> put_req_header("accept", "application/xml")
-        |> get("/users/#{user.nickname}")
-        |> response(302)
+      note2 =
+        insert(:note,
+          user: user,
+          data: %{
+            "content" => "42 This is :moominmamma: note ",
+            "inReplyTo" => activity.data["id"]
+          }
+        )
 
-      assert response ==
-               "<html><body>You are being <a href=\"#{Pleroma.Web.base_url()}/users/#{
-                 user.nickname
-               }/feed.atom\">redirected</a>.</body></html>"
-    end
+      note_activity2 = insert(:note_activity, note: note2)
+      object = Object.normalize(note_activity)
 
-    test "undefined format. it returns error when user not found", %{conn: conn} do
-      response =
+      resp =
         conn
-        |> put_req_header("accept", "application/xml")
-        |> get(user_feed_path(conn, :feed, "jimm"))
-        |> response(404)
+        |> put_req_header("accept", "application/rss+xml")
+        |> get("/users/#{user.nickname}/feed.rss")
+        |> response(200)
 
-      assert response == ~S({"error":"Not found"})
-    end
+      activity_titles =
+        resp
+        |> SweetXml.parse()
+        |> SweetXml.xpath(~x"//item/title/text()"l)
 
-    test "activity+json format. it redirects on actual feed of user", %{conn: conn} do
-      note_activity = insert(:note_activity)
-      user = User.get_cached_by_ap_id(note_activity.data["actor"])
+      assert activity_titles == ['42 This...', 'This is...']
+      assert resp =~ object.data["content"]
 
-      response =
+      resp =
         conn
-        |> put_req_header("accept", "application/activity+json")
-        |> get("/users/#{user.nickname}")
-        |> json_response(200)
-
-      assert response["endpoints"] == %{
-               "oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize",
-               "oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps",
-               "oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token",
-               "sharedInbox" => "#{Pleroma.Web.base_url()}/inbox",
-               "uploadMedia" => "#{Pleroma.Web.base_url()}/api/ap/upload_media"
-             }
-
-      assert response["@context"] == [
-               "https://www.w3.org/ns/activitystreams",
-               "http://localhost:4001/schemas/litepub-0.1.jsonld",
-               %{"@language" => "und"}
-             ]
-
-      assert Map.take(response, [
-               "followers",
-               "following",
-               "id",
-               "inbox",
-               "manuallyApprovesFollowers",
-               "name",
-               "outbox",
-               "preferredUsername",
-               "summary",
-               "tag",
-               "type",
-               "url"
-             ]) == %{
-               "followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers",
-               "following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following",
-               "id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}",
-               "inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox",
-               "manuallyApprovesFollowers" => false,
-               "name" => user.name,
-               "outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox",
-               "preferredUsername" => user.nickname,
-               "summary" => user.bio,
-               "tag" => [],
-               "type" => "Person",
-               "url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
-             }
+        |> put_req_header("accept", "application/rss+xml")
+        |> get("/users/#{user.nickname}/feed.rss", %{"max_id" => note_activity2.id})
+        |> response(200)
+
+      activity_titles =
+        resp
+        |> SweetXml.parse()
+        |> SweetXml.xpath(~x"//item/title/text()"l)
+
+      assert activity_titles == ['This is...']
     end
 
-    test "activity+json format. it returns error whe use not found", %{conn: conn} do
-      response =
+    test "returns 404 for a missing feed", %{conn: conn} do
+      conn =
         conn
-        |> put_req_header("accept", "application/activity+json")
-        |> get("/users/jimm")
-        |> json_response(404)
+        |> put_req_header("accept", "application/atom+xml")
+        |> get(user_feed_path(conn, :feed, "nonexisting"))
 
-      assert response == "Not found"
+      assert response(conn, 404)
     end
 
-    test "json format. it redirects on actual feed of user", %{conn: conn} do
-      note_activity = insert(:note_activity)
-      user = User.get_cached_by_ap_id(note_activity.data["actor"])
+    test "returns feed with public and unlisted activities", %{conn: conn} do
+      user = insert(:user)
 
-      response =
+      {:ok, _} = CommonAPI.post(user, %{status: "public", visibility: "public"})
+      {:ok, _} = CommonAPI.post(user, %{status: "direct", visibility: "direct"})
+      {:ok, _} = CommonAPI.post(user, %{status: "unlisted", visibility: "unlisted"})
+      {:ok, _} = CommonAPI.post(user, %{status: "private", visibility: "private"})
+
+      resp =
         conn
-        |> put_req_header("accept", "application/json")
-        |> get("/users/#{user.nickname}")
-        |> json_response(200)
-
-      assert response["endpoints"] == %{
-               "oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize",
-               "oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps",
-               "oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token",
-               "sharedInbox" => "#{Pleroma.Web.base_url()}/inbox",
-               "uploadMedia" => "#{Pleroma.Web.base_url()}/api/ap/upload_media"
-             }
-
-      assert response["@context"] == [
-               "https://www.w3.org/ns/activitystreams",
-               "http://localhost:4001/schemas/litepub-0.1.jsonld",
-               %{"@language" => "und"}
-             ]
-
-      assert Map.take(response, [
-               "followers",
-               "following",
-               "id",
-               "inbox",
-               "manuallyApprovesFollowers",
-               "name",
-               "outbox",
-               "preferredUsername",
-               "summary",
-               "tag",
-               "type",
-               "url"
-             ]) == %{
-               "followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers",
-               "following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following",
-               "id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}",
-               "inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox",
-               "manuallyApprovesFollowers" => false,
-               "name" => user.name,
-               "outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox",
-               "preferredUsername" => user.nickname,
-               "summary" => user.bio,
-               "tag" => [],
-               "type" => "Person",
-               "url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
-             }
+        |> put_req_header("accept", "application/atom+xml")
+        |> get(user_feed_path(conn, :feed, user.nickname))
+        |> response(200)
+
+      activity_titles =
+        resp
+        |> SweetXml.parse()
+        |> SweetXml.xpath(~x"//entry/title/text()"l)
+        |> Enum.sort()
+
+      assert activity_titles == ['public', 'unlisted']
     end
 
-    test "json format. it returns error whe use not found", %{conn: conn} do
-      response =
-        conn
-        |> put_req_header("accept", "application/json")
-        |> get("/users/jimm")
-        |> json_response(404)
+    test "returns 404 when the user is remote", %{conn: conn} do
+      user = insert(:user, local: false)
 
-      assert response == "Not found"
+      {:ok, _} = CommonAPI.post(user, %{status: "test"})
+
+      assert conn
+             |> put_req_header("accept", "application/atom+xml")
+             |> get(user_feed_path(conn, :feed, user.nickname))
+             |> response(404)
     end
+  end
 
-    test "html format. it redirects on actual feed of user", %{conn: conn} do
+  # Note: see ActivityPubControllerTest for JSON format tests
+  describe "feed_redirect" do
+    test "with html format, it redirects to user feed", %{conn: conn} do
       note_activity = insert(:note_activity)
       user = User.get_cached_by_ap_id(note_activity.data["actor"])
 
@@ -251,7 +212,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
                ).resp_body
     end
 
-    test "html format. it returns error when user not found", %{conn: conn} do
+    test "with html format, it returns error when user is not found", %{conn: conn} do
       response =
         conn
         |> get("/users/jimm")
@@ -259,30 +220,46 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
 
       assert response == %{"error" => "Not found"}
     end
-  end
 
-  describe "feed_redirect (depending on federation enabled state)" do
-    setup %{conn: conn} do
-      user = insert(:user)
-      conn = put_req_header(conn, "accept", "application/json")
+    test "with non-html / non-json format, it redirects to user feed in atom format", %{
+      conn: conn
+    } do
+      note_activity = insert(:note_activity)
+      user = User.get_cached_by_ap_id(note_activity.data["actor"])
 
-      %{conn: conn, user: user}
-    end
+      conn =
+        conn
+        |> put_req_header("accept", "application/xml")
+        |> get("/users/#{user.nickname}")
 
-    clear_config([:instance, :federating])
+      assert conn.status == 302
+      assert redirected_to(conn) == "#{Pleroma.Web.base_url()}/users/#{user.nickname}/feed.atom"
+    end
 
-    test "renders if instance is federating", %{conn: conn, user: user} do
-      Config.put([:instance, :federating], true)
+    test "with non-html / non-json format, it returns error when user is not found", %{conn: conn} do
+      response =
+        conn
+        |> put_req_header("accept", "application/xml")
+        |> get(user_feed_path(conn, :feed, "jimm"))
+        |> response(404)
 
-      conn = get(conn, "/users/#{user.nickname}")
-      assert json_response(conn, 200)
+      assert response == ~S({"error":"Not found"})
     end
+  end
+
+  describe "private instance" do
+    setup do: clear_config([:instance, :public])
+
+    test "returns 404 for user feed", %{conn: conn} do
+      Config.put([:instance, :public], false)
+      user = insert(:user)
 
-    test "renders 404 if instance is NOT federating", %{conn: conn, user: user} do
-      Config.put([:instance, :federating], false)
+      {:ok, _} = CommonAPI.post(user, %{status: "test"})
 
-      conn = get(conn, "/users/#{user.nickname}")
-      assert json_response(conn, 404)
+      assert conn
+             |> put_req_header("accept", "application/atom+xml")
+             |> get(user_feed_path(conn, :feed, user.nickname))
+             |> response(404)
     end
   end
 end