Reblog content should be ""
[akkoma] / test / pleroma / web / mastodon_api / views / status_view_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 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.Bookmark
10 alias Pleroma.Conversation.Participation
11 alias Pleroma.HTML
12 alias Pleroma.Object
13 alias Pleroma.Repo
14 alias Pleroma.User
15 alias Pleroma.UserRelationship
16 alias Pleroma.Web.CommonAPI
17 alias Pleroma.Web.MastodonAPI.AccountView
18 alias Pleroma.Web.MastodonAPI.StatusView
19
20 import Pleroma.Factory
21 import Tesla.Mock
22 import OpenApiSpex.TestAssertions
23
24 setup do
25 mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
26 :ok
27 end
28
29 test "has an emoji reaction list" do
30 user = insert(:user)
31 other_user = insert(:user)
32 third_user = insert(:user)
33 {:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"})
34
35 {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "☕")
36 {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, ":dinosaur:")
37 {:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵")
38 {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
39 {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, ":dinosaur:")
40
41 activity = Repo.get(Activity, activity.id)
42 status = StatusView.render("show.json", activity: activity)
43
44 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
45
46 assert status[:pleroma][:emoji_reactions] == [
47 %{name: "☕", count: 2, me: false, url: nil, account_ids: [other_user.id, user.id]},
48 %{
49 count: 2,
50 me: false,
51 name: "dinosaur",
52 url: "http://localhost:4001/emoji/dino walking.gif",
53 account_ids: [other_user.id, user.id]
54 },
55 %{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]}
56 ]
57
58 status = StatusView.render("show.json", activity: activity, for: user)
59
60 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
61
62 assert status[:pleroma][:emoji_reactions] == [
63 %{name: "☕", count: 2, me: true, url: nil, account_ids: [other_user.id, user.id]},
64 %{
65 count: 2,
66 me: true,
67 name: "dinosaur",
68 url: "http://localhost:4001/emoji/dino walking.gif",
69 account_ids: [other_user.id, user.id]
70 },
71 %{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]}
72 ]
73 end
74
75 test "works correctly with badly formatted emojis" do
76 user = insert(:user)
77 {:ok, activity} = CommonAPI.post(user, %{status: "yo"})
78
79 activity
80 |> Object.normalize(fetch: false)
81 |> Object.update_data(%{"reactions" => %{"☕" => [user.ap_id], "x" => 1}})
82
83 activity = Activity.get_by_id(activity.id)
84 status = StatusView.render("show.json", activity: activity, for: user)
85
86 assert status[:pleroma][:emoji_reactions] == [
87 %{name: "☕", count: 1, me: true, url: nil, account_ids: [user.id]}
88 ]
89 end
90
91 test "doesn't show reactions from muted and blocked users" do
92 user = insert(:user)
93 other_user = insert(:user)
94 third_user = insert(:user)
95
96 {:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"})
97
98 {:ok, _} = User.mute(user, other_user)
99 {:ok, _} = User.block(other_user, third_user)
100
101 {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
102
103 activity = Repo.get(Activity, activity.id)
104 status = StatusView.render("show.json", activity: activity)
105
106 assert status[:pleroma][:emoji_reactions] == [
107 %{name: "☕", count: 1, me: false, url: nil, account_ids: [other_user.id]}
108 ]
109
110 status = StatusView.render("show.json", activity: activity, for: user)
111
112 assert status[:pleroma][:emoji_reactions] == []
113
114 {:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "☕")
115
116 status = StatusView.render("show.json", activity: activity)
117
118 assert status[:pleroma][:emoji_reactions] == [
119 %{
120 name: "☕",
121 count: 2,
122 me: false,
123 url: nil,
124 account_ids: [third_user.id, other_user.id]
125 }
126 ]
127
128 status = StatusView.render("show.json", activity: activity, for: user)
129
130 assert status[:pleroma][:emoji_reactions] == [
131 %{name: "☕", count: 1, me: false, url: nil, account_ids: [third_user.id]}
132 ]
133
134 status = StatusView.render("show.json", activity: activity, for: other_user)
135
136 assert status[:pleroma][:emoji_reactions] == [
137 %{name: "☕", count: 1, me: true, url: nil, account_ids: [other_user.id]}
138 ]
139 end
140
141 test "loads and returns the direct conversation id when given the `with_direct_conversation_id` option" do
142 user = insert(:user)
143
144 {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
145 [participation] = Participation.for_user(user)
146
147 status =
148 StatusView.render("show.json",
149 activity: activity,
150 with_direct_conversation_id: true,
151 for: user
152 )
153
154 assert status[:pleroma][:direct_conversation_id] == participation.id
155
156 status = StatusView.render("show.json", activity: activity, for: user)
157 assert status[:pleroma][:direct_conversation_id] == nil
158 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
159 end
160
161 test "returns the direct conversation id when given the `direct_conversation_id` option" do
162 user = insert(:user)
163
164 {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
165 [participation] = Participation.for_user(user)
166
167 status =
168 StatusView.render("show.json",
169 activity: activity,
170 direct_conversation_id: participation.id,
171 for: user
172 )
173
174 assert status[:pleroma][:direct_conversation_id] == participation.id
175 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
176 end
177
178 test "returns a temporary ap_id based user for activities missing db users" do
179 user = insert(:user)
180
181 {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
182
183 Repo.delete(user)
184 User.invalidate_cache(user)
185
186 finger_url =
187 "https://localhost/.well-known/webfinger?resource=acct:#{user.nickname}@localhost"
188
189 Tesla.Mock.mock_global(fn
190 %{method: :get, url: "http://localhost/.well-known/host-meta"} ->
191 %Tesla.Env{status: 404, body: ""}
192
193 %{method: :get, url: "https://localhost/.well-known/host-meta"} ->
194 %Tesla.Env{status: 404, body: ""}
195
196 %{
197 method: :get,
198 url: ^finger_url
199 } ->
200 %Tesla.Env{status: 404, body: ""}
201 end)
202
203 %{account: ms_user} = StatusView.render("show.json", activity: activity)
204
205 assert ms_user.acct == "erroruser@example.com"
206 end
207
208 test "tries to get a user by nickname if fetching by ap_id doesn't work" do
209 user = insert(:user)
210
211 {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
212
213 {:ok, user} =
214 user
215 |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"})
216 |> Repo.update()
217
218 User.invalidate_cache(user)
219
220 result = StatusView.render("show.json", activity: activity)
221
222 assert result[:account][:id] == to_string(user.id)
223 assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
224 end
225
226 test "a note with null content" do
227 note = insert(:note_activity)
228 note_object = Object.normalize(note, fetch: false)
229
230 data =
231 note_object.data
232 |> Map.put("content", nil)
233
234 Object.change(note_object, %{data: data})
235 |> Object.update_and_set_cache()
236
237 User.get_cached_by_ap_id(note.data["actor"])
238
239 status = StatusView.render("show.json", %{activity: note})
240
241 assert status.content == ""
242 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
243 end
244
245 test "a note activity" do
246 note = insert(:note_activity)
247 object_data = Object.normalize(note, fetch: false).data
248 user = User.get_cached_by_ap_id(note.data["actor"])
249
250 convo_id = :erlang.crc32(object_data["context"]) |> Bitwise.band(Bitwise.bnot(0x8000_0000))
251
252 status = StatusView.render("show.json", %{activity: note})
253
254 created_at =
255 (object_data["published"] || "")
256 |> String.replace(~r/\.\d+Z/, ".000Z")
257
258 expected = %{
259 id: to_string(note.id),
260 uri: object_data["id"],
261 url: Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, note),
262 account: AccountView.render("show.json", %{user: user, skip_visibility_check: true}),
263 in_reply_to_id: nil,
264 in_reply_to_account_id: nil,
265 card: nil,
266 reblog: nil,
267 content: HTML.filter_tags(object_data["content"]),
268 text: nil,
269 created_at: created_at,
270 edited_at: nil,
271 reblogs_count: 0,
272 replies_count: 0,
273 favourites_count: 0,
274 reblogged: false,
275 bookmarked: false,
276 favourited: false,
277 muted: false,
278 pinned: false,
279 sensitive: false,
280 poll: nil,
281 spoiler_text: HTML.filter_tags(object_data["summary"]),
282 visibility: "public",
283 media_attachments: [],
284 emoji_reactions: [],
285 mentions: [],
286 tags: [
287 %{
288 name: "#{hd(object_data["tag"])}",
289 url: "http://localhost:4001/tag/#{hd(object_data["tag"])}"
290 }
291 ],
292 application: nil,
293 language: nil,
294 emojis: [
295 %{
296 shortcode: "2hu",
297 url: "corndog.png",
298 static_url: "corndog.png",
299 visible_in_picker: false
300 }
301 ],
302 pleroma: %{
303 local: true,
304 conversation_id: convo_id,
305 context: object_data["context"],
306 in_reply_to_account_acct: nil,
307 content: %{"text/plain" => HTML.strip_tags(object_data["content"])},
308 spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])},
309 expires_at: nil,
310 direct_conversation_id: nil,
311 thread_muted: false,
312 emoji_reactions: [],
313 parent_visible: false,
314 pinned_at: nil
315 },
316 akkoma: %{
317 source: HTML.filter_tags(object_data["content"])
318 },
319 quote_id: nil,
320 quote: nil
321 }
322
323 assert status == expected
324 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
325 end
326
327 test "tells if the message is muted for some reason" do
328 user = insert(:user)
329 other_user = insert(:user)
330
331 {:ok, _user_relationships} = User.mute(user, other_user)
332
333 {:ok, activity} = CommonAPI.post(other_user, %{status: "test"})
334
335 relationships_opt = UserRelationship.view_relationships_option(user, [other_user])
336
337 opts = %{activity: activity}
338 status = StatusView.render("show.json", opts)
339 assert status.muted == false
340 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
341
342 status = StatusView.render("show.json", Map.put(opts, :relationships, relationships_opt))
343 assert status.muted == false
344
345 for_opts = %{activity: activity, for: user}
346 status = StatusView.render("show.json", for_opts)
347 assert status.muted == true
348
349 status = StatusView.render("show.json", Map.put(for_opts, :relationships, relationships_opt))
350 assert status.muted == true
351 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
352 end
353
354 test "tells if the message is thread muted" do
355 user = insert(:user)
356 other_user = insert(:user)
357
358 {:ok, _user_relationships} = User.mute(user, other_user)
359
360 {:ok, activity} = CommonAPI.post(other_user, %{status: "test"})
361 status = StatusView.render("show.json", %{activity: activity, for: user})
362
363 assert status.pleroma.thread_muted == false
364
365 {:ok, activity} = CommonAPI.add_mute(user, activity)
366
367 status = StatusView.render("show.json", %{activity: activity, for: user})
368
369 assert status.pleroma.thread_muted == true
370 end
371
372 test "tells if the status is bookmarked" do
373 user = insert(:user)
374
375 {:ok, activity} = CommonAPI.post(user, %{status: "Cute girls doing cute things"})
376 status = StatusView.render("show.json", %{activity: activity})
377
378 assert status.bookmarked == false
379
380 status = StatusView.render("show.json", %{activity: activity, for: user})
381
382 assert status.bookmarked == false
383
384 {:ok, _bookmark} = Bookmark.create(user.id, activity.id)
385
386 activity = Activity.get_by_id_with_object(activity.id)
387
388 status = StatusView.render("show.json", %{activity: activity, for: user})
389
390 assert status.bookmarked == true
391 end
392
393 test "a reply" do
394 note = insert(:note_activity)
395 user = insert(:user)
396
397 {:ok, activity} = CommonAPI.post(user, %{status: "he", in_reply_to_status_id: note.id})
398
399 status = StatusView.render("show.json", %{activity: activity})
400
401 assert status.in_reply_to_id == to_string(note.id)
402
403 [status] = StatusView.render("index.json", %{activities: [activity], as: :activity})
404
405 assert status.in_reply_to_id == to_string(note.id)
406 end
407
408 test "a quote" do
409 note = insert(:note_activity)
410 user = insert(:user)
411
412 {:ok, activity} = CommonAPI.post(user, %{status: "hehe", quote_id: note.id})
413
414 status = StatusView.render("show.json", %{activity: activity})
415
416 assert status.quote_id == to_string(note.id)
417
418 [status] = StatusView.render("index.json", %{activities: [activity], as: :activity})
419
420 assert status.quote_id == to_string(note.id)
421 end
422
423 test "a quote that we can't resolve" do
424 note = insert(:note_activity, quoteUri: "oopsie")
425
426 status = StatusView.render("show.json", %{activity: note})
427
428 assert is_nil(status.quote_id)
429 assert is_nil(status.quote)
430 end
431
432 test "a quote from a user we block" do
433 user = insert(:user)
434 other_user = insert(:user)
435 blocked_user = insert(:user)
436
437 {:ok, _relationship} = User.block(user, blocked_user)
438
439 {:ok, activity} = CommonAPI.post(blocked_user, %{status: ":< i am ANGERY"})
440 {:ok, quote_activity} = CommonAPI.post(other_user, %{status: "hehe", quote_id: activity.id})
441
442 status = StatusView.render("show.json", %{activity: quote_activity, for: user})
443 assert is_nil(status.quote)
444 end
445
446 test "a quote from a user we mute" do
447 user = insert(:user)
448 other_user = insert(:user)
449 blocked_user = insert(:user)
450
451 {:ok, _relationship} = User.mute(user, blocked_user)
452
453 {:ok, activity} = CommonAPI.post(blocked_user, %{status: ":< i am ANGERY"})
454 {:ok, quote_activity} = CommonAPI.post(other_user, %{status: "hehe", quote_id: activity.id})
455
456 status = StatusView.render("show.json", %{activity: quote_activity, for: user})
457 assert is_nil(status.quote)
458 end
459
460 test "contains mentions" do
461 user = insert(:user)
462 mentioned = insert(:user)
463
464 {:ok, activity} = CommonAPI.post(user, %{status: "hi @#{mentioned.nickname}"})
465
466 status = StatusView.render("show.json", %{activity: activity})
467
468 assert status.mentions ==
469 Enum.map([mentioned], fn u -> AccountView.render("mention.json", %{user: u}) end)
470
471 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
472 end
473
474 test "create mentions from the 'to' field" do
475 %User{ap_id: recipient_ap_id} = insert(:user)
476 cc = insert_pair(:user) |> Enum.map(& &1.ap_id)
477
478 object =
479 insert(:note, %{
480 data: %{
481 "to" => [recipient_ap_id],
482 "cc" => cc
483 }
484 })
485
486 activity =
487 insert(:note_activity, %{
488 note: object,
489 recipients: [recipient_ap_id | cc]
490 })
491
492 assert length(activity.recipients) == 3
493
494 %{mentions: [mention] = mentions} = StatusView.render("show.json", %{activity: activity})
495
496 assert length(mentions) == 1
497 assert mention.url == recipient_ap_id
498 end
499
500 test "create mentions from the 'tag' field" do
501 recipient = insert(:user)
502 cc = insert_pair(:user) |> Enum.map(& &1.ap_id)
503
504 object =
505 insert(:note, %{
506 data: %{
507 "cc" => cc,
508 "tag" => [
509 %{
510 "href" => recipient.ap_id,
511 "name" => recipient.nickname,
512 "type" => "Mention"
513 },
514 %{
515 "href" => "https://example.com/search?tag=test",
516 "name" => "#test",
517 "type" => "Hashtag"
518 }
519 ]
520 }
521 })
522
523 activity =
524 insert(:note_activity, %{
525 note: object,
526 recipients: [recipient.ap_id | cc]
527 })
528
529 assert length(activity.recipients) == 3
530
531 %{mentions: [mention] = mentions} = StatusView.render("show.json", %{activity: activity})
532
533 assert length(mentions) == 1
534 assert mention.url == recipient.ap_id
535 end
536
537 test "attachments" do
538 object = %{
539 "type" => "Image",
540 "url" => [
541 %{
542 "mediaType" => "image/png",
543 "href" => "someurl",
544 "width" => 200,
545 "height" => 100
546 }
547 ],
548 "blurhash" => "UJJ8X[xYW,%Jtq%NNFbXB5j]IVM|9GV=WHRn",
549 "uuid" => 6
550 }
551
552 expected = %{
553 id: "1638338801",
554 type: "image",
555 url: "someurl",
556 remote_url: "someurl",
557 preview_url: "someurl",
558 text_url: "someurl",
559 description: nil,
560 pleroma: %{mime_type: "image/png"},
561 meta: %{original: %{width: 200, height: 100, aspect: 2}},
562 blurhash: "UJJ8X[xYW,%Jtq%NNFbXB5j]IVM|9GV=WHRn"
563 }
564
565 api_spec = Pleroma.Web.ApiSpec.spec()
566
567 assert expected == StatusView.render("attachment.json", %{attachment: object})
568 assert_schema(expected, "Attachment", api_spec)
569
570 # If theres a "id", use that instead of the generated one
571 object = Map.put(object, "id", 2)
572 result = StatusView.render("attachment.json", %{attachment: object})
573
574 assert %{id: "2"} = result
575 assert_schema(result, "Attachment", api_spec)
576 end
577
578 test "put the url advertised in the Activity in to the url attribute" do
579 id = "https://wedistribute.org/wp-json/pterotype/v1/object/85810"
580 [activity] = Activity.search(nil, id)
581
582 status = StatusView.render("show.json", %{activity: activity})
583
584 assert status.uri == id
585 assert status.url == "https://wedistribute.org/2019/07/mastodon-drops-ostatus/"
586 end
587
588 test "a reblog" do
589 user = insert(:user)
590 activity = insert(:note_activity)
591
592 {:ok, reblog} = CommonAPI.repeat(activity.id, user)
593
594 represented = StatusView.render("show.json", %{for: user, activity: reblog})
595
596 assert represented[:id] == to_string(reblog.id)
597 assert represented[:content] == ""
598 assert represented[:reblog][:id] == to_string(activity.id)
599 assert represented[:emojis] == []
600 assert_schema(represented, "Status", Pleroma.Web.ApiSpec.spec())
601 end
602
603 test "a peertube video" do
604 user = insert(:user)
605
606 {:ok, object} =
607 Pleroma.Object.Fetcher.fetch_object_from_id(
608 "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
609 )
610
611 %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
612
613 represented = StatusView.render("show.json", %{for: user, activity: activity})
614
615 assert represented[:id] == to_string(activity.id)
616 assert length(represented[:media_attachments]) == 1
617 assert_schema(represented, "Status", Pleroma.Web.ApiSpec.spec())
618 end
619
620 test "funkwhale audio" do
621 user = insert(:user)
622
623 {:ok, object} =
624 Pleroma.Object.Fetcher.fetch_object_from_id(
625 "https://channels.tests.funkwhale.audio/federation/music/uploads/42342395-0208-4fee-a38d-259a6dae0871"
626 )
627
628 %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
629
630 represented = StatusView.render("show.json", %{for: user, activity: activity})
631
632 assert represented[:id] == to_string(activity.id)
633 assert length(represented[:media_attachments]) == 1
634 end
635
636 test "a Mobilizon event" do
637 user = insert(:user)
638
639 {:ok, object} =
640 Pleroma.Object.Fetcher.fetch_object_from_id(
641 "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"
642 )
643
644 %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
645
646 represented = StatusView.render("show.json", %{for: user, activity: activity})
647
648 assert represented[:id] == to_string(activity.id)
649
650 assert represented[:url] ==
651 "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"
652
653 assert represented[:content] ==
654 "<p><a href=\"https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39\">Mobilizon Launching Party</a></p><p>Mobilizon is now federated! 🎉</p><p></p><p>You can view this event from other instances if they are subscribed to mobilizon.org, and soon directly from Mastodon and Pleroma. It is possible that you may see some comments from other instances, including Mastodon ones, just below.</p><p></p><p>With a Mobilizon account on an instance, you may <strong>participate</strong> at events from other instances and <strong>add comments</strong> on events.</p><p></p><p>Of course, it&#39;s still <u>a work in progress</u>: if reports made from an instance on events and comments can be federated, you can&#39;t block people right now, and moderators actions are rather limited, but this <strong>will definitely get fixed over time</strong> until first stable version next year.</p><p></p><p>Anyway, if you want to come up with some feedback, head over to our forum or - if you feel you have technical skills and are familiar with it - on our Gitlab repository.</p><p></p><p>Also, to people that want to set Mobilizon themselves even though we really don&#39;t advise to do that for now, we have a little documentation but it&#39;s quite the early days and you&#39;ll probably need some help. No worries, you can chat with us on our Forum or though our Matrix channel.</p><p></p><p>Check our website for more informations and follow us on Twitter or Mastodon.</p>"
655 end
656
657 describe "build_tags/1" do
658 test "it returns a a dictionary tags" do
659 object_tags = [
660 "fediverse",
661 "mastodon",
662 "nextcloud",
663 %{
664 "href" => "https://kawen.space/users/lain",
665 "name" => "@lain@kawen.space",
666 "type" => "Mention"
667 }
668 ]
669
670 assert StatusView.build_tags(object_tags) == [
671 %{name: "fediverse", url: "http://localhost:4001/tag/fediverse"},
672 %{name: "mastodon", url: "http://localhost:4001/tag/mastodon"},
673 %{name: "nextcloud", url: "http://localhost:4001/tag/nextcloud"}
674 ]
675 end
676 end
677
678 describe "rich media cards" do
679 test "a rich media card without a site name renders correctly" do
680 page_url = "http://example.com"
681
682 card = %{
683 url: page_url,
684 image: page_url <> "/example.jpg",
685 title: "Example website"
686 }
687
688 %{provider_name: "example.com"} =
689 StatusView.render("card.json", %{page_url: page_url, rich_media: card})
690 end
691
692 test "a rich media card without a site name or image renders correctly" do
693 page_url = "http://example.com"
694
695 card = %{
696 url: page_url,
697 title: "Example website"
698 }
699
700 %{provider_name: "example.com"} =
701 StatusView.render("card.json", %{page_url: page_url, rich_media: card})
702 end
703
704 test "a rich media card without an image renders correctly" do
705 page_url = "http://example.com"
706
707 card = %{
708 url: page_url,
709 site_name: "Example site name",
710 title: "Example website"
711 }
712
713 %{provider_name: "example.com"} =
714 StatusView.render("card.json", %{page_url: page_url, rich_media: card})
715 end
716
717 test "a rich media card with all relevant data renders correctly" do
718 page_url = "http://example.com"
719
720 card = %{
721 url: page_url,
722 site_name: "Example site name",
723 title: "Example website",
724 image: page_url <> "/example.jpg",
725 description: "Example description"
726 }
727
728 %{provider_name: "example.com"} =
729 StatusView.render("card.json", %{page_url: page_url, rich_media: card})
730 end
731 end
732
733 test "does not embed a relationship in the account" do
734 user = insert(:user)
735 other_user = insert(:user)
736
737 {:ok, activity} =
738 CommonAPI.post(user, %{
739 status: "drink more water"
740 })
741
742 result = StatusView.render("show.json", %{activity: activity, for: other_user})
743
744 assert result[:account][:pleroma][:relationship] == %{}
745 assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
746 end
747
748 test "does not embed a relationship in the account in reposts" do
749 user = insert(:user)
750 other_user = insert(:user)
751
752 {:ok, activity} =
753 CommonAPI.post(user, %{
754 status: "˙˙ɐʎns"
755 })
756
757 {:ok, activity} = CommonAPI.repeat(activity.id, other_user)
758
759 result = StatusView.render("show.json", %{activity: activity, for: user})
760
761 assert result[:account][:pleroma][:relationship] == %{}
762 assert result[:reblog][:account][:pleroma][:relationship] == %{}
763 assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
764 end
765
766 test "visibility/list" do
767 user = insert(:user)
768
769 {:ok, list} = Pleroma.List.create("foo", user)
770
771 {:ok, activity} = CommonAPI.post(user, %{status: "foobar", visibility: "list:#{list.id}"})
772
773 status = StatusView.render("show.json", activity: activity)
774
775 assert status.visibility == "list"
776 end
777
778 test "has a field for parent visibility" do
779 user = insert(:user)
780 poster = insert(:user)
781
782 {:ok, invisible} = CommonAPI.post(poster, %{status: "hey", visibility: "private"})
783
784 {:ok, visible} =
785 CommonAPI.post(poster, %{status: "hey", visibility: "private", in_reply_to_id: invisible.id})
786
787 status = StatusView.render("show.json", activity: visible, for: user)
788 refute status.pleroma.parent_visible
789
790 status = StatusView.render("show.json", activity: visible, for: poster)
791 assert status.pleroma.parent_visible
792 end
793
794 test "it shows edited_at" do
795 poster = insert(:user)
796
797 {:ok, post} = CommonAPI.post(poster, %{status: "hey"})
798
799 status = StatusView.render("show.json", activity: post)
800 refute status.edited_at
801
802 {:ok, _} = CommonAPI.update(poster, post, %{status: "mew mew"})
803 edited = Pleroma.Activity.normalize(post)
804
805 status = StatusView.render("show.json", activity: edited)
806 assert status.edited_at
807 end
808
809 test "with a source object" do
810 note =
811 insert(:note,
812 data: %{"source" => %{"content" => "object source", "mediaType" => "text/markdown"}}
813 )
814
815 activity = insert(:note_activity, note: note)
816
817 status = StatusView.render("show.json", activity: activity, with_source: true)
818 assert status.text == "object source"
819 end
820
821 describe "source.json" do
822 test "with a source object, renders both source and content type" do
823 note =
824 insert(:note,
825 data: %{"source" => %{"content" => "object source", "mediaType" => "text/markdown"}}
826 )
827
828 activity = insert(:note_activity, note: note)
829
830 status = StatusView.render("source.json", activity: activity)
831 assert status.text == "object source"
832 assert status.content_type == "text/markdown"
833 end
834
835 test "with a source string, renders source and put text/plain as the content type" do
836 note = insert(:note, data: %{"source" => "string source"})
837 activity = insert(:note_activity, note: note)
838
839 status = StatusView.render("source.json", activity: activity)
840 assert status.text == "string source"
841 assert status.content_type == "text/plain"
842 end
843 end
844 end