Merge branch 'feature/788-separate-email-addresses' into 'develop'
[akkoma] / test / web / mastodon_api / status_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.MastodonAPI.StatusViewTest do
6 use Pleroma.DataCase
7
8 alias Pleroma.Activity
9 alias Pleroma.User
10 alias Pleroma.Web.ActivityPub.ActivityPub
11 alias Pleroma.Web.CommonAPI
12 alias Pleroma.Web.CommonAPI.Utils
13 alias Pleroma.Web.MastodonAPI.AccountView
14 alias Pleroma.Web.MastodonAPI.StatusView
15 alias Pleroma.Web.OStatus
16 import Pleroma.Factory
17 import Tesla.Mock
18
19 setup do
20 mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
21 :ok
22 end
23
24 test "returns a temporary ap_id based user for activities missing db users" do
25 user = insert(:user)
26
27 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"})
28
29 Repo.delete(user)
30 Cachex.clear(:user_cache)
31
32 %{account: ms_user} = StatusView.render("status.json", activity: activity)
33
34 assert ms_user.acct == "erroruser@example.com"
35 end
36
37 test "tries to get a user by nickname if fetching by ap_id doesn't work" do
38 user = insert(:user)
39
40 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"})
41
42 {:ok, user} =
43 user
44 |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"})
45 |> Repo.update()
46
47 Cachex.clear(:user_cache)
48
49 result = StatusView.render("status.json", activity: activity)
50
51 assert result[:account][:id] == to_string(user.id)
52 end
53
54 test "a note with null content" do
55 note = insert(:note_activity)
56
57 data =
58 note.data
59 |> put_in(["object", "content"], nil)
60
61 note =
62 note
63 |> Map.put(:data, data)
64
65 User.get_cached_by_ap_id(note.data["actor"])
66
67 status = StatusView.render("status.json", %{activity: note})
68
69 assert status.content == ""
70 end
71
72 test "a note activity" do
73 note = insert(:note_activity)
74 user = User.get_cached_by_ap_id(note.data["actor"])
75
76 convo_id = Utils.context_to_conversation_id(note.data["object"]["context"])
77
78 status = StatusView.render("status.json", %{activity: note})
79
80 created_at =
81 (note.data["object"]["published"] || "")
82 |> String.replace(~r/\.\d+Z/, ".000Z")
83
84 expected = %{
85 id: to_string(note.id),
86 uri: note.data["object"]["id"],
87 url: Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, note),
88 account: AccountView.render("account.json", %{user: user}),
89 in_reply_to_id: nil,
90 in_reply_to_account_id: nil,
91 card: nil,
92 reblog: nil,
93 content: HtmlSanitizeEx.basic_html(note.data["object"]["content"]),
94 created_at: created_at,
95 reblogs_count: 0,
96 replies_count: 0,
97 favourites_count: 0,
98 reblogged: false,
99 bookmarked: false,
100 favourited: false,
101 muted: false,
102 pinned: false,
103 sensitive: false,
104 spoiler_text: HtmlSanitizeEx.basic_html(note.data["object"]["summary"]),
105 visibility: "public",
106 media_attachments: [],
107 mentions: [],
108 tags: [
109 %{
110 name: "#{note.data["object"]["tag"]}",
111 url: "/tag/#{note.data["object"]["tag"]}"
112 }
113 ],
114 application: %{
115 name: "Web",
116 website: nil
117 },
118 language: nil,
119 emojis: [
120 %{
121 shortcode: "2hu",
122 url: "corndog.png",
123 static_url: "corndog.png",
124 visible_in_picker: false
125 }
126 ],
127 pleroma: %{
128 local: true,
129 conversation_id: convo_id,
130 content: %{"text/plain" => HtmlSanitizeEx.strip_tags(note.data["object"]["content"])},
131 spoiler_text: %{"text/plain" => HtmlSanitizeEx.strip_tags(note.data["object"]["summary"])}
132 }
133 }
134
135 assert status == expected
136 end
137
138 test "tells if the message is muted for some reason" do
139 user = insert(:user)
140 other_user = insert(:user)
141
142 {:ok, user} = User.mute(user, other_user)
143
144 {:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"})
145 status = StatusView.render("status.json", %{activity: activity})
146
147 assert status.muted == false
148
149 status = StatusView.render("status.json", %{activity: activity, for: user})
150
151 assert status.muted == true
152 end
153
154 test "a reply" do
155 note = insert(:note_activity)
156 user = insert(:user)
157
158 {:ok, activity} =
159 CommonAPI.post(user, %{"status" => "he", "in_reply_to_status_id" => note.id})
160
161 status = StatusView.render("status.json", %{activity: activity})
162
163 assert status.in_reply_to_id == to_string(note.id)
164
165 [status] = StatusView.render("index.json", %{activities: [activity], as: :activity})
166
167 assert status.in_reply_to_id == to_string(note.id)
168 end
169
170 test "contains mentions" do
171 incoming = File.read!("test/fixtures/incoming_reply_mastodon.xml")
172 # a user with this ap id might be in the cache.
173 recipient = "https://pleroma.soykaf.com/users/lain"
174 user = insert(:user, %{ap_id: recipient})
175
176 {:ok, [activity]} = OStatus.handle_incoming(incoming)
177
178 status = StatusView.render("status.json", %{activity: activity})
179
180 actor = User.get_by_ap_id(activity.actor)
181
182 assert status.mentions ==
183 Enum.map([user, actor], fn u -> AccountView.render("mention.json", %{user: u}) end)
184 end
185
186 test "attachments" do
187 object = %{
188 "type" => "Image",
189 "url" => [
190 %{
191 "mediaType" => "image/png",
192 "href" => "someurl"
193 }
194 ],
195 "uuid" => 6
196 }
197
198 expected = %{
199 id: "1638338801",
200 type: "image",
201 url: "someurl",
202 remote_url: "someurl",
203 preview_url: "someurl",
204 text_url: "someurl",
205 description: nil,
206 pleroma: %{mime_type: "image/png"}
207 }
208
209 assert expected == StatusView.render("attachment.json", %{attachment: object})
210
211 # If theres a "id", use that instead of the generated one
212 object = Map.put(object, "id", 2)
213 assert %{id: "2"} = StatusView.render("attachment.json", %{attachment: object})
214 end
215
216 test "a reblog" do
217 user = insert(:user)
218 activity = insert(:note_activity)
219
220 {:ok, reblog, _} = CommonAPI.repeat(activity.id, user)
221
222 represented = StatusView.render("status.json", %{for: user, activity: reblog})
223
224 assert represented[:id] == to_string(reblog.id)
225 assert represented[:reblog][:id] == to_string(activity.id)
226 assert represented[:emojis] == []
227 end
228
229 test "a peertube video" do
230 user = insert(:user)
231
232 {:ok, object} =
233 ActivityPub.fetch_object_from_id(
234 "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
235 )
236
237 %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
238
239 represented = StatusView.render("status.json", %{for: user, activity: activity})
240
241 assert represented[:id] == to_string(activity.id)
242 assert length(represented[:media_attachments]) == 1
243 end
244
245 describe "build_tags/1" do
246 test "it returns a a dictionary tags" do
247 object_tags = [
248 "fediverse",
249 "mastodon",
250 "nextcloud",
251 %{
252 "href" => "https://kawen.space/users/lain",
253 "name" => "@lain@kawen.space",
254 "type" => "Mention"
255 }
256 ]
257
258 assert StatusView.build_tags(object_tags) == [
259 %{name: "fediverse", url: "/tag/fediverse"},
260 %{name: "mastodon", url: "/tag/mastodon"},
261 %{name: "nextcloud", url: "/tag/nextcloud"}
262 ]
263 end
264 end
265
266 describe "rich media cards" do
267 test "a rich media card without a site name renders correctly" do
268 page_url = "http://example.com"
269
270 card = %{
271 url: page_url,
272 image: page_url <> "/example.jpg",
273 title: "Example website"
274 }
275
276 %{provider_name: "example.com"} =
277 StatusView.render("card.json", %{page_url: page_url, rich_media: card})
278 end
279
280 test "a rich media card without a site name or image renders correctly" do
281 page_url = "http://example.com"
282
283 card = %{
284 url: page_url,
285 title: "Example website"
286 }
287
288 %{provider_name: "example.com"} =
289 StatusView.render("card.json", %{page_url: page_url, rich_media: card})
290 end
291
292 test "a rich media card without an image renders correctly" do
293 page_url = "http://example.com"
294
295 card = %{
296 url: page_url,
297 site_name: "Example site name",
298 title: "Example website"
299 }
300
301 %{provider_name: "Example site name"} =
302 StatusView.render("card.json", %{page_url: page_url, rich_media: card})
303 end
304
305 test "a rich media card with all relevant data renders correctly" do
306 page_url = "http://example.com"
307
308 card = %{
309 url: page_url,
310 site_name: "Example site name",
311 title: "Example website",
312 image: page_url <> "/example.jpg",
313 description: "Example description"
314 }
315
316 %{provider_name: "Example site name"} =
317 StatusView.render("card.json", %{page_url: page_url, rich_media: card})
318 end
319 end
320 end