logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma

activity_view_test.exs (12799B)


      1 # Pleroma: A lightweight social networking server
      2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
      3 # SPDX-License-Identifier: AGPL-3.0-only
      4 
      5 defmodule Pleroma.Web.TwitterAPI.ActivityViewTest do
      6   use Pleroma.DataCase
      7 
      8   alias Pleroma.Activity
      9   alias Pleroma.Object
     10   alias Pleroma.Repo
     11   alias Pleroma.User
     12   alias Pleroma.Web.ActivityPub.ActivityPub
     13   alias Pleroma.Web.CommonAPI
     14   alias Pleroma.Web.CommonAPI.Utils
     15   alias Pleroma.Web.TwitterAPI.ActivityView
     16   alias Pleroma.Web.TwitterAPI.UserView
     17 
     18   import Pleroma.Factory
     19   import Tesla.Mock
     20 
     21   setup do
     22     mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
     23     :ok
     24   end
     25 
     26   import Mock
     27 
     28   test "returns a temporary ap_id based user for activities missing db users" do
     29     user = insert(:user)
     30 
     31     {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"})
     32 
     33     Repo.delete(user)
     34     Cachex.clear(:user_cache)
     35 
     36     %{"user" => tw_user} = ActivityView.render("activity.json", activity: activity)
     37 
     38     assert tw_user["screen_name"] == "erroruser@example.com"
     39     assert tw_user["name"] == user.ap_id
     40     assert tw_user["statusnet_profile_url"] == user.ap_id
     41   end
     42 
     43   test "tries to get a user by nickname if fetching by ap_id doesn't work" do
     44     user = insert(:user)
     45 
     46     {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"})
     47 
     48     {:ok, user} =
     49       user
     50       |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"})
     51       |> Repo.update()
     52 
     53     Cachex.clear(:user_cache)
     54 
     55     result = ActivityView.render("activity.json", activity: activity)
     56     assert result["user"]["id"] == user.id
     57   end
     58 
     59   test "tells if the message is muted for some reason" do
     60     user = insert(:user)
     61     other_user = insert(:user)
     62 
     63     {:ok, user} = User.mute(user, other_user)
     64 
     65     {:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"})
     66     status = ActivityView.render("activity.json", %{activity: activity})
     67 
     68     assert status["muted"] == false
     69 
     70     status = ActivityView.render("activity.json", %{activity: activity, for: user})
     71 
     72     assert status["muted"] == true
     73   end
     74 
     75   test "a create activity with a html status" do
     76     text = """
     77     #Bike log - Commute Tuesday\nhttps://pla.bike/posts/20181211/\n#cycling #CHScycling #commute\nMVIMG_20181211_054020.jpg
     78     """
     79 
     80     {:ok, activity} = CommonAPI.post(insert(:user), %{"status" => text})
     81 
     82     result = ActivityView.render("activity.json", activity: activity)
     83 
     84     assert result["statusnet_html"] ==
     85              "<a class=\"hashtag\" data-tag=\"bike\" href=\"http://localhost:4001/tag/bike\" rel=\"tag\">#Bike</a> log - Commute Tuesday<br /><a href=\"https://pla.bike/posts/20181211/\">https://pla.bike/posts/20181211/</a><br /><a class=\"hashtag\" data-tag=\"cycling\" href=\"http://localhost:4001/tag/cycling\" rel=\"tag\">#cycling</a> <a class=\"hashtag\" data-tag=\"chscycling\" href=\"http://localhost:4001/tag/chscycling\" rel=\"tag\">#CHScycling</a> <a class=\"hashtag\" data-tag=\"commute\" href=\"http://localhost:4001/tag/commute\" rel=\"tag\">#commute</a><br />MVIMG_20181211_054020.jpg"
     86 
     87     assert result["text"] ==
     88              "#Bike log - Commute Tuesday\nhttps://pla.bike/posts/20181211/\n#cycling #CHScycling #commute\nMVIMG_20181211_054020.jpg"
     89   end
     90 
     91   test "a create activity with a summary containing emoji" do
     92     {:ok, activity} =
     93       CommonAPI.post(insert(:user), %{
     94         "spoiler_text" => ":firefox: meow",
     95         "status" => "."
     96       })
     97 
     98     result = ActivityView.render("activity.json", activity: activity)
     99 
    100     expected = ":firefox: meow"
    101 
    102     expected_html =
    103       "<img class=\"emoji\" alt=\"firefox\" title=\"firefox\" src=\"http://localhost:4001/emoji/Firefox.gif\" /> meow"
    104 
    105     assert result["summary"] == expected
    106     assert result["summary_html"] == expected_html
    107   end
    108 
    109   test "a create activity with a summary containing invalid HTML" do
    110     {:ok, activity} =
    111       CommonAPI.post(insert(:user), %{
    112         "spoiler_text" => "<span style=\"color: magenta; font-size: 32px;\">meow</span>",
    113         "status" => "."
    114       })
    115 
    116     result = ActivityView.render("activity.json", activity: activity)
    117 
    118     expected = "meow"
    119 
    120     assert result["summary"] == expected
    121     assert result["summary_html"] == expected
    122   end
    123 
    124   test "a create activity with a note" do
    125     user = insert(:user)
    126     other_user = insert(:user, %{nickname: "shp"})
    127 
    128     {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"})
    129     object = Object.normalize(activity)
    130 
    131     result = ActivityView.render("activity.json", activity: activity)
    132 
    133     convo_id = Utils.context_to_conversation_id(object.data["context"])
    134 
    135     expected = %{
    136       "activity_type" => "post",
    137       "attachments" => [],
    138       "attentions" => [
    139         UserView.render("show.json", %{user: other_user})
    140       ],
    141       "created_at" => object.data["published"] |> Utils.date_to_asctime(),
    142       "external_url" => object.data["id"],
    143       "fave_num" => 0,
    144       "favorited" => false,
    145       "id" => activity.id,
    146       "in_reply_to_status_id" => nil,
    147       "in_reply_to_screen_name" => nil,
    148       "in_reply_to_user_id" => nil,
    149       "in_reply_to_profileurl" => nil,
    150       "in_reply_to_ostatus_uri" => nil,
    151       "is_local" => true,
    152       "is_post_verb" => true,
    153       "possibly_sensitive" => false,
    154       "repeat_num" => 0,
    155       "repeated" => false,
    156       "pinned" => false,
    157       "statusnet_conversation_id" => convo_id,
    158       "summary" => "",
    159       "summary_html" => "",
    160       "statusnet_html" =>
    161         "Hey <span class=\"h-card\"><a data-user=\"#{other_user.id}\" class=\"u-url mention\" href=\"#{
    162           other_user.ap_id
    163         }\">@<span>shp</span></a></span>!",
    164       "tags" => [],
    165       "text" => "Hey @shp!",
    166       "uri" => object.data["id"],
    167       "user" => UserView.render("show.json", %{user: user}),
    168       "visibility" => "direct",
    169       "card" => nil,
    170       "muted" => false
    171     }
    172 
    173     assert result == expected
    174   end
    175 
    176   test "a list of activities" do
    177     user = insert(:user)
    178     other_user = insert(:user, %{nickname: "shp"})
    179     {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
    180     object = Object.normalize(activity)
    181 
    182     convo_id = Utils.context_to_conversation_id(object.data["context"])
    183 
    184     mocks = [
    185       {
    186         Utils,
    187         [:passthrough],
    188         [context_to_conversation_id: fn _ -> false end]
    189       },
    190       {
    191         User,
    192         [:passthrough],
    193         [get_cached_by_ap_id: fn _ -> nil end]
    194       }
    195     ]
    196 
    197     with_mocks mocks do
    198       [result] = ActivityView.render("index.json", activities: [activity])
    199 
    200       assert result["statusnet_conversation_id"] == convo_id
    201       assert result["user"]
    202       refute called(Utils.context_to_conversation_id(:_))
    203       refute called(User.get_cached_by_ap_id(user.ap_id))
    204       refute called(User.get_cached_by_ap_id(other_user.ap_id))
    205     end
    206   end
    207 
    208   test "an activity that is a reply" do
    209     user = insert(:user)
    210     other_user = insert(:user, %{nickname: "shp"})
    211 
    212     {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
    213 
    214     {:ok, answer} =
    215       CommonAPI.post(other_user, %{"status" => "Hi!", "in_reply_to_status_id" => activity.id})
    216 
    217     result = ActivityView.render("activity.json", %{activity: answer})
    218 
    219     assert result["in_reply_to_status_id"] == activity.id
    220   end
    221 
    222   test "a like activity" do
    223     user = insert(:user)
    224     other_user = insert(:user, %{nickname: "shp"})
    225 
    226     {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
    227     {:ok, like, _object} = CommonAPI.favorite(activity.id, other_user)
    228 
    229     result = ActivityView.render("activity.json", activity: like)
    230     activity = Pleroma.Activity.get_by_ap_id(activity.data["id"])
    231 
    232     expected = %{
    233       "activity_type" => "like",
    234       "created_at" => like.data["published"] |> Utils.date_to_asctime(),
    235       "external_url" => like.data["id"],
    236       "id" => like.id,
    237       "in_reply_to_status_id" => activity.id,
    238       "is_local" => true,
    239       "is_post_verb" => false,
    240       "favorited_status" => ActivityView.render("activity.json", activity: activity),
    241       "statusnet_html" => "shp favorited a status.",
    242       "text" => "shp favorited a status.",
    243       "uri" => "tag:#{like.data["id"]}:objectType=Favourite",
    244       "user" => UserView.render("show.json", user: other_user)
    245     }
    246 
    247     assert result == expected
    248   end
    249 
    250   test "a like activity for deleted post" do
    251     user = insert(:user)
    252     other_user = insert(:user, %{nickname: "shp"})
    253 
    254     {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
    255     {:ok, like, _object} = CommonAPI.favorite(activity.id, other_user)
    256     CommonAPI.delete(activity.id, user)
    257 
    258     result = ActivityView.render("activity.json", activity: like)
    259 
    260     expected = %{
    261       "activity_type" => "like",
    262       "created_at" => like.data["published"] |> Utils.date_to_asctime(),
    263       "external_url" => like.data["id"],
    264       "id" => like.id,
    265       "in_reply_to_status_id" => nil,
    266       "is_local" => true,
    267       "is_post_verb" => false,
    268       "favorited_status" => nil,
    269       "statusnet_html" => "shp favorited a status.",
    270       "text" => "shp favorited a status.",
    271       "uri" => "tag:#{like.data["id"]}:objectType=Favourite",
    272       "user" => UserView.render("show.json", user: other_user)
    273     }
    274 
    275     assert result == expected
    276   end
    277 
    278   test "an announce activity" do
    279     user = insert(:user)
    280     other_user = insert(:user, %{nickname: "shp"})
    281 
    282     {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
    283     {:ok, announce, object} = CommonAPI.repeat(activity.id, other_user)
    284 
    285     convo_id = Utils.context_to_conversation_id(object.data["context"])
    286 
    287     activity = Activity.get_by_id(activity.id)
    288 
    289     result = ActivityView.render("activity.json", activity: announce)
    290 
    291     expected = %{
    292       "activity_type" => "repeat",
    293       "created_at" => announce.data["published"] |> Utils.date_to_asctime(),
    294       "external_url" => announce.data["id"],
    295       "id" => announce.id,
    296       "is_local" => true,
    297       "is_post_verb" => false,
    298       "statusnet_html" => "shp repeated a status.",
    299       "text" => "shp repeated a status.",
    300       "uri" => "tag:#{announce.data["id"]}:objectType=note",
    301       "user" => UserView.render("show.json", user: other_user),
    302       "retweeted_status" => ActivityView.render("activity.json", activity: activity),
    303       "statusnet_conversation_id" => convo_id
    304     }
    305 
    306     assert result == expected
    307   end
    308 
    309   test "A follow activity" do
    310     user = insert(:user)
    311     other_user = insert(:user, %{nickname: "shp"})
    312 
    313     {:ok, follower} = User.follow(user, other_user)
    314     {:ok, follow} = ActivityPub.follow(follower, other_user)
    315 
    316     result = ActivityView.render("activity.json", activity: follow)
    317 
    318     expected = %{
    319       "activity_type" => "follow",
    320       "attentions" => [],
    321       "created_at" => follow.data["published"] |> Utils.date_to_asctime(),
    322       "external_url" => follow.data["id"],
    323       "id" => follow.id,
    324       "in_reply_to_status_id" => nil,
    325       "is_local" => true,
    326       "is_post_verb" => false,
    327       "statusnet_html" => "#{user.nickname} started following shp",
    328       "text" => "#{user.nickname} started following shp",
    329       "user" => UserView.render("show.json", user: user)
    330     }
    331 
    332     assert result == expected
    333   end
    334 
    335   test "a delete activity" do
    336     user = insert(:user)
    337 
    338     {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
    339     {:ok, delete} = CommonAPI.delete(activity.id, user)
    340 
    341     result = ActivityView.render("activity.json", activity: delete)
    342 
    343     expected = %{
    344       "activity_type" => "delete",
    345       "attentions" => [],
    346       "created_at" => delete.data["published"] |> Utils.date_to_asctime(),
    347       "external_url" => delete.data["id"],
    348       "id" => delete.id,
    349       "in_reply_to_status_id" => nil,
    350       "is_local" => true,
    351       "is_post_verb" => false,
    352       "statusnet_html" => "deleted notice {{tag",
    353       "text" => "deleted notice {{tag",
    354       "uri" => Object.normalize(delete).data["id"],
    355       "user" => UserView.render("show.json", user: user)
    356     }
    357 
    358     assert result == expected
    359   end
    360 
    361   test "a peertube video" do
    362     {:ok, object} =
    363       Pleroma.Object.Fetcher.fetch_object_from_id(
    364         "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
    365       )
    366 
    367     %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
    368 
    369     result = ActivityView.render("activity.json", activity: activity)
    370 
    371     assert length(result["attachments"]) == 1
    372     assert result["summary"] == "Friday Night"
    373   end
    374 
    375   test "special characters are not escaped in text field for status created" do
    376     text = "<3 is on the way"
    377 
    378     {:ok, activity} = CommonAPI.post(insert(:user), %{"status" => text})
    379 
    380     result = ActivityView.render("activity.json", activity: activity)
    381 
    382     assert result["text"] == text
    383   end
    384 end