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