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  | 
