diff options
Diffstat (limited to 'test/web/activity_pub')
-rw-r--r-- | test/web/activity_pub/activity_pub_test.exs | 237 | ||||
-rw-r--r-- | test/web/activity_pub/mrf/normalize_markup_test.exs | 10 | ||||
-rw-r--r-- | test/web/activity_pub/transmogrifier_test.exs | 141 | ||||
-rw-r--r-- | test/web/activity_pub/utils_test.exs | 11 |
4 files changed, 335 insertions, 64 deletions
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index bbae3fcf1..71aab92c3 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -13,6 +13,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Utils + alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.CommonAPI import Pleroma.Factory @@ -736,56 +737,54 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end test "retrieves a maximum of 20 activities" do - activities = ActivityBuilder.insert_list(30) - last_expected = List.last(activities) + ActivityBuilder.insert_list(10) + expected_activities = ActivityBuilder.insert_list(20) activities = ActivityPub.fetch_public_activities() - last = List.last(activities) + assert collect_ids(activities) == collect_ids(expected_activities) assert length(activities) == 20 - assert last == last_expected end test "retrieves ids starting from a since_id" do activities = ActivityBuilder.insert_list(30) - later_activities = ActivityBuilder.insert_list(10) + expected_activities = ActivityBuilder.insert_list(10) since_id = List.last(activities).id - last_expected = List.last(later_activities) activities = ActivityPub.fetch_public_activities(%{"since_id" => since_id}) - last = List.last(activities) + assert collect_ids(activities) == collect_ids(expected_activities) assert length(activities) == 10 - assert last == last_expected end test "retrieves ids up to max_id" do - _first_activities = ActivityBuilder.insert_list(10) - activities = ActivityBuilder.insert_list(20) - later_activities = ActivityBuilder.insert_list(10) - max_id = List.first(later_activities).id - last_expected = List.last(activities) + ActivityBuilder.insert_list(10) + expected_activities = ActivityBuilder.insert_list(20) + + %{id: max_id} = + 10 + |> ActivityBuilder.insert_list() + |> List.first() activities = ActivityPub.fetch_public_activities(%{"max_id" => max_id}) - last = List.last(activities) assert length(activities) == 20 - assert last == last_expected + assert collect_ids(activities) == collect_ids(expected_activities) end test "paginates via offset/limit" do - _first_activities = ActivityBuilder.insert_list(10) - activities = ActivityBuilder.insert_list(10) - _later_activities = ActivityBuilder.insert_list(10) - first_expected = List.first(activities) + _first_part_activities = ActivityBuilder.insert_list(10) + second_part_activities = ActivityBuilder.insert_list(10) + + later_activities = ActivityBuilder.insert_list(10) activities = ActivityPub.fetch_public_activities(%{"page" => "2", "page_size" => "20"}, :offset) - first = List.first(activities) - assert length(activities) == 20 - assert first == first_expected + + assert collect_ids(activities) == + collect_ids(second_part_activities) ++ collect_ids(later_activities) end test "doesn't return reblogs for users for whom reblogs have been muted" do @@ -816,6 +815,78 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end end + describe "react to an object" do + test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do + Pleroma.Config.put([:instance, :federating], true) + user = insert(:user) + reactor = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) + assert object = Object.normalize(activity) + + {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥") + + assert called(Pleroma.Web.Federator.publish(reaction_activity)) + end + + test "adds an emoji reaction activity to the db" do + user = insert(:user) + reactor = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) + assert object = Object.normalize(activity) + + {:ok, reaction_activity, object} = ActivityPub.react_with_emoji(reactor, object, "🔥") + + assert reaction_activity + + assert reaction_activity.data["actor"] == reactor.ap_id + assert reaction_activity.data["type"] == "EmojiReaction" + assert reaction_activity.data["content"] == "🔥" + assert reaction_activity.data["object"] == object.data["id"] + assert reaction_activity.data["to"] == [User.ap_followers(reactor), activity.data["actor"]] + assert reaction_activity.data["context"] == object.data["context"] + assert object.data["reaction_count"] == 1 + assert object.data["reactions"]["🔥"] == [reactor.ap_id] + end + end + + describe "unreacting to an object" do + test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do + Pleroma.Config.put([:instance, :federating], true) + user = insert(:user) + reactor = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) + assert object = Object.normalize(activity) + + {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥") + + assert called(Pleroma.Web.Federator.publish(reaction_activity)) + + {:ok, unreaction_activity, _object} = + ActivityPub.unreact_with_emoji(reactor, reaction_activity.data["id"]) + + assert called(Pleroma.Web.Federator.publish(unreaction_activity)) + end + + test "adds an undo activity to the db" do + user = insert(:user) + reactor = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) + assert object = Object.normalize(activity) + + {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥") + + {:ok, unreaction_activity, _object} = + ActivityPub.unreact_with_emoji(reactor, reaction_activity.data["id"]) + + assert unreaction_activity.actor == reactor.ap_id + assert unreaction_activity.data["object"] == reaction_activity.data["id"] + + object = Object.get_by_ap_id(object.data["id"]) + assert object.data["reaction_count"] == 0 + assert object.data["reactions"] == %{} + end + end + describe "like an object" do test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do Pleroma.Config.put([:instance, :federating], true) @@ -1284,35 +1355,99 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert 3 = length(activities) end - test "it can create a Flag activity" do - reporter = insert(:user) - target_account = insert(:user) - {:ok, activity} = CommonAPI.post(target_account, %{"status" => "foobar"}) - context = Utils.generate_context_id() - content = "foobar" - - reporter_ap_id = reporter.ap_id - target_ap_id = target_account.ap_id - activity_ap_id = activity.data["id"] - - assert {:ok, activity} = - ActivityPub.flag(%{ - actor: reporter, - context: context, - account: target_account, - statuses: [activity], - content: content - }) - - assert %Activity{ - actor: ^reporter_ap_id, - data: %{ - "type" => "Flag", - "content" => ^content, - "context" => ^context, - "object" => [^target_ap_id, ^activity_ap_id] - } - } = activity + describe "flag/1" do + setup do + reporter = insert(:user) + target_account = insert(:user) + content = "foobar" + {:ok, activity} = CommonAPI.post(target_account, %{"status" => content}) + context = Utils.generate_context_id() + + reporter_ap_id = reporter.ap_id + target_ap_id = target_account.ap_id + activity_ap_id = activity.data["id"] + + activity_with_object = Activity.get_by_ap_id_with_object(activity_ap_id) + + {:ok, + %{ + reporter: reporter, + context: context, + target_account: target_account, + reported_activity: activity, + content: content, + activity_ap_id: activity_ap_id, + activity_with_object: activity_with_object, + reporter_ap_id: reporter_ap_id, + target_ap_id: target_ap_id + }} + end + + test "it can create a Flag activity", + %{ + reporter: reporter, + context: context, + target_account: target_account, + reported_activity: reported_activity, + content: content, + activity_ap_id: activity_ap_id, + activity_with_object: activity_with_object, + reporter_ap_id: reporter_ap_id, + target_ap_id: target_ap_id + } do + assert {:ok, activity} = + ActivityPub.flag(%{ + actor: reporter, + context: context, + account: target_account, + statuses: [reported_activity], + content: content + }) + + note_obj = %{ + "type" => "Note", + "id" => activity_ap_id, + "content" => content, + "published" => activity_with_object.object.data["published"], + "actor" => AccountView.render("show.json", %{user: target_account}) + } + + assert %Activity{ + actor: ^reporter_ap_id, + data: %{ + "type" => "Flag", + "content" => ^content, + "context" => ^context, + "object" => [^target_ap_id, ^note_obj] + } + } = activity + end + + test_with_mock "strips status data from Flag, before federating it", + %{ + reporter: reporter, + context: context, + target_account: target_account, + reported_activity: reported_activity, + content: content + }, + Utils, + [:passthrough], + [] do + {:ok, activity} = + ActivityPub.flag(%{ + actor: reporter, + context: context, + account: target_account, + statuses: [reported_activity], + content: content + }) + + new_data = + put_in(activity.data, ["object"], [target_account.ap_id, reported_activity.data["id"]]) + + assert_called(Utils.maybe_federate(%{activity | data: new_data})) + end end test "fetch_activities/2 returns activities addressed to a list " do diff --git a/test/web/activity_pub/mrf/normalize_markup_test.exs b/test/web/activity_pub/mrf/normalize_markup_test.exs index 3916a1f35..0207be56b 100644 --- a/test/web/activity_pub/mrf/normalize_markup_test.exs +++ b/test/web/activity_pub/mrf/normalize_markup_test.exs @@ -20,11 +20,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do expected = """ <b>this is in bold</b> <p>this is a paragraph</p> - this is a linebreak<br /> - this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a> - this is a link with not allowed "rel" attribute: <a href="http://example.com/">example.com</a> - this is an image: <img src="http://example.com/image.jpg" /><br /> - alert('hacked') + this is a linebreak<br/> + this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a> + this is a link with not allowed "rel" attribute: <a href="http://example.com/">example.com</a> + this is an image: <img src="http://example.com/image.jpg"/><br/> + alert('hacked') """ message = %{"type" => "Create", "object" => %{"content" => @html_sample}} diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 76e7ad8ea..517a9621a 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Transmogrifier + alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.CommonAPI import Mock @@ -338,6 +339,80 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do assert data["object"] == activity.data["object"] end + test "it works for incoming misskey likes, turning them into EmojiReactions" do + user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) + + data = + File.read!("test/fixtures/misskey-like.json") + |> Poison.decode!() + |> Map.put("object", activity.data["object"]) + + {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + + assert data["actor"] == data["actor"] + assert data["type"] == "EmojiReaction" + assert data["id"] == data["id"] + assert data["object"] == activity.data["object"] + assert data["content"] == "🍮" + end + + test "it works for incoming misskey likes that contain unicode emojis, turning them into EmojiReactions" do + user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) + + data = + File.read!("test/fixtures/misskey-like.json") + |> Poison.decode!() + |> Map.put("object", activity.data["object"]) + |> Map.put("_misskey_reaction", "⭐") + + {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + + assert data["actor"] == data["actor"] + assert data["type"] == "EmojiReaction" + assert data["id"] == data["id"] + assert data["object"] == activity.data["object"] + assert data["content"] == "⭐" + end + + test "it works for incoming emoji reactions" do + user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) + + data = + File.read!("test/fixtures/emoji-reaction.json") + |> Poison.decode!() + |> Map.put("object", activity.data["object"]) + + {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + + assert data["actor"] == "http://mastodon.example.org/users/admin" + assert data["type"] == "EmojiReaction" + assert data["id"] == "http://mastodon.example.org/users/admin#reactions/2" + assert data["object"] == activity.data["object"] + assert data["content"] == "👌" + end + + test "it works for incoming emoji reaction undos" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) + {:ok, reaction_activity, _object} = CommonAPI.react_with_emoji(activity.id, user, "👌") + + data = + File.read!("test/fixtures/mastodon-undo-like.json") + |> Poison.decode!() + |> Map.put("object", reaction_activity.data["id"]) + |> Map.put("actor", user.ap_id) + + {:ok, activity} = Transmogrifier.handle_incoming(data) + + assert activity.actor == user.ap_id + assert activity.data["id"] == data["id"] + assert activity.data["type"] == "Undo" + end + test "it returns an error for incoming unlikes wihout a like activity" do user = insert(:user) {:ok, activity} = CommonAPI.post(user, %{"status" => "leave a like pls"}) @@ -552,6 +627,20 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do refute Map.has_key?(object.data, "likes") end + test "it strips internal reactions" do + user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"}) + {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, user, "📢") + + %{object: object} = Activity.get_by_id_with_object(activity.id) + assert Map.has_key?(object.data, "reactions") + assert Map.has_key?(object.data, "reaction_count") + + object_data = Transmogrifier.strip_internal_fields(object.data) + refute Map.has_key?(object_data, "reactions") + refute Map.has_key?(object_data, "reaction_count") + end + test "it works for incoming update activities" do data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() @@ -777,7 +866,10 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do |> Poison.decode!() |> Map.put("actor", ap_id) - assert :error == Transmogrifier.handle_incoming(data) + assert capture_log(fn -> + assert :error == Transmogrifier.handle_incoming(data) + end) =~ "Object containment failed" + assert User.get_cached_by_ap_id(ap_id) end @@ -835,6 +927,25 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do refute User.following?(User.get_cached_by_ap_id(data["actor"]), user) end + test "it works for incoming follows to locked account" do + pending_follower = insert(:user, ap_id: "http://mastodon.example.org/users/admin") + user = insert(:user, locked: true) + + data = + File.read!("test/fixtures/mastodon-follow-activity.json") + |> Poison.decode!() + |> Map.put("object", user.ap_id) + + {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + + assert data["type"] == "Follow" + assert data["object"] == user.ap_id + assert data["state"] == "pending" + assert data["actor"] == "http://mastodon.example.org/users/admin" + + assert [^pending_follower] = User.get_follow_requests(user) + end + test "it works for incoming blocks" do user = insert(:user) @@ -1121,10 +1232,18 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"}) object = Object.normalize(activity) + note_obj = %{ + "type" => "Note", + "id" => activity.data["id"], + "content" => "test post", + "published" => object.data["published"], + "actor" => AccountView.render("show.json", %{user: user}) + } + message = %{ "@context" => "https://www.w3.org/ns/activitystreams", "cc" => [user.ap_id], - "object" => [user.ap_id, object.data["id"]], + "object" => [user.ap_id, activity.data["id"]], "type" => "Flag", "content" => "blocked AND reported!!!", "actor" => other_user.ap_id @@ -1132,7 +1251,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do assert {:ok, activity} = Transmogrifier.handle_incoming(message) - assert activity.data["object"] == [user.ap_id, object.data["id"]] + assert activity.data["object"] == [user.ap_id, note_obj] assert activity.data["content"] == "blocked AND reported!!!" assert activity.data["actor"] == other_user.ap_id assert activity.data["cc"] == [user.ap_id] @@ -1464,7 +1583,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do "type" => "Announce" } - :error = Transmogrifier.handle_incoming(data) + assert capture_log(fn -> + :error = Transmogrifier.handle_incoming(data) + end) =~ "Object containment failed" end test "it rejects activities which reference objects that have an incorrect attribution (variant 1)" do @@ -1477,7 +1598,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do "type" => "Announce" } - :error = Transmogrifier.handle_incoming(data) + assert capture_log(fn -> + :error = Transmogrifier.handle_incoming(data) + end) =~ "Object containment failed" end test "it rejects activities which reference objects that have an incorrect attribution (variant 2)" do @@ -1490,7 +1613,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do "type" => "Announce" } - :error = Transmogrifier.handle_incoming(data) + assert capture_log(fn -> + :error = Transmogrifier.handle_incoming(data) + end) =~ "Object containment failed" end end @@ -1793,7 +1918,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do describe "get_obj_helper/2" do test "returns nil when cannot normalize object" do - refute Transmogrifier.get_obj_helper("test-obj-id") + assert capture_log(fn -> + refute Transmogrifier.get_obj_helper("test-obj-id") + end) =~ "Unsupported URI scheme" end test "returns {:ok, %Object{}} for success case" do diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs index c1b000fac..586eb1d2f 100644 --- a/test/web/activity_pub/utils_test.exs +++ b/test/web/activity_pub/utils_test.exs @@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Utils + alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.CommonAPI import Pleroma.Factory @@ -581,11 +582,19 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do %{} ) + note_obj = %{ + "type" => "Note", + "id" => activity_ap_id, + "content" => content, + "published" => activity.object.data["published"], + "actor" => AccountView.render("show.json", %{user: target_account}) + } + assert %{ "type" => "Flag", "content" => ^content, "context" => ^context, - "object" => [^target_ap_id, ^activity_ap_id], + "object" => [^target_ap_id, ^note_obj], "state" => "open" } = res end |