diff options
Diffstat (limited to 'test/web/activity_pub')
| -rw-r--r-- | test/web/activity_pub/activity_pub_controller_test.exs | 71 | ||||
| -rw-r--r-- | test/web/activity_pub/activity_pub_test.exs | 159 | ||||
| -rw-r--r-- | test/web/activity_pub/mrf/simple_policy_test.exs | 309 | ||||
| -rw-r--r-- | test/web/activity_pub/transmogrifier_test.exs | 132 | ||||
| -rw-r--r-- | test/web/activity_pub/views/user_view_test.exs | 13 | ||||
| -rw-r--r-- | test/web/activity_pub/visibilty_test.exs | 26 |
6 files changed, 664 insertions, 46 deletions
diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index 30adfda36..8b3233729 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do alias Pleroma.User alias Pleroma.Web.ActivityPub.ObjectView alias Pleroma.Web.ActivityPub.UserView + alias Pleroma.Web.ActivityPub.Utils setup_all do Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) @@ -234,13 +235,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do end describe "/users/:nickname/inbox" do - test "it inserts an incoming activity into the database", %{conn: conn} do - user = insert(:user) - + setup do data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() - |> Map.put("bcc", [user.ap_id]) + + [data: data] + end + + test "it inserts an incoming activity into the database", %{conn: conn, data: data} do + user = insert(:user) + data = Map.put(data, "bcc", [user.ap_id]) conn = conn @@ -253,16 +258,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert Activity.get_by_ap_id(data["id"]) end - test "it accepts messages from actors that are followed by the user", %{conn: conn} do + test "it accepts messages from actors that are followed by the user", %{ + conn: conn, + data: data + } do recipient = insert(:user) actor = insert(:user, %{ap_id: "http://mastodon.example.org/users/actor"}) {:ok, recipient} = User.follow(recipient, actor) - data = - File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() - object = data["object"] |> Map.put("attributedTo", actor.ap_id) @@ -309,13 +313,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert response(conn, 200) =~ note_activity.data["object"]["content"] end - test "it clears `unreachable` federation status of the sender", %{conn: conn} do + test "it clears `unreachable` federation status of the sender", %{conn: conn, data: data} do user = insert(:user) - - data = - File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() - |> Map.put("bcc", [user.ap_id]) + data = Map.put(data, "bcc", [user.ap_id]) sender_host = URI.parse(data["actor"]).host Instances.set_consistently_unreachable(sender_host) @@ -330,6 +330,47 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert "ok" == json_response(conn, 200) assert Instances.reachable?(sender_host) end + + test "it removes all follower collections but actor's", %{conn: conn} do + [actor, recipient] = insert_pair(:user) + + data = + File.read!("test/fixtures/activitypub-client-post-activity.json") + |> Poison.decode!() + + object = Map.put(data["object"], "attributedTo", actor.ap_id) + + data = + data + |> Map.put("id", Utils.generate_object_id()) + |> Map.put("actor", actor.ap_id) + |> Map.put("object", object) + |> Map.put("cc", [ + recipient.follower_address, + actor.follower_address + ]) + |> Map.put("to", [ + recipient.ap_id, + recipient.follower_address, + "https://www.w3.org/ns/activitystreams#Public" + ]) + + conn + |> assign(:valid_signature, true) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{recipient.nickname}/inbox", data) + |> json_response(200) + + activity = Activity.get_by_ap_id(data["id"]) + + assert activity.id + assert actor.follower_address in activity.recipients + assert actor.follower_address in activity.data["cc"] + + refute recipient.follower_address in activity.recipients + refute recipient.follower_address in activity.data["cc"] + refute recipient.follower_address in activity.data["to"] + end end describe "/users/:nickname/outbox" do diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index f8e987e58..76586ee4a 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do alias Pleroma.Object alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.Web.ActivityPub.Publisher alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.CommonAPI @@ -22,6 +23,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do :ok end + describe "streaming out participations" do + test "it streams them out" do + user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"}) + + {:ok, conversation} = Pleroma.Conversation.create_or_bump_for(activity) + + participations = + conversation.participations + |> Repo.preload(:user) + + with_mock Pleroma.Web.Streamer, + stream: fn _, _ -> nil end do + ActivityPub.stream_out_participations(conversation.participations) + + Enum.each(participations, fn participation -> + assert called(Pleroma.Web.Streamer.stream("participation", participation)) + end) + end + end + end + describe "fetching restricted by visibility" do test "it restricts by the appropriate visibility" do user = insert(:user) @@ -130,9 +153,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end test "doesn't drop activities with content being null" do + user = insert(:user) + data = %{ - "ok" => true, + "actor" => user.ap_id, + "to" => [], "object" => %{ + "actor" => user.ap_id, + "to" => [], + "type" => "Note", "content" => nil } } @@ -148,8 +177,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end test "inserts a given map into the activity database, giving it an id if it has none." do + user = insert(:user) + data = %{ - "ok" => true + "actor" => user.ap_id, + "to" => [], + "object" => %{ + "actor" => user.ap_id, + "to" => [], + "type" => "Note", + "content" => "hey" + } } {:ok, %Activity{} = activity} = ActivityPub.insert(data) @@ -159,9 +197,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do given_id = "bla" data = %{ - "ok" => true, "id" => given_id, - "context" => "blabla" + "actor" => user.ap_id, + "to" => [], + "context" => "blabla", + "object" => %{ + "actor" => user.ap_id, + "to" => [], + "type" => "Note", + "content" => "hey" + } } {:ok, %Activity{} = activity} = ActivityPub.insert(data) @@ -172,26 +217,39 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end test "adds a context when none is there" do + user = insert(:user) + data = %{ - "id" => "some_id", + "actor" => user.ap_id, + "to" => [], "object" => %{ - "id" => "object_id" + "actor" => user.ap_id, + "to" => [], + "type" => "Note", + "content" => "hey" } } {:ok, %Activity{} = activity} = ActivityPub.insert(data) + object = Pleroma.Object.normalize(activity) assert is_binary(activity.data["context"]) - assert is_binary(activity.data["object"]["context"]) + assert is_binary(object.data["context"]) assert activity.data["context_id"] - assert activity.data["object"]["context_id"] + assert object.data["context_id"] end test "adds an id to a given object if it lacks one and is a note and inserts it to the object database" do + user = insert(:user) + data = %{ + "actor" => user.ap_id, + "to" => [], "object" => %{ + "actor" => user.ap_id, + "to" => [], "type" => "Note", - "ok" => true + "content" => "hey" } } @@ -404,6 +462,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do refute Enum.member?(activities, activity_three.id) end + test "doesn't return activities from blocked domains" do + domain = "dogwhistle.zone" + domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"}) + note = insert(:note, %{data: %{"actor" => domain_user.ap_id}}) + activity = insert(:note_activity, %{note: note}) + user = insert(:user) + {:ok, user} = User.block_domain(user, domain) + + activities = + ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true}) + + refute activity in activities + + followed_user = insert(:user) + ActivityPub.follow(user, followed_user) + {:ok, repeat_activity, _} = CommonAPI.repeat(activity.id, followed_user) + + activities = + ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true}) + + refute repeat_activity in activities + end + test "doesn't return muted activities" do activity_one = insert(:note_activity) activity_two = insert(:note_activity) @@ -902,18 +983,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do "in_reply_to_status_id" => private_activity_2.id }) - activities = ActivityPub.fetch_activities([user1.ap_id | user1.following]) + activities = + ActivityPub.fetch_activities([user1.ap_id | user1.following]) + |> Enum.map(fn a -> a.id end) private_activity_1 = Activity.get_by_ap_id_with_object(private_activity_1.data["id"]) - assert [public_activity, private_activity_1, private_activity_3] == - activities + assert [public_activity.id, private_activity_1.id, private_activity_3.id] == activities assert length(activities) == 3 - activities = ActivityPub.contain_timeline(activities, user1) + activities = + ActivityPub.fetch_activities([user1.ap_id | user1.following], %{"user" => user1}) + |> Enum.map(fn a -> a.id end) - assert [public_activity, private_activity_1] == activities + assert [public_activity.id, private_activity_1.id] == activities assert length(activities) == 2 end end @@ -921,7 +1005,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do describe "update" do test "it creates an update activity with the new user data" do user = insert(:user) - {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) + {:ok, user} = User.ensure_keys_present(user) user_data = Pleroma.Web.ActivityPub.UserView.render("user.json", %{user: user}) {:ok, update} = @@ -1000,7 +1084,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do actor = insert(:user) inbox = "http://200.site/users/nick1/inbox" - assert {:ok, _} = ActivityPub.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) + assert {:ok, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) assert called(Instances.set_reachable(inbox)) end @@ -1013,7 +1097,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do inbox = "http://200.site/users/nick1/inbox" assert {:ok, _} = - ActivityPub.publish_one(%{ + Publisher.publish_one(%{ inbox: inbox, json: "{}", actor: actor, @@ -1032,7 +1116,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do inbox = "http://200.site/users/nick1/inbox" assert {:ok, _} = - ActivityPub.publish_one(%{ + Publisher.publish_one(%{ inbox: inbox, json: "{}", actor: actor, @@ -1050,8 +1134,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do actor = insert(:user) inbox = "http://404.site/users/nick1/inbox" - assert {:error, _} = - ActivityPub.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) + assert {:error, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) assert called(Instances.set_unreachable(inbox)) end @@ -1063,8 +1146,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do actor = insert(:user) inbox = "http://connrefused.site/users/nick1/inbox" - assert {:error, _} = - ActivityPub.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) + assert {:error, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) assert called(Instances.set_unreachable(inbox)) end @@ -1076,7 +1158,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do actor = insert(:user) inbox = "http://200.site/users/nick1/inbox" - assert {:ok, _} = ActivityPub.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) + assert {:ok, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) refute called(Instances.set_unreachable(inbox)) end @@ -1089,7 +1171,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do inbox = "http://connrefused.site/users/nick1/inbox" assert {:error, _} = - ActivityPub.publish_one(%{ + Publisher.publish_one(%{ inbox: inbox, json: "{}", actor: actor, @@ -1104,4 +1186,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do def data_uri do File.read!("test/fixtures/avatar_data_uri") end + + describe "fetch_activities_bounded" do + test "fetches private posts for followed users" do + user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{ + "status" => "thought I looked cute might delete later :3", + "visibility" => "private" + }) + + [result] = ActivityPub.fetch_activities_bounded([user.follower_address], []) + assert result.id == activity.id + end + + test "fetches only public posts for other users" do + user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe", "visibility" => "public"}) + + {:ok, _private_activity} = + CommonAPI.post(user, %{ + "status" => "why is tenshi eating a corndog so cute?", + "visibility" => "private" + }) + + [result] = ActivityPub.fetch_activities_bounded([], [user.follower_address]) + assert result.id == activity.id + end + end end diff --git a/test/web/activity_pub/mrf/simple_policy_test.exs b/test/web/activity_pub/mrf/simple_policy_test.exs new file mode 100644 index 000000000..0fd68e103 --- /dev/null +++ b/test/web/activity_pub/mrf/simple_policy_test.exs @@ -0,0 +1,309 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do + use Pleroma.DataCase + import Pleroma.Factory + alias Pleroma.Config + alias Pleroma.Web.ActivityPub.MRF.SimplePolicy + + setup do + orig = Config.get!(:mrf_simple) + + Config.put(:mrf_simple, + media_removal: [], + media_nsfw: [], + federated_timeline_removal: [], + report_removal: [], + reject: [], + accept: [], + avatar_removal: [], + banner_removal: [] + ) + + on_exit(fn -> + Config.put(:mrf_simple, orig) + end) + end + + describe "when :media_removal" do + test "is empty" do + Config.put([:mrf_simple, :media_removal], []) + media_message = build_media_message() + local_message = build_local_message() + + assert SimplePolicy.filter(media_message) == {:ok, media_message} + assert SimplePolicy.filter(local_message) == {:ok, local_message} + end + + test "has a matching host" do + Config.put([:mrf_simple, :media_removal], ["remote.instance"]) + media_message = build_media_message() + local_message = build_local_message() + + assert SimplePolicy.filter(media_message) == + {:ok, + media_message + |> Map.put("object", Map.delete(media_message["object"], "attachment"))} + + assert SimplePolicy.filter(local_message) == {:ok, local_message} + end + end + + describe "when :media_nsfw" do + test "is empty" do + Config.put([:mrf_simple, :media_nsfw], []) + media_message = build_media_message() + local_message = build_local_message() + + assert SimplePolicy.filter(media_message) == {:ok, media_message} + assert SimplePolicy.filter(local_message) == {:ok, local_message} + end + + test "has a matching host" do + Config.put([:mrf_simple, :media_nsfw], ["remote.instance"]) + media_message = build_media_message() + local_message = build_local_message() + + assert SimplePolicy.filter(media_message) == + {:ok, + media_message + |> put_in(["object", "tag"], ["foo", "nsfw"]) + |> put_in(["object", "sensitive"], true)} + + assert SimplePolicy.filter(local_message) == {:ok, local_message} + end + end + + defp build_media_message do + %{ + "actor" => "https://remote.instance/users/bob", + "type" => "Create", + "object" => %{ + "attachment" => [%{}], + "tag" => ["foo"], + "sensitive" => false + } + } + end + + describe "when :report_removal" do + test "is empty" do + Config.put([:mrf_simple, :report_removal], []) + report_message = build_report_message() + local_message = build_local_message() + + assert SimplePolicy.filter(report_message) == {:ok, report_message} + assert SimplePolicy.filter(local_message) == {:ok, local_message} + end + + test "has a matching host" do + Config.put([:mrf_simple, :report_removal], ["remote.instance"]) + report_message = build_report_message() + local_message = build_local_message() + + assert SimplePolicy.filter(report_message) == {:reject, nil} + assert SimplePolicy.filter(local_message) == {:ok, local_message} + end + end + + defp build_report_message do + %{ + "actor" => "https://remote.instance/users/bob", + "type" => "Flag" + } + end + + describe "when :federated_timeline_removal" do + test "is empty" do + Config.put([:mrf_simple, :federated_timeline_removal], []) + {_, ftl_message} = build_ftl_actor_and_message() + local_message = build_local_message() + + assert SimplePolicy.filter(ftl_message) == {:ok, ftl_message} + assert SimplePolicy.filter(local_message) == {:ok, local_message} + end + + test "has a matching host" do + {actor, ftl_message} = build_ftl_actor_and_message() + + ftl_message_actor_host = + ftl_message + |> Map.fetch!("actor") + |> URI.parse() + |> Map.fetch!(:host) + + Config.put([:mrf_simple, :federated_timeline_removal], [ftl_message_actor_host]) + local_message = build_local_message() + + assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message) + assert actor.follower_address in ftl_message["to"] + refute actor.follower_address in ftl_message["cc"] + refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"] + assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"] + + assert SimplePolicy.filter(local_message) == {:ok, local_message} + end + + test "has a matching host but only as:Public in to" do + {_actor, ftl_message} = build_ftl_actor_and_message() + + ftl_message_actor_host = + ftl_message + |> Map.fetch!("actor") + |> URI.parse() + |> Map.fetch!(:host) + + ftl_message = Map.put(ftl_message, "cc", []) + + Config.put([:mrf_simple, :federated_timeline_removal], [ftl_message_actor_host]) + + assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message) + refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"] + assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"] + end + end + + defp build_ftl_actor_and_message do + actor = insert(:user) + + {actor, + %{ + "actor" => actor.ap_id, + "to" => ["https://www.w3.org/ns/activitystreams#Public", "http://foo.bar/baz"], + "cc" => [actor.follower_address, "http://foo.bar/qux"] + }} + end + + describe "when :reject" do + test "is empty" do + Config.put([:mrf_simple, :reject], []) + + remote_message = build_remote_message() + + assert SimplePolicy.filter(remote_message) == {:ok, remote_message} + end + + test "has a matching host" do + Config.put([:mrf_simple, :reject], ["remote.instance"]) + + remote_message = build_remote_message() + + assert SimplePolicy.filter(remote_message) == {:reject, nil} + end + end + + describe "when :accept" do + test "is empty" do + Config.put([:mrf_simple, :accept], []) + + local_message = build_local_message() + remote_message = build_remote_message() + + assert SimplePolicy.filter(local_message) == {:ok, local_message} + assert SimplePolicy.filter(remote_message) == {:ok, remote_message} + end + + test "is not empty but it doesn't have a matching host" do + Config.put([:mrf_simple, :accept], ["non.matching.remote"]) + + local_message = build_local_message() + remote_message = build_remote_message() + + assert SimplePolicy.filter(local_message) == {:ok, local_message} + assert SimplePolicy.filter(remote_message) == {:reject, nil} + end + + test "has a matching host" do + Config.put([:mrf_simple, :accept], ["remote.instance"]) + + local_message = build_local_message() + remote_message = build_remote_message() + + assert SimplePolicy.filter(local_message) == {:ok, local_message} + assert SimplePolicy.filter(remote_message) == {:ok, remote_message} + end + end + + describe "when :avatar_removal" do + test "is empty" do + Config.put([:mrf_simple, :avatar_removal], []) + + remote_user = build_remote_user() + + assert SimplePolicy.filter(remote_user) == {:ok, remote_user} + end + + test "is not empty but it doesn't have a matching host" do + Config.put([:mrf_simple, :avatar_removal], ["non.matching.remote"]) + + remote_user = build_remote_user() + + assert SimplePolicy.filter(remote_user) == {:ok, remote_user} + end + + test "has a matching host" do + Config.put([:mrf_simple, :avatar_removal], ["remote.instance"]) + + remote_user = build_remote_user() + {:ok, filtered} = SimplePolicy.filter(remote_user) + + refute filtered["icon"] + end + end + + describe "when :banner_removal" do + test "is empty" do + Config.put([:mrf_simple, :banner_removal], []) + + remote_user = build_remote_user() + + assert SimplePolicy.filter(remote_user) == {:ok, remote_user} + end + + test "is not empty but it doesn't have a matching host" do + Config.put([:mrf_simple, :banner_removal], ["non.matching.remote"]) + + remote_user = build_remote_user() + + assert SimplePolicy.filter(remote_user) == {:ok, remote_user} + end + + test "has a matching host" do + Config.put([:mrf_simple, :banner_removal], ["remote.instance"]) + + remote_user = build_remote_user() + {:ok, filtered} = SimplePolicy.filter(remote_user) + + refute filtered["image"] + end + end + + defp build_local_message do + %{ + "actor" => "#{Pleroma.Web.base_url()}/users/alice", + "to" => [], + "cc" => [] + } + end + + defp build_remote_message do + %{"actor" => "https://remote.instance/users/bob"} + end + + defp build_remote_user do + %{ + "id" => "https://remote.instance/users/bob", + "icon" => %{ + "url" => "http://example.com/image.jpg", + "type" => "Image" + }, + "image" => %{ + "url" => "http://example.com/image.jpg", + "type" => "Image" + }, + "type" => "Person" + } + end +end diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 78429c7c6..89c8f79c9 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -113,6 +113,55 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do assert Enum.at(object.data["tag"], 2) == "moo" end + test "it works for incoming questions" do + data = File.read!("test/fixtures/mastodon-question-activity.json") |> Poison.decode!() + + {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data) + + object = Object.normalize(activity) + + assert Enum.all?(object.data["oneOf"], fn choice -> + choice["name"] in [ + "Dunno", + "Everyone knows that!", + "25 char limit is dumb", + "I can't even fit a funny" + ] + end) + end + + test "it rewrites Note votes to Answers and increments vote counters on question activities" do + user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{ + "status" => "suya...", + "poll" => %{"options" => ["suya", "suya.", "suya.."], "expires_in" => 10} + }) + + object = Object.normalize(activity) + + data = + File.read!("test/fixtures/mastodon-vote.json") + |> Poison.decode!() + |> Kernel.put_in(["to"], user.ap_id) + |> Kernel.put_in(["object", "inReplyTo"], object.data["id"]) + |> Kernel.put_in(["object", "to"], user.ap_id) + + {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data) + answer_object = Object.normalize(activity) + assert answer_object.data["type"] == "Answer" + object = Object.get_by_ap_id(object.data["id"]) + + assert Enum.any?( + object.data["oneOf"], + fn + %{"name" => "suya..", "replies" => %{"totalItems" => 1}} -> true + _ -> false + end + ) + end + test "it works for incoming notices with contentMap" do data = File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Poison.decode!() @@ -219,7 +268,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do Pleroma.Config.put([:user, :deny_follow_blocked], true) user = insert(:user) - target = User.get_or_fetch("http://mastodon.example.org/users/admin") + {:ok, target} = User.get_or_fetch("http://mastodon.example.org/users/admin") {:ok, user} = User.block(user, target) @@ -1209,4 +1258,85 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do {:ok, _} = Transmogrifier.prepare_outgoing(activity.data) end end + + test "Rewrites Answers to Notes" do + user = insert(:user) + + {:ok, poll_activity} = + CommonAPI.post(user, %{ + "status" => "suya...", + "poll" => %{"options" => ["suya", "suya.", "suya.."], "expires_in" => 10} + }) + + poll_object = Object.normalize(poll_activity) + # TODO: Replace with CommonAPI vote creation when implemented + data = + File.read!("test/fixtures/mastodon-vote.json") + |> Poison.decode!() + |> Kernel.put_in(["to"], user.ap_id) + |> Kernel.put_in(["object", "inReplyTo"], poll_object.data["id"]) + |> Kernel.put_in(["object", "to"], user.ap_id) + + {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data) + {:ok, data} = Transmogrifier.prepare_outgoing(activity.data) + + assert data["object"]["type"] == "Note" + end + + describe "fix_explicit_addressing" do + setup do + user = insert(:user) + [user: user] + end + + test "moves non-explicitly mentioned actors to cc", %{user: user} do + explicitly_mentioned_actors = [ + "https://pleroma.gold/users/user1", + "https://pleroma.gold/user2" + ] + + object = %{ + "actor" => user.ap_id, + "to" => explicitly_mentioned_actors ++ ["https://social.beepboop.ga/users/dirb"], + "cc" => [], + "tag" => + Enum.map(explicitly_mentioned_actors, fn href -> + %{"type" => "Mention", "href" => href} + end) + } + + fixed_object = Transmogrifier.fix_explicit_addressing(object) + assert Enum.all?(explicitly_mentioned_actors, &(&1 in fixed_object["to"])) + refute "https://social.beepboop.ga/users/dirb" in fixed_object["to"] + assert "https://social.beepboop.ga/users/dirb" in fixed_object["cc"] + end + + test "does not move actor's follower collection to cc", %{user: user} do + object = %{ + "actor" => user.ap_id, + "to" => [user.follower_address], + "cc" => [] + } + + fixed_object = Transmogrifier.fix_explicit_addressing(object) + assert user.follower_address in fixed_object["to"] + refute user.follower_address in fixed_object["cc"] + end + + test "removes recipient's follower collection from cc", %{user: user} do + recipient = insert(:user) + + object = %{ + "actor" => user.ap_id, + "to" => [recipient.ap_id, "https://www.w3.org/ns/activitystreams#Public"], + "cc" => [user.follower_address, recipient.follower_address] + } + + fixed_object = Transmogrifier.fix_explicit_addressing(object) + + assert user.follower_address in fixed_object["cc"] + refute recipient.follower_address in fixed_object["cc"] + refute recipient.follower_address in fixed_object["to"] + end + end end diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/web/activity_pub/views/user_view_test.exs index 9fb9455d2..e6483db8b 100644 --- a/test/web/activity_pub/views/user_view_test.exs +++ b/test/web/activity_pub/views/user_view_test.exs @@ -2,11 +2,12 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do use Pleroma.DataCase import Pleroma.Factory + alias Pleroma.User alias Pleroma.Web.ActivityPub.UserView test "Renders a user, including the public key" do user = insert(:user) - {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) + {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) @@ -18,7 +19,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do test "Does not add an avatar image if the user hasn't set one" do user = insert(:user) - {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) + {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) refute result["icon"] @@ -32,7 +33,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do } ) - {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) + {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) assert result["icon"]["url"] == "https://someurl" @@ -42,7 +43,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do describe "endpoints" do test "local users have a usable endpoints structure" do user = insert(:user) - {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) + {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) @@ -58,7 +59,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do test "remote users have an empty endpoints structure" do user = insert(:user, local: false) - {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) + {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) @@ -68,7 +69,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do test "instance users do not expose oAuth endpoints" do user = insert(:user, nickname: nil, local: true) - {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) + {:ok, user} = User.ensure_keys_present(user) result = UserView.render("user.json", %{user: user}) diff --git a/test/web/activity_pub/visibilty_test.exs b/test/web/activity_pub/visibilty_test.exs index 24b96c4aa..466d980dc 100644 --- a/test/web/activity_pub/visibilty_test.exs +++ b/test/web/activity_pub/visibilty_test.exs @@ -95,4 +95,30 @@ defmodule Pleroma.Web.ActivityPub.VisibilityTest do refute Visibility.visible_for_user?(private, unrelated) refute Visibility.visible_for_user?(direct, unrelated) end + + test "doesn't die when the user doesn't exist", + %{ + direct: direct, + user: user + } do + Repo.delete(user) + Cachex.clear(:user_cache) + refute Visibility.is_private?(direct) + end + + test "get_visibility", %{ + public: public, + private: private, + direct: direct, + unlisted: unlisted + } do + assert Visibility.get_visibility(public) == "public" + assert Visibility.get_visibility(private) == "private" + assert Visibility.get_visibility(direct) == "direct" + assert Visibility.get_visibility(unlisted) == "unlisted" + end + + test "get_visibility with directMessage flag" do + assert Visibility.get_visibility(%{data: %{"directMessage" => true}}) == "direct" + end end |
