Merge branch 'develop' into activation-meta
[akkoma] / test / web / streamer / streamer_test.exs
index ee530f4e94515db157efd0e5264b9b63e3abc3ca..245f6e63f53f7bccab9782c236cea453ecf0f943 100644 (file)
@@ -7,16 +7,90 @@ defmodule Pleroma.Web.StreamerTest do
 
   import Pleroma.Factory
 
+  alias Pleroma.Chat
+  alias Pleroma.Chat.MessageReference
   alias Pleroma.Conversation.Participation
   alias Pleroma.List
+  alias Pleroma.Object
   alias Pleroma.User
   alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.Streamer
+  alias Pleroma.Web.StreamerView
 
   @moduletag needs_streamer: true, capture_log: true
 
   setup do: clear_config([:instance, :skip_thread_containment])
 
+  describe "get_topic without an user" do
+    test "allows public" do
+      assert {:ok, "public"} = Streamer.get_topic("public", nil)
+      assert {:ok, "public:local"} = Streamer.get_topic("public:local", nil)
+      assert {:ok, "public:media"} = Streamer.get_topic("public:media", nil)
+      assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", nil)
+    end
+
+    test "allows hashtag streams" do
+      assert {:ok, "hashtag:cofe"} = Streamer.get_topic("hashtag", nil, %{"tag" => "cofe"})
+    end
+
+    test "disallows user streams" do
+      assert {:error, _} = Streamer.get_topic("user", nil)
+      assert {:error, _} = Streamer.get_topic("user:notification", nil)
+      assert {:error, _} = Streamer.get_topic("direct", nil)
+    end
+
+    test "disallows list streams" do
+      assert {:error, _} = Streamer.get_topic("list", nil, %{"list" => 42})
+    end
+  end
+
+  describe "get_topic with an user" do
+    setup do
+      user = insert(:user)
+      {:ok, %{user: user}}
+    end
+
+    test "allows public streams", %{user: user} do
+      assert {:ok, "public"} = Streamer.get_topic("public", user)
+      assert {:ok, "public:local"} = Streamer.get_topic("public:local", user)
+      assert {:ok, "public:media"} = Streamer.get_topic("public:media", user)
+      assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", user)
+    end
+
+    test "allows user streams", %{user: user} do
+      expected_user_topic = "user:#{user.id}"
+      expected_notif_topic = "user:notification:#{user.id}"
+      expected_direct_topic = "direct:#{user.id}"
+      assert {:ok, ^expected_user_topic} = Streamer.get_topic("user", user)
+      assert {:ok, ^expected_notif_topic} = Streamer.get_topic("user:notification", user)
+      assert {:ok, ^expected_direct_topic} = Streamer.get_topic("direct", user)
+    end
+
+    test "allows hashtag streams", %{user: user} do
+      assert {:ok, "hashtag:cofe"} = Streamer.get_topic("hashtag", user, %{"tag" => "cofe"})
+    end
+
+    test "disallows registering to an user stream", %{user: user} do
+      another_user = insert(:user)
+      assert {:error, _} = Streamer.get_topic("user:#{another_user.id}", user)
+      assert {:error, _} = Streamer.get_topic("user:notification:#{another_user.id}", user)
+      assert {:error, _} = Streamer.get_topic("direct:#{another_user.id}", user)
+    end
+
+    test "allows list stream that are owned by the user", %{user: user} do
+      {:ok, list} = List.create("Test", user)
+      assert {:error, _} = Streamer.get_topic("list:#{list.id}", user)
+      assert {:ok, _} = Streamer.get_topic("list", user, %{"list" => list.id})
+    end
+
+    test "disallows list stream that are not owned by the user", %{user: user} do
+      another_user = insert(:user)
+      {:ok, list} = List.create("Test", another_user)
+      assert {:error, _} = Streamer.get_topic("list:#{list.id}", user)
+      assert {:error, _} = Streamer.get_topic("list", user, %{"list" => list.id})
+    end
+  end
+
   describe "user streams" do
     setup do
       user = insert(:user)
@@ -25,32 +99,102 @@ defmodule Pleroma.Web.StreamerTest do
     end
 
     test "it streams the user's post in the 'user' stream", %{user: user} do
