Add tests for emoji and lack of HTML in summaries.
[akkoma] / test / web / twitter_api / views / activity_view_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2018 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.Web.CommonAPI
9 alias Pleroma.Web.CommonAPI.Utils
10 alias Pleroma.Web.TwitterAPI.ActivityView
11 alias Pleroma.Web.TwitterAPI.UserView
12 alias Pleroma.Web.TwitterAPI.TwitterAPI
13 alias Pleroma.Repo
14 alias Pleroma.Activity
15 alias Pleroma.User
16 alias Pleroma.Web.ActivityPub.ActivityPub
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 "a create activity with a html status" do
29 text = """
30 #Bike log - Commute Tuesday\nhttps://pla.bike/posts/20181211/\n#cycling #CHScycling #commute\nMVIMG_20181211_054020.jpg
31 """
32
33 {:ok, activity} = CommonAPI.post(insert(:user), %{"status" => text})
34
35 result = ActivityView.render("activity.json", activity: activity)
36
37 assert result["statusnet_html"] ==
38 "<a data-tag=\"bike\" href=\"http://localhost:4001/tag/bike\">#Bike</a> log - Commute Tuesday<br /><a href=\"https://pla.bike/posts/20181211/\">https://pla.bike/posts/20181211/</a><br /><a data-tag=\"cycling\" href=\"http://localhost:4001/tag/cycling\">#cycling</a> <a data-tag=\"chscycling\" href=\"http://localhost:4001/tag/chscycling\">#CHScycling</a> <a data-tag=\"commute\" href=\"http://localhost:4001/tag/commute\">#commute</a><br />MVIMG_20181211_054020.jpg"
39
40 assert result["text"] ==
41 "#Bike log - Commute Tuesday\nhttps://pla.bike/posts/20181211/\n#cycling #CHScycling #commute\nMVIMG_20181211_054020.jpg"
42 end
43
44 test "a create activity with a summary containing emoji" do
45 {:ok, activity} =
46 CommonAPI.post(insert(:user), %{
47 "spoiler_text" => ":woollysocks: meow",
48 "status" => "."
49 })
50
51 result = ActivityView.render("activity.json", activity: activity)
52
53 expected =
54 "<img height=\"32px\" width=\"32px\" alt=\"woollysocks\" title=\"woollysocks\" src=\"http://localhost:4001/finmoji/128px/woollysocks-128.png\" /> meow"
55
56 assert result["summary"] == expected
57 end
58
59 test "a create activity with a summary containing invalid HTML" do
60 {:ok, activity} =
61 CommonAPI.post(insert(:user), %{
62 "spoiler_text" => "<span style=\"color: magenta; font-size: 32px;\">meow</span>",
63 "status" => "."
64 })
65
66 result = ActivityView.render("activity.json", activity: activity)
67
68 expected = "meow"
69
70 assert result["summary"] == expected
71 end
72
73 test "a create activity with a note" do
74 user = insert(:user)
75 other_user = insert(:user, %{nickname: "shp"})
76
77 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"})
78
79 result = ActivityView.render("activity.json", activity: activity)
80
81 convo_id = TwitterAPI.context_to_conversation_id(activity.data["object"]["context"])
82
83 expected = %{
84 "activity_type" => "post",
85 "attachments" => [],
86 "attentions" => [
87 UserView.render("show.json", %{user: other_user})
88 ],
89 "created_at" => activity.data["object"]["published"] |> Utils.date_to_asctime(),
90 "external_url" => activity.data["object"]["id"],
91 "fave_num" => 0,
92 "favorited" => false,
93 "id" => activity.id,
94 "in_reply_to_status_id" => nil,
95 "in_reply_to_screen_name" => nil,
96 "in_reply_to_user_id" => nil,
97 "in_reply_to_profileurl" => nil,
98 "in_reply_to_ostatus_uri" => nil,
99 "is_local" => true,
100 "is_post_verb" => true,
101 "possibly_sensitive" => false,
102 "repeat_num" => 0,
103 "repeated" => false,
104 "statusnet_conversation_id" => convo_id,
105 "summary" => "",
106 "statusnet_html" =>
107 "Hey <span><a data-user=\"#{other_user.id}\" href=\"#{other_user.ap_id}\">@<span>shp</span></a></span>!",
108 "tags" => [],
109 "text" => "Hey @shp!",
110 "uri" => activity.data["object"]["id"],
111 "user" => UserView.render("show.json", %{user: user}),
112 "visibility" => "direct"
113 }
114
115 assert result == expected
116 end
117
118 test "a list of activities" do
119 user = insert(:user)
120 other_user = insert(:user, %{nickname: "shp"})
121 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
122
123 convo_id = TwitterAPI.context_to_conversation_id(activity.data["object"]["context"])
124
125 mocks = [
126 {
127 TwitterAPI,
128 [],
129 [context_to_conversation_id: fn _ -> false end]
130 },
131 {
132 User,
133 [:passthrough],
134 [get_cached_by_ap_id: fn _ -> nil end]
135 }
136 ]
137
138 with_mocks mocks do
139 [result] = ActivityView.render("index.json", activities: [activity])
140
141 assert result["statusnet_conversation_id"] == convo_id
142 assert result["user"]
143 refute called(TwitterAPI.context_to_conversation_id(:_))
144 refute called(User.get_cached_by_ap_id(user.ap_id))
145 refute called(User.get_cached_by_ap_id(other_user.ap_id))
146 end
147 end
148
149 test "an activity that is a reply" do
150 user = insert(:user)
151 other_user = insert(:user, %{nickname: "shp"})
152
153 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
154
155 {:ok, answer} =
156 CommonAPI.post(other_user, %{"status" => "Hi!", "in_reply_to_status_id" => activity.id})
157
158 result = ActivityView.render("activity.json", %{activity: answer})
159
160 assert result["in_reply_to_status_id"] == activity.id
161 end
162
163 test "a like activity" do
164 user = insert(:user)
165 other_user = insert(:user, %{nickname: "shp"})
166
167 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
168 {:ok, like, _object} = CommonAPI.favorite(activity.id, other_user)
169
170 result = ActivityView.render("activity.json", activity: like)
171 activity = Pleroma.Activity.get_by_ap_id(activity.data["id"])
172
173 expected = %{
174 "activity_type" => "like",
175 "created_at" => like.data["published"] |> Utils.date_to_asctime(),
176 "external_url" => like.data["id"],
177 "id" => like.id,
178 "in_reply_to_status_id" => activity.id,
179 "is_local" => true,
180 "is_post_verb" => false,
181 "favorited_status" => ActivityView.render("activity.json", activity: activity),
182 "statusnet_html" => "shp favorited a status.",
183 "text" => "shp favorited a status.",
184 "uri" => "tag:#{like.data["id"]}:objectType=Favourite",
185 "user" => UserView.render("show.json", user: other_user)
186 }
187
188 assert result == expected
189 end
190
191 test "a like activity for deleted post" do
192 user = insert(:user)
193 other_user = insert(:user, %{nickname: "shp"})
194
195 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
196 {:ok, like, _object} = CommonAPI.favorite(activity.id, other_user)
197 CommonAPI.delete(activity.id, user)
198
199 result = ActivityView.render("activity.json", activity: like)
200
201 expected = %{
202 "activity_type" => "like",
203 "created_at" => like.data["published"] |> Utils.date_to_asctime(),
204 "external_url" => like.data["id"],
205 "id" => like.id,
206 "in_reply_to_status_id" => nil,
207 "is_local" => true,
208 "is_post_verb" => false,
209 "favorited_status" => nil,
210 "statusnet_html" => "shp favorited a status.",
211 "text" => "shp favorited a status.",
212 "uri" => "tag:#{like.data["id"]}:objectType=Favourite",
213 "user" => UserView.render("show.json", user: other_user)
214 }
215
216 assert result == expected
217 end
218
219 test "an announce activity" do
220 user = insert(:user)
221 other_user = insert(:user, %{nickname: "shp"})
222
223 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
224 {:ok, announce, _object} = CommonAPI.repeat(activity.id, other_user)
225
226 convo_id = TwitterAPI.context_to_conversation_id(activity.data["object"]["context"])
227
228 activity = Repo.get(Activity, activity.id)
229
230 result = ActivityView.render("activity.json", activity: announce)
231
232 expected = %{
233 "activity_type" => "repeat",
234 "created_at" => announce.data["published"] |> Utils.date_to_asctime(),
235 "external_url" => announce.data["id"],
236 "id" => announce.id,
237 "is_local" => true,
238 "is_post_verb" => false,
239 "statusnet_html" => "shp retweeted a status.",
240 "text" => "shp retweeted a status.",
241 "uri" => "tag:#{announce.data["id"]}:objectType=note",
242 "user" => UserView.render("show.json", user: other_user),
243 "retweeted_status" => ActivityView.render("activity.json", activity: activity),
244 "statusnet_conversation_id" => convo_id
245 }
246
247 assert result == expected
248 end
249
250 test "A follow activity" do
251 user = insert(:user)
252 other_user = insert(:user, %{nickname: "shp"})
253
254 {:ok, follower} = User.follow(user, other_user)
255 {:ok, follow} = ActivityPub.follow(follower, other_user)
256
257 result = ActivityView.render("activity.json", activity: follow)
258
259 expected = %{
260 "activity_type" => "follow",
261 "attentions" => [],
262 "created_at" => follow.data["published"] |> Utils.date_to_asctime(),
263 "external_url" => follow.data["id"],
264 "id" => follow.id,
265 "in_reply_to_status_id" => nil,
266 "is_local" => true,
267 "is_post_verb" => false,
268 "statusnet_html" => "#{user.nickname} started following shp",
269 "text" => "#{user.nickname} started following shp",
270 "user" => UserView.render("show.json", user: user)
271 }
272
273 assert result == expected
274 end
275
276 test "a delete activity" do
277 user = insert(:user)
278
279 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
280 {:ok, delete} = CommonAPI.delete(activity.id, user)
281
282 result = ActivityView.render("activity.json", activity: delete)
283
284 expected = %{
285 "activity_type" => "delete",
286 "attentions" => [],
287 "created_at" => delete.data["published"] |> Utils.date_to_asctime(),
288 "external_url" => delete.data["id"],
289 "id" => delete.id,
290 "in_reply_to_status_id" => nil,
291 "is_local" => true,
292 "is_post_verb" => false,
293 "statusnet_html" => "deleted notice {{tag",
294 "text" => "deleted notice {{tag",
295 "uri" => delete.data["object"],
296 "user" => UserView.render("show.json", user: user)
297 }
298
299 assert result == expected
300 end
301
302 test "a peertube video" do
303 {:ok, object} =
304 ActivityPub.fetch_object_from_id(
305 "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
306 )
307
308 %Activity{} = activity = Activity.get_create_activity_by_object_ap_id(object.data["id"])
309
310 result = ActivityView.render("activity.json", activity: activity)
311
312 assert length(result["attachments"]) == 1
313 assert result["summary"] == "Friday Night"
314 end
315 end