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