1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
10 alias Pleroma.Conversation.Participation
14 alias Pleroma.UnstubbedConfigMock, as: ConfigMock
16 alias Pleroma.UserRelationship
17 alias Pleroma.Web.CommonAPI
18 alias Pleroma.Web.MastodonAPI.AccountView
19 alias Pleroma.Web.MastodonAPI.StatusView
20 alias Pleroma.Web.RichMedia.Card
25 import OpenApiSpex.TestAssertions
26 import Pleroma.Factory
30 mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
34 test "has an emoji reaction list" do
36 other_user = insert(:user)
37 third_user = insert(:user)
38 {:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"})
40 {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "☕")
41 {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, ":dinosaur:")
42 {:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵")
43 {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
44 {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, ":dinosaur:")
46 activity = Repo.get(Activity, activity.id)
47 status = StatusView.render("show.json", activity: activity)
49 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
51 assert status[:pleroma][:emoji_reactions] == [
52 %{name: "☕", count: 2, me: false, url: nil, account_ids: [other_user.id, user.id]},
57 url: "http://localhost:4001/emoji/dino walking.gif",
58 account_ids: [other_user.id, user.id]
60 %{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]}
63 status = StatusView.render("show.json", activity: activity, for: user)
65 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
67 assert status[:pleroma][:emoji_reactions] == [
68 %{name: "☕", count: 2, me: true, url: nil, account_ids: [other_user.id, user.id]},
73 url: "http://localhost:4001/emoji/dino walking.gif",
74 account_ids: [other_user.id, user.id]
76 %{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]}
80 test "works with legacy-formatted reactions" do
82 other_user = insert(:user)
88 "reactions" => [["😿", [other_user.ap_id]]]
92 activity = insert(:note_activity, user: user, note: note)
94 status = StatusView.render("show.json", activity: activity, for: user)
96 assert status[:pleroma][:emoji_reactions] == [
97 %{name: "😿", count: 1, me: false, url: nil, account_ids: [other_user.id]}
101 test "works correctly with badly formatted emojis" do
103 {:ok, activity} = CommonAPI.post(user, %{status: "yo"})
106 |> Object.normalize(fetch: false)
107 |> Object.update_data(%{"reactions" => %{"☕" => [user.ap_id], "x" => 1}})
109 activity = Activity.get_by_id(activity.id)
110 status = StatusView.render("show.json", activity: activity, for: user)
112 assert status[:pleroma][:emoji_reactions] == [
113 %{name: "☕", count: 1, me: true, url: nil, account_ids: [user.id]}
117 test "doesn't show reactions from muted and blocked users" do
119 other_user = insert(:user)
120 third_user = insert(:user)
122 {:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"})
124 {:ok, _} = User.mute(user, other_user)
125 {:ok, _} = User.block(other_user, third_user)
127 {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
129 activity = Repo.get(Activity, activity.id)
130 status = StatusView.render("show.json", activity: activity)
132 assert status[:pleroma][:emoji_reactions] == [
133 %{name: "☕", count: 1, me: false, url: nil, account_ids: [other_user.id]}
136 status = StatusView.render("show.json", activity: activity, for: user)
138 assert status[:pleroma][:emoji_reactions] == []
140 {:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "☕")
142 status = StatusView.render("show.json", activity: activity)
144 assert status[:pleroma][:emoji_reactions] == [
150 account_ids: [third_user.id, other_user.id]
154 status = StatusView.render("show.json", activity: activity, for: user)
156 assert status[:pleroma][:emoji_reactions] == [
157 %{name: "☕", count: 1, me: false, url: nil, account_ids: [third_user.id]}
160 status = StatusView.render("show.json", activity: activity, for: other_user)
162 assert status[:pleroma][:emoji_reactions] == [
163 %{name: "☕", count: 1, me: true, url: nil, account_ids: [other_user.id]}
167 test "loads and returns the direct conversation id when given the `with_direct_conversation_id` option" do
170 {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
171 [participation] = Participation.for_user(user)
174 StatusView.render("show.json",
176 with_direct_conversation_id: true,
180 assert status[:pleroma][:direct_conversation_id] == participation.id
182 status = StatusView.render("show.json", activity: activity, for: user)
183 assert status[:pleroma][:direct_conversation_id] == nil
184 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
187 test "returns the direct conversation id when given the `direct_conversation_id` option" do
190 {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
191 [participation] = Participation.for_user(user)
194 StatusView.render("show.json",
196 direct_conversation_id: participation.id,
200 assert status[:pleroma][:direct_conversation_id] == participation.id
201 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
204 @tag capture_log: true
205 test "returns a temporary ap_id based user for activities missing db users" do
208 {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
211 User.invalidate_cache(user)
214 "https://localhost/.well-known/webfinger?resource=acct:#{user.nickname}@localhost"
216 Tesla.Mock.mock_global(fn
217 %{method: :get, url: "http://localhost/.well-known/host-meta"} ->
218 %Tesla.Env{status: 404, body: ""}
220 %{method: :get, url: "https://localhost/.well-known/host-meta"} ->
221 %Tesla.Env{status: 404, body: ""}
227 %Tesla.Env{status: 404, body: ""}
230 %{account: ms_user} = StatusView.render("show.json", activity: activity)
232 assert ms_user.acct == "erroruser@example.com"
235 test "tries to get a user by nickname if fetching by ap_id doesn't work" do
238 {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
242 |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"})
245 User.invalidate_cache(user)
247 result = StatusView.render("show.json", activity: activity)
249 assert result[:account][:id] == to_string(user.id)
250 assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
253 test "a note with null content" do
254 note = insert(:note_activity)
255 note_object = Object.normalize(note, fetch: false)
259 |> Map.put("content", nil)
261 Object.change(note_object, %{data: data})
262 |> Object.update_and_set_cache()
264 User.get_cached_by_ap_id(note.data["actor"])
266 status = StatusView.render("show.json", %{activity: note})
268 assert status.content == ""
269 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
272 test "a note activity" do
273 note = insert(:note_activity)
274 object_data = Object.normalize(note, fetch: false).data
275 user = User.get_cached_by_ap_id(note.data["actor"])
277 convo_id = :erlang.crc32(object_data["context"]) |> Bitwise.band(Bitwise.bnot(0x8000_0000))
279 status = StatusView.render("show.json", %{activity: note})
282 (object_data["published"] || "")
283 |> String.replace(~r/\.\d+Z/, ".000Z")
286 id: to_string(note.id),
287 uri: object_data["id"],
288 url: Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, note),
289 account: AccountView.render("show.json", %{user: user, skip_visibility_check: true}),
291 in_reply_to_account_id: nil,
294 content: HTML.filter_tags(object_data["content"]),
296 created_at: created_at,
308 spoiler_text: HTML.filter_tags(object_data["summary"]),
309 visibility: "public",
310 media_attachments: [],
314 name: "#{hd(object_data["tag"])}",
315 url: "http://localhost:4001/tag/#{hd(object_data["tag"])}"
324 static_url: "corndog.png",
325 visible_in_picker: false
330 conversation_id: convo_id,
331 context: object_data["context"],
332 in_reply_to_account_acct: nil,
336 quote_visible: false,
337 content: %{"text/plain" => HTML.strip_tags(object_data["content"])},
338 spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])},
340 direct_conversation_id: nil,
343 parent_visible: false,
350 assert status == expected
351 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
354 test "tells if the message is muted for some reason" do
356 other_user = insert(:user)
358 {:ok, _user_relationships} = User.mute(user, other_user)
360 {:ok, activity} = CommonAPI.post(other_user, %{status: "test"})
362 relationships_opt = UserRelationship.view_relationships_option(user, [other_user])
364 opts = %{activity: activity}
365 status = StatusView.render("show.json", opts)
366 assert status.muted == false
367 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
369 status = StatusView.render("show.json", Map.put(opts, :relationships, relationships_opt))
370 assert status.muted == false
372 for_opts = %{activity: activity, for: user}
373 status = StatusView.render("show.json", for_opts)
374 assert status.muted == true
376 status = StatusView.render("show.json", Map.put(for_opts, :relationships, relationships_opt))
377 assert status.muted == true
378 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
381 test "tells if the message is thread muted" do
383 other_user = insert(:user)
385 {:ok, _user_relationships} = User.mute(user, other_user)
387 {:ok, activity} = CommonAPI.post(other_user, %{status: "test"})
388 status = StatusView.render("show.json", %{activity: activity, for: user})
390 assert status.pleroma.thread_muted == false
392 {:ok, activity} = CommonAPI.add_mute(user, activity)
394 status = StatusView.render("show.json", %{activity: activity, for: user})
396 assert status.pleroma.thread_muted == true
399 test "tells if the status is bookmarked" do
402 {:ok, activity} = CommonAPI.post(user, %{status: "Cute girls doing cute things"})
403 status = StatusView.render("show.json", %{activity: activity})
405 assert status.bookmarked == false
407 status = StatusView.render("show.json", %{activity: activity, for: user})
409 assert status.bookmarked == false
411 {:ok, _bookmark} = Bookmark.create(user.id, activity.id)
413 activity = Activity.get_by_id_with_object(activity.id)
415 status = StatusView.render("show.json", %{activity: activity, for: user})
417 assert status.bookmarked == true
421 note = insert(:note_activity)
424 {:ok, activity} = CommonAPI.post(user, %{status: "he", in_reply_to_status_id: note.id})
426 status = StatusView.render("show.json", %{activity: activity})
428 assert status.in_reply_to_id == to_string(note.id)
430 [status] = StatusView.render("index.json", %{activities: [activity], as: :activity})
432 assert status.in_reply_to_id == to_string(note.id)
435 test "a quote post" do
436 post = insert(:note_activity)
439 {:ok, quote_post} = CommonAPI.post(user, %{status: "he", quote_id: post.id})
440 {:ok, quoted_quote_post} = CommonAPI.post(user, %{status: "yo", quote_id: quote_post.id})
442 status = StatusView.render("show.json", %{activity: quoted_quote_post})
444 assert status.pleroma.quote.id == to_string(quote_post.id)
445 assert status.pleroma.quote_id == to_string(quote_post.id)
446 assert status.pleroma.quote_url == Object.normalize(quote_post).data["id"]
447 assert status.pleroma.quote_visible
449 # Quotes don't go more than one level deep
450 refute status.pleroma.quote.pleroma.quote
451 assert status.pleroma.quote.pleroma.quote_id == to_string(post.id)
452 assert status.pleroma.quote.pleroma.quote_url == Object.normalize(post).data["id"]
453 assert status.pleroma.quote.pleroma.quote_visible
456 [status] = StatusView.render("index.json", %{activities: [quoted_quote_post], as: :activity})
458 assert status.pleroma.quote.id == to_string(quote_post.id)
461 test "quoted private post" do
464 # Insert a private post
465 private = insert(:followers_only_note_activity, user: user)
466 private_object = Object.normalize(private)
468 # Create a public post quoting the private post
470 insert(:note_activity, note: insert(:note, data: %{"quoteUrl" => private_object.data["id"]}))
472 status = StatusView.render("show.json", %{activity: quote_private})
474 # The quote isn't rendered
475 refute status.pleroma.quote
476 assert status.pleroma.quote_url == private_object.data["id"]
477 refute status.pleroma.quote_visible
479 # After following the user, the quote is rendered
480 follower = insert(:user)
481 CommonAPI.follow(follower, user)
483 status = StatusView.render("show.json", %{activity: quote_private, for: follower})
484 assert status.pleroma.quote.id == to_string(private.id)
485 assert status.pleroma.quote_visible
488 test "quoted direct message" do
489 # Insert a direct message
490 direct = insert(:direct_note_activity)
491 direct_object = Object.normalize(direct)
493 # Create a public post quoting the direct message
495 insert(:note_activity, note: insert(:note, data: %{"quoteUrl" => direct_object.data["id"]}))
497 status = StatusView.render("show.json", %{activity: quote_direct})
499 # The quote isn't rendered
500 refute status.pleroma.quote
501 assert status.pleroma.quote_url == direct_object.data["id"]
502 refute status.pleroma.quote_visible
505 test "repost of quote post" do
506 post = insert(:note_activity)
509 {:ok, quote_post} = CommonAPI.post(user, %{status: "he", quote_id: post.id})
510 {:ok, repost} = CommonAPI.repeat(quote_post.id, user)
512 [status] = StatusView.render("index.json", %{activities: [repost], as: :activity})
514 assert status.reblog.pleroma.quote.id == to_string(post.id)
517 test "contains mentions" do
519 mentioned = insert(:user)
521 {:ok, activity} = CommonAPI.post(user, %{status: "hi @#{mentioned.nickname}"})
523 status = StatusView.render("show.json", %{activity: activity})
525 assert status.mentions ==
526 Enum.map([mentioned], fn u -> AccountView.render("mention.json", %{user: u}) end)
528 assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
531 test "create mentions from the 'to' field" do
532 %User{ap_id: recipient_ap_id} = insert(:user)
533 cc = insert_pair(:user) |> Enum.map(& &1.ap_id)
538 "to" => [recipient_ap_id],
544 insert(:note_activity, %{
546 recipients: [recipient_ap_id | cc]
549 assert length(activity.recipients) == 3
551 %{mentions: [mention] = mentions} = StatusView.render("show.json", %{activity: activity})
553 assert length(mentions) == 1
554 assert mention.url == recipient_ap_id
557 test "create mentions from the 'tag' field" do
558 recipient = insert(:user)
559 cc = insert_pair(:user) |> Enum.map(& &1.ap_id)
567 "href" => recipient.ap_id,
568 "name" => recipient.nickname,
572 "href" => "https://example.com/search?tag=test",
581 insert(:note_activity, %{
583 recipients: [recipient.ap_id | cc]
586 assert length(activity.recipients) == 3
588 %{mentions: [mention] = mentions} = StatusView.render("show.json", %{activity: activity})
590 assert length(mentions) == 1
591 assert mention.url == recipient.ap_id
594 test "attachments" do
599 "mediaType" => "image/png",
605 "blurhash" => "UJJ8X[xYW,%Jtq%NNFbXB5j]IVM|9GV=WHRn",
613 remote_url: "someurl",
614 preview_url: "someurl",
617 pleroma: %{mime_type: "image/png"},
618 meta: %{original: %{width: 200, height: 100, aspect: 2}},
619 blurhash: "UJJ8X[xYW,%Jtq%NNFbXB5j]IVM|9GV=WHRn"
622 api_spec = Pleroma.Web.ApiSpec.spec()
624 assert expected == StatusView.render("attachment.json", %{attachment: object})
625 assert_schema(expected, "Attachment", api_spec)
627 # If theres a "id", use that instead of the generated one
628 object = Map.put(object, "id", 2)
629 result = StatusView.render("attachment.json", %{attachment: object})
631 assert %{id: "2"} = result
632 assert_schema(result, "Attachment", api_spec)
635 test "put the url advertised in the Activity in to the url attribute" do
636 id = "https://wedistribute.org/wp-json/pterotype/v1/object/85810"
637 [activity] = Activity.search(nil, id)
639 status = StatusView.render("show.json", %{activity: activity})
641 assert status.uri == id
642 assert status.url == "https://wedistribute.org/2019/07/mastodon-drops-ostatus/"
647 activity = insert(:note_activity)
649 {:ok, reblog} = CommonAPI.repeat(activity.id, user)
651 represented = StatusView.render("show.json", %{for: user, activity: reblog})
653 assert represented[:id] == to_string(reblog.id)
654 assert represented[:reblog][:id] == to_string(activity.id)
655 assert represented[:emojis] == []
656 assert_schema(represented, "Status", Pleroma.Web.ApiSpec.spec())
659 test "a peertube video" do
663 Pleroma.Object.Fetcher.fetch_object_from_id(
664 "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
667 %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
669 represented = StatusView.render("show.json", %{for: user, activity: activity})
671 assert represented[:id] == to_string(activity.id)
672 assert length(represented[:media_attachments]) == 1
673 assert_schema(represented, "Status", Pleroma.Web.ApiSpec.spec())
676 test "funkwhale audio" do
680 Pleroma.Object.Fetcher.fetch_object_from_id(
681 "https://channels.tests.funkwhale.audio/federation/music/uploads/42342395-0208-4fee-a38d-259a6dae0871"
684 %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
686 represented = StatusView.render("show.json", %{for: user, activity: activity})
688 assert represented[:id] == to_string(activity.id)
689 assert length(represented[:media_attachments]) == 1
692 test "a Mobilizon event" do
696 Pleroma.Object.Fetcher.fetch_object_from_id(
697 "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"
700 %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
702 represented = StatusView.render("show.json", %{for: user, activity: activity})
704 assert represented[:id] == to_string(activity.id)
706 assert represented[:url] ==
707 "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"
709 assert represented[:content] ==
710 "<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's still <u>a work in progress</u>: if reports made from an instance on events and comments can be federated, you can'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't advise to do that for now, we have a little documentation but it's quite the early days and you'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>"
713 describe "build_tags/1" do
714 test "it returns a a dictionary tags" do
720 "href" => "https://kawen.space/users/lain",
721 "name" => "@lain@kawen.space",
726 assert StatusView.build_tags(object_tags) == [
727 %{name: "fediverse", url: "http://localhost:4001/tag/fediverse"},
728 %{name: "mastodon", url: "http://localhost:4001/tag/mastodon"},
729 %{name: "nextcloud", url: "http://localhost:4001/tag/nextcloud"}
734 describe "rich media cards" do
735 test "a rich media card without a site name renders correctly" do
736 page_url = "https://example.com"
739 Card.create(page_url, %{image: page_url <> "/example.jpg", title: "Example website"})
741 assert match?(%{provider_name: "example.com"}, StatusView.render("card.json", card))
744 test "a rich media card without a site name or image renders correctly" do
745 page_url = "https://example.com"
749 "title" => "Example website"
752 {:ok, card} = Card.create(page_url, fields)
754 assert match?(%{provider_name: "example.com"}, StatusView.render("card.json", card))
757 test "a rich media card without an image renders correctly" do
758 page_url = "https://example.com"
762 "site_name" => "Example site name",
763 "title" => "Example website"
766 {:ok, card} = Card.create(page_url, fields)
768 assert match?(%{provider_name: "example.com"}, StatusView.render("card.json", card))
771 test "a rich media card without descriptions returns the fields with empty strings" do
772 page_url = "https://example.com"
776 "site_name" => "Example site name",
777 "title" => "Example website"
780 {:ok, card} = Card.create(page_url, fields)
783 %{description: "", image_description: ""},
784 StatusView.render("card.json", card)
788 test "a rich media card with all relevant data renders correctly" do
789 page_url = "https://example.com"
793 "site_name" => "Example site name",
794 "title" => "Example website",
795 "image" => page_url <> "/example.jpg",
796 "description" => "Example description"
799 {:ok, card} = Card.create(page_url, fields)
801 assert match?(%{provider_name: "example.com"}, StatusView.render("card.json", card))
804 test "a rich media card has all media proxied" do
805 clear_config([:media_proxy, :enabled], true)
806 clear_config([:media_preview_proxy, :enabled])
809 |> stub_with(Pleroma.Test.StaticConfig)
811 page_url = "https://example.com"
815 "site_name" => "Example site name",
816 "title" => "Example website",
817 "image" => page_url <> "/example.jpg",
818 "audio" => page_url <> "/example.ogg",
819 "video" => page_url <> "/example.mp4",
820 "description" => "Example description"
823 {:ok, card} = Card.create(page_url, fields)
826 provider_name: "example.com",
828 pleroma: %{opengraph: og}
829 } = StatusView.render("card.json", card)
831 assert String.match?(image, ~r/\/proxy\//)
832 assert String.match?(og["image"], ~r/\/proxy\//)
833 assert String.match?(og["audio"], ~r/\/proxy\//)
834 assert String.match?(og["video"], ~r/\/proxy\//)
838 test "does not embed a relationship in the account" do
840 other_user = insert(:user)
843 CommonAPI.post(user, %{
844 status: "drink more water"
847 result = StatusView.render("show.json", %{activity: activity, for: other_user})
849 assert result[:account][:pleroma][:relationship] == %{}
850 assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
853 test "does not embed a relationship in the account in reposts" do
855 other_user = insert(:user)
858 CommonAPI.post(user, %{
862 {:ok, activity} = CommonAPI.repeat(activity.id, other_user)
864 result = StatusView.render("show.json", %{activity: activity, for: user})
866 assert result[:account][:pleroma][:relationship] == %{}
867 assert result[:reblog][:account][:pleroma][:relationship] == %{}
868 assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
871 test "visibility/list" do
874 {:ok, list} = Pleroma.List.create("foo", user)
876 {:ok, activity} = CommonAPI.post(user, %{status: "foobar", visibility: "list:#{list.id}"})
878 status = StatusView.render("show.json", activity: activity)
880 assert status.visibility == "list"
883 test "has a field for parent visibility" do
885 poster = insert(:user)
887 {:ok, invisible} = CommonAPI.post(poster, %{status: "hey", visibility: "private"})
890 CommonAPI.post(poster, %{status: "hey", visibility: "private", in_reply_to_id: invisible.id})
892 status = StatusView.render("show.json", activity: visible, for: user)
893 refute status.pleroma.parent_visible
895 status = StatusView.render("show.json", activity: visible, for: poster)
896 assert status.pleroma.parent_visible
899 test "it shows edited_at" do
900 poster = insert(:user)
902 {:ok, post} = CommonAPI.post(poster, %{status: "hey"})
904 status = StatusView.render("show.json", activity: post)
905 refute status.edited_at
907 {:ok, _} = CommonAPI.update(poster, post, %{status: "mew mew"})
908 edited = Pleroma.Activity.normalize(post)
910 status = StatusView.render("show.json", activity: edited)
911 assert status.edited_at
914 test "with a source object" do
917 data: %{"source" => %{"content" => "object source", "mediaType" => "text/markdown"}}
920 activity = insert(:note_activity, note: note)
922 status = StatusView.render("show.json", activity: activity, with_source: true)
923 assert status.text == "object source"
926 describe "source.json" do
927 test "with a source object, renders both source and content type" do
930 data: %{"source" => %{"content" => "object source", "mediaType" => "text/markdown"}}
933 activity = insert(:note_activity, note: note)
935 status = StatusView.render("source.json", activity: activity)
936 assert status.text == "object source"
937 assert status.content_type == "text/markdown"
940 test "with a source string, renders source and put text/plain as the content type" do
941 note = insert(:note, data: %{"source" => "string source"})
942 activity = insert(:note_activity, note: note)
944 status = StatusView.render("source.json", activity: activity)
945 assert status.text == "string source"
946 assert status.content_type == "text/plain"