-      Streamer.add_socket("user", user)
-      {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
+      Streamer.get_topic_and_add_socket("user", user)
+      {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
       assert_receive {:render_with_user, _, _, ^activity}
       refute Streamer.filtered_by_user?(user, activity)
     end
 
     test "it streams boosts of the user in the 'user' stream", %{user: user} do
-      Streamer.add_socket("user", user)
+      Streamer.get_topic_and_add_socket("user", user)
+
+      other_user = insert(:user)
+      {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
+      {:ok, announce} = CommonAPI.repeat(activity.id, user)
+
+      assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
+      refute Streamer.filtered_by_user?(user, announce)
+    end
+
+    test "it streams boosts of mastodon user in the 'user' stream", %{user: user} do
+      Streamer.get_topic_and_add_socket("user", user)
 
       other_user = insert(:user)
-      {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey"})
-      {:ok, announce, _} = CommonAPI.repeat(activity.id, user)
+      {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
+
+      data =
+        File.read!("test/fixtures/mastodon-announce.json")
+        |> Poison.decode!()
+        |> Map.put("object", activity.data["object"])
+        |> Map.put("actor", user.ap_id)
+
+      {:ok, %Pleroma.Activity{data: _data, local: false} = announce} =
+        Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming(data)
 
       assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
       refute Streamer.filtered_by_user?(user, announce)
     end
 
     test "it sends notify to in the 'user' stream", %{user: user, notify: notify} do
-      Streamer.add_socket("user", user)
+      Streamer.get_topic_and_add_socket("user", user)
       Streamer.stream("user", notify)
       assert_receive {:render_with_user, _, _, ^notify}
       refute Streamer.filtered_by_user?(user, notify)
     end
 
     test "it sends notify to in the 'user:notification' stream", %{user: user, notify: notify} do
-      Streamer.add_socket("user:notification", user)
+      Streamer.get_topic_and_add_socket("user:notification", user)
+      Streamer.stream("user:notification", notify)
+      assert_receive {:render_with_user, _, _, ^notify}
+      refute Streamer.filtered_by_user?(user, notify)
+    end
+
+    test "it sends chat messages to the 'user:pleroma_chat' stream", %{user: user} do
+      other_user = insert(:user)
+
+      {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno")
+      object = Object.normalize(create_activity, false)
+      chat = Chat.get(user.id, other_user.ap_id)
+      cm_ref = MessageReference.for_chat_and_object(chat, object)
+      cm_ref = %{cm_ref | chat: chat, object: object}
+
+      Streamer.get_topic_and_add_socket("user:pleroma_chat", user)
+      Streamer.stream("user:pleroma_chat", {user, cm_ref})
+
+      text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
+
+      assert text =~ "hey cirno"
+      assert_receive {:text, ^text}
+    end
+
+    test "it sends chat messages to the 'user' stream", %{user: user} do
+      other_user = insert(:user)
+
+      {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno")
+      object = Object.normalize(create_activity, false)
+      chat = Chat.get(user.id, other_user.ap_id)
+      cm_ref = MessageReference.for_chat_and_object(chat, object)
+      cm_ref = %{cm_ref | chat: chat, object: object}
+
+      Streamer.get_topic_and_add_socket("user", user)
+      Streamer.stream("user", {user, cm_ref})
+
+      text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
+
+      assert text =~ "hey cirno"
+      assert_receive {:text, ^text}
+    end
+
+    test "it sends chat message notifications to the 'user:notification' stream", %{user: user} do
+      other_user = insert(:user)
+
+      {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey")
+
+      notify =
+        Repo.get_by(Pleroma.Notification, user_id: user.id, activity_id: create_activity.id)
+        |> Repo.preload(:activity)
+
+      Streamer.get_topic_and_add_socket("user:notification", user)
       Streamer.stream("user:notification", notify)
       assert_receive {:render_with_user, _, _, ^notify}
       refute Streamer.filtered_by_user?(user, notify)
@@ -62,9 +206,9 @@ defmodule Pleroma.Web.StreamerTest do
       blocked = insert(:user)
       {:ok, _user_relationship} = User.block(user, blocked)
 
-      Streamer.add_socket("user:notification", user)
+      Streamer.get_topic_and_add_socket("user:notification", user)
 
-      {:ok, activity} = CommonAPI.post(user, %{"status" => ":("})
+      {:ok, activity} = CommonAPI.post(user, %{status: ":("})
       {:ok, _} = CommonAPI.favorite(blocked, activity.id)
 
       refute_receive _
@@ -75,10 +219,10 @@ defmodule Pleroma.Web.StreamerTest do
     } do
       user2 = insert(:user)
 
-      {:ok, activity} = CommonAPI.post(user, %{"status" => "super hot take"})
+      {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
       {:ok, _} = CommonAPI.add_mute(user, activity)
 
-      Streamer.add_socket("user:notification", user)
+      Streamer.get_topic_and_add_socket("user:notification", user)
 
       {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
 
@@ -91,8 +235,8 @@ defmodule Pleroma.Web.StreamerTest do
     } do
       user2 = insert(:user, %{ap_id: "https://hecking-lewd-place.com/user/meanie"})
 
-      {:ok, activity} = CommonAPI.post(user, %{"status" => "super hot take"})
-      Streamer.add_socket("user:notification", user)
+      {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
+      Streamer.get_topic_and_add_socket("user:notification", user)
       {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
 
       assert_receive {:render_with_user, _, "notification.json", notif}
@@ -106,8 +250,8 @@ defmodule Pleroma.Web.StreamerTest do
       user2 = insert(:user, %{ap_id: "https://hecking-lewd-place.com/user/meanie"})
 
       {:ok, user} = User.block_domain(user, "hecking-lewd-place.com")
-      {:ok, activity} = CommonAPI.post(user, %{"status" => "super hot take"})
-      Streamer.add_socket("user:notification", user)
+      {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
+      Streamer.get_topic_and_add_socket("user:notification", user)
       {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
 
       refute_receive _
@@ -130,7 +274,7 @@ defmodule Pleroma.Web.StreamerTest do
           %Tesla.Env{status: 200, body: body}
       end)
 
-      Streamer.add_socket("user:notification", user)
+      Streamer.get_topic_and_add_socket("user:notification", user)
       {:ok, _follower, _followed, follow_activity} = CommonAPI.follow(user2, user)
 
       assert_receive {:render_with_user, _, "notification.json", notif}
@@ -143,9 +287,9 @@ defmodule Pleroma.Web.StreamerTest do
     user = insert(:user)
     other_user = insert(:user)
 
-    Streamer.add_socket("public", other_user)
+    Streamer.get_topic_and_add_socket("public", other_user)
 
-    {:ok, activity} = CommonAPI.post(user, %{"status" => "Test"})
+    {:ok, activity} = CommonAPI.post(user, %{status: "Test"})
     assert_receive {:render_with_user, _, _, ^activity}
     refute Streamer.filtered_by_user?(user, activity)
   end
@@ -153,9 +297,9 @@ defmodule Pleroma.Web.StreamerTest do
   test "works for deletions" do
     user = insert(:user)
     other_user = insert(:user)
-    {:ok, activity} = CommonAPI.post(other_user, %{"status" => "Test"})
+    {:ok, activity} = CommonAPI.post(other_user, %{status: "Test"})
 
-    Streamer.add_socket("public", user)
+    Streamer.get_topic_and_add_socket("public", user)
 
     {:ok, _} = CommonAPI.delete(activity.id, other_user)
     activity_id = activity.id
@@ -166,9 +310,9 @@ defmodule Pleroma.Web.StreamerTest do
   test "it sends to public unauthenticated" do
     user = insert(:user)
 
-    Streamer.add_socket("public", nil)
+    Streamer.get_topic_and_add_socket("public", nil)
 
-    {:ok, activity} = CommonAPI.post(user, %{"status" => "Test"})
+    {:ok, activity} = CommonAPI.post(user, %{status: "Test"})
     activity_id = activity.id
     assert_receive {:text, event}
     assert %{"event" => "update", "payload" => payload} = Jason.decode!(event)
@@ -195,7 +339,7 @@ defmodule Pleroma.Web.StreamerTest do
             )
         )
 
-      Streamer.add_socket("public", user)
+      Streamer.get_topic_and_add_socket("public", user)
       Streamer.stream("public", activity)
       assert_receive {:render_with_user, _, _, ^activity}
       assert Streamer.filtered_by_user?(user, activity)
@@ -216,7 +360,7 @@ defmodule Pleroma.Web.StreamerTest do
             )
         )
 
-      Streamer.add_socket("public", user)
+      Streamer.get_topic_and_add_socket("public", user)
       Streamer.stream("public", activity)
 
       assert_receive {:render_with_user, _, _, ^activity}
@@ -238,7 +382,7 @@ defmodule Pleroma.Web.StreamerTest do
             )
         )
 
-      Streamer.add_socket("public", user)
+      Streamer.get_topic_and_add_socket("public", user)
       Streamer.stream("public", activity)
 
       assert_receive {:render_with_user, _, _, ^activity}
@@ -252,8 +396,8 @@ defmodule Pleroma.Web.StreamerTest do
       blocked_user = insert(:user)
       {:ok, _user_relationship} = User.block(user, blocked_user)
 
-      Streamer.add_socket("public", user)
-      {:ok, activity} = CommonAPI.post(blocked_user, %{"status" => "Test"})
+      Streamer.get_topic_and_add_socket("public", user)
+      {:ok, activity} = CommonAPI.post(blocked_user, %{status: "Test"})
       assert_receive {:render_with_user, _, _, ^activity}
       assert Streamer.filtered_by_user?(user, activity)
     end
@@ -263,21 +407,21 @@ defmodule Pleroma.Web.StreamerTest do
       blockee = insert(:user)
       friend = insert(:user)
 
-      Streamer.add_socket("public", blocker)
+      Streamer.get_topic_and_add_socket("public", blocker)
 
       {:ok, _user_relationship} = User.block(blocker, blockee)
 
-      {:ok, activity_one} = CommonAPI.post(friend, %{"status" => "hey! @#{blockee.nickname}"})
+      {:ok, activity_one} = CommonAPI.post(friend, %{status: "hey! @#{blockee.nickname}"})
 
       assert_receive {:render_with_user, _, _, ^activity_one}
       assert Streamer.filtered_by_user?(blocker, activity_one)
 
-      {:ok, activity_two} = CommonAPI.post(blockee, %{"status" => "hey! @#{friend.nickname}"})
+      {:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
 
       assert_receive {:render_with_user, _, _, ^activity_two}
       assert Streamer.filtered_by_user?(blocker, activity_two)
 
-      {:ok, activity_three} = CommonAPI.post(blockee, %{"status" => "hey! @#{blocker.nickname}"})
+      {:ok, activity_three} = CommonAPI.post(blockee, %{status: "hey! @#{blocker.nickname}"})
 
       assert_receive {:render_with_user, _, _, ^activity_three}
       assert Streamer.filtered_by_user?(blocker, activity_three)
@@ -295,12 +439,12 @@ defmodule Pleroma.Web.StreamerTest do
       {:ok, list} = List.create("Test", user_a)
       {:ok, list} = List.follow(list, user_b)
 
-      Streamer.add_socket("list:#{list.id}", user_a)
+      Streamer.get_topic_and_add_socket("list", user_a, %{"list" => list.id})
 
       {:ok, _activity} =
         CommonAPI.post(user_b, %{
-          "status" => "@#{user_c.nickname} Test",
-          "visibility" => "direct"
+          status: "@#{user_c.nickname} Test",
+          visibility: "direct"
         })
 
       refute_receive _
@@ -313,12 +457,12 @@ defmodule Pleroma.Web.StreamerTest do
       {:ok, list} = List.create("Test", user_a)
       {:ok, list} = List.follow(list, user_b)
 
-      Streamer.add_socket("list:#{list.id}", user_a)
+      Streamer.get_topic_and_add_socket("list", user_a, %{"list" => list.id})
 
       {:ok, _activity} =
         CommonAPI.post(user_b, %{
-          "status" => "Test",
-          "visibility" => "private"
+          status: "Test",
+          visibility: "private"
         })
 
       refute_receive _
@@ -333,12 +477,12 @@ defmodule Pleroma.Web.StreamerTest do
       {:ok, list} = List.create("Test", user_a)
       {:ok, list} = List.follow(list, user_b)
 
-      Streamer.add_socket("list:#{list.id}", user_a)
+      Streamer.get_topic_and_add_socket("list", user_a, %{"list" => list.id})
 
       {:ok, activity} =
         CommonAPI.post(user_b, %{
-          "status" => "Test",
-          "visibility" => "private"
+          status: "Test",
+          visibility: "private"
         })
 
       assert_receive {:render_with_user, _, _, ^activity}
@@ -354,10 +498,10 @@ defmodule Pleroma.Web.StreamerTest do
       CommonAPI.follow(user1, user2)
       CommonAPI.hide_reblogs(user1, user2)
 
-      {:ok, create_activity} = CommonAPI.post(user3, %{"status" => "I'm kawen"})
+      {:ok, create_activity} = CommonAPI.post(user3, %{status: "I'm kawen"})
 
-      Streamer.add_socket("user", user1)
-      {:ok, announce_activity, _} = CommonAPI.repeat(create_activity.id, user2)
+      Streamer.get_topic_and_add_socket("user", user1)
+      {:ok, announce_activity} = CommonAPI.repeat(create_activity.id, user2)
       assert_receive {:render_with_user, _, _, ^announce_activity}
       assert Streamer.filtered_by_user?(user1, announce_activity)
     end
@@ -368,9 +512,9 @@ defmodule Pleroma.Web.StreamerTest do
       CommonAPI.follow(user1, user2)
       CommonAPI.hide_reblogs(user1, user2)
 
-      {:ok, create_activity} = CommonAPI.post(user1, %{"status" => "I'm kawen"})
-      Streamer.add_socket("user", user1)
-      {:ok, _favorite_activity, _} = CommonAPI.repeat(create_activity.id, user2)
+      {:ok, create_activity} = CommonAPI.post(user1, %{status: "I'm kawen"})
+      Streamer.get_topic_and_add_socket("user", user1)
+      {:ok, _announce_activity} = CommonAPI.repeat(create_activity.id, user2)
 
       assert_receive {:render_with_user, _, "notification.json", notif}
       assert Streamer.filtered_by_user?(user1, notif)
@@ -382,8 +526,8 @@ defmodule Pleroma.Web.StreamerTest do
       CommonAPI.follow(user1, user2)
       CommonAPI.hide_reblogs(user1, user2)
 
-      {:ok, create_activity} = CommonAPI.post(user1, %{"status" => "I'm kawen"})
-      Streamer.add_socket("user", user1)
+      {:ok, create_activity} = CommonAPI.post(user1, %{status: "I'm kawen"})
+      Streamer.get_topic_and_add_socket("user", user1)
       {:ok, _favorite_activity} = CommonAPI.favorite(user2, create_activity.id)
 
       assert_receive {:render_with_user, _, "notification.json", notif}
@@ -394,9 +538,9 @@ defmodule Pleroma.Web.StreamerTest do
   test "it filters posts from muted threads" do
     user = insert(:user)
     user2 = insert(:user)
-    Streamer.add_socket("user", user2)
+    Streamer.get_topic_and_add_socket("user", user2)
     {:ok, user2, user, _activity} = CommonAPI.follow(user2, user)
-    {:ok, activity} = CommonAPI.post(user, %{"status" => "super hot take"})
+    {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
     {:ok, _} = CommonAPI.add_mute(user2, activity)
     assert_receive {:render_with_user, _, _, ^activity}
     assert Streamer.filtered_by_user?(user2, activity)
@@ -411,12 +555,12 @@ defmodule Pleroma.Web.StreamerTest do
       user = insert(:user)
       another_user = insert(:user)
 
-      Streamer.add_socket("direct", user)
+      Streamer.get_topic_and_add_socket("direct", user)
 
       {:ok, _create_activity} =
         CommonAPI.post(another_user, %{
-          "status" => "hey @#{user.nickname}",
-          "visibility" => "direct"
+          status: "hey @#{user.nickname}",
+          visibility: "direct"
         })
 
       assert_receive {:text, received_event}
@@ -433,12 +577,12 @@ defmodule Pleroma.Web.StreamerTest do
       user = insert(:user)
       another_user = insert(:user)
 
-      Streamer.add_socket("direct", user)
+      Streamer.get_topic_and_add_socket("direct", user)
 
       {:ok, create_activity} =
         CommonAPI.post(another_user, %{
-          "status" => "hi @#{user.nickname}",
-          "visibility" => "direct"
+          status: "hi @#{user.nickname}",
+          visibility: "direct"
         })
 
       create_activity_id = create_activity.id
@@ -459,19 +603,19 @@ defmodule Pleroma.Web.StreamerTest do
     test "it sends conversation update to the 'direct' stream when a message is deleted" do
       user = insert(:user)
       another_user = insert(:user)
-      Streamer.add_socket("direct", user)
+      Streamer.get_topic_and_add_socket("direct", user)
 
       {:ok, create_activity} =
         CommonAPI.post(another_user, %{
-          "status" => "hi @#{user.nickname}",
-          "visibility" => "direct"
+          status: "hi @#{user.nickname}",
+          visibility: "direct"
         })
 
       {:ok, create_activity2} =
         CommonAPI.post(another_user, %{
-          "status" => "hi @#{user.nickname} 2",
-          "in_reply_to_status_id" => create_activity.id,
-          "visibility" => "direct"
+          status: "hi @#{user.nickname} 2",
+          in_reply_to_status_id: create_activity.id,
+          visibility: "direct"
         })
 
       assert_receive {:render_with_user, _, _, ^create_activity}