811a2dd7b262dc85ac5521683c3ddcb7fbe213df
[akkoma] / test / web / mastodon_api / mastodon_api_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
6 use Pleroma.Web.ConnCase
7
8 alias Ecto.Changeset
9 alias Pleroma.Activity
10 alias Pleroma.Notification
11 alias Pleroma.Object
12 alias Pleroma.Repo
13 alias Pleroma.User
14 alias Pleroma.Web.ActivityPub.ActivityPub
15 alias Pleroma.Web.CommonAPI
16 alias Pleroma.Web.MastodonAPI.FilterView
17 alias Pleroma.Web.OAuth.App
18 alias Pleroma.Web.OStatus
19 alias Pleroma.Web.Push
20 alias Pleroma.Web.TwitterAPI.TwitterAPI
21 import Pleroma.Factory
22 import ExUnit.CaptureLog
23 import Tesla.Mock
24
25 setup do
26 mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
27 :ok
28 end
29
30 test "the home timeline", %{conn: conn} do
31 user = insert(:user)
32 following = insert(:user)
33
34 {:ok, _activity} = TwitterAPI.create_status(following, %{"status" => "test"})
35
36 conn =
37 conn
38 |> assign(:user, user)
39 |> get("/api/v1/timelines/home")
40
41 assert Enum.empty?(json_response(conn, 200))
42
43 {:ok, user} = User.follow(user, following)
44
45 conn =
46 build_conn()
47 |> assign(:user, user)
48 |> get("/api/v1/timelines/home")
49
50 assert [%{"content" => "test"}] = json_response(conn, 200)
51 end
52
53 test "the public timeline", %{conn: conn} do
54 following = insert(:user)
55
56 capture_log(fn ->
57 {:ok, _activity} = TwitterAPI.create_status(following, %{"status" => "test"})
58
59 {:ok, [_activity]} =
60 OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873")
61
62 conn =
63 conn
64 |> get("/api/v1/timelines/public", %{"local" => "False"})
65
66 assert length(json_response(conn, 200)) == 2
67
68 conn =
69 build_conn()
70 |> get("/api/v1/timelines/public", %{"local" => "True"})
71
72 assert [%{"content" => "test"}] = json_response(conn, 200)
73
74 conn =
75 build_conn()
76 |> get("/api/v1/timelines/public", %{"local" => "1"})
77
78 assert [%{"content" => "test"}] = json_response(conn, 200)
79 end)
80 end
81
82 test "posting a status", %{conn: conn} do
83 user = insert(:user)
84
85 idempotency_key = "Pikachu rocks!"
86
87 conn_one =
88 conn
89 |> assign(:user, user)
90 |> put_req_header("idempotency-key", idempotency_key)
91 |> post("/api/v1/statuses", %{
92 "status" => "cofe",
93 "spoiler_text" => "2hu",
94 "sensitive" => "false"
95 })
96
97 {:ok, ttl} = Cachex.ttl(:idempotency_cache, idempotency_key)
98 # Six hours
99 assert ttl > :timer.seconds(6 * 60 * 60 - 1)
100
101 assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} =
102 json_response(conn_one, 200)
103
104 assert Activity.get_by_id(id)
105
106 conn_two =
107 conn
108 |> assign(:user, user)
109 |> put_req_header("idempotency-key", idempotency_key)
110 |> post("/api/v1/statuses", %{
111 "status" => "cofe",
112 "spoiler_text" => "2hu",
113 "sensitive" => "false"
114 })
115
116 assert %{"id" => second_id} = json_response(conn_two, 200)
117
118 assert id == second_id
119
120 conn_three =
121 conn
122 |> assign(:user, user)
123 |> post("/api/v1/statuses", %{
124 "status" => "cofe",
125 "spoiler_text" => "2hu",
126 "sensitive" => "false"
127 })
128
129 assert %{"id" => third_id} = json_response(conn_three, 200)
130
131 refute id == third_id
132 end
133
134 test "posting a sensitive status", %{conn: conn} do
135 user = insert(:user)
136
137 conn =
138 conn
139 |> assign(:user, user)
140 |> post("/api/v1/statuses", %{"status" => "cofe", "sensitive" => true})
141
142 assert %{"content" => "cofe", "id" => id, "sensitive" => true} = json_response(conn, 200)
143 assert Activity.get_by_id(id)
144 end
145
146 test "posting a fake status", %{conn: conn} do
147 user = insert(:user)
148
149 real_conn =
150 conn
151 |> assign(:user, user)
152 |> post("/api/v1/statuses", %{
153 "status" =>
154 "\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it"
155 })
156
157 real_status = json_response(real_conn, 200)
158
159 assert real_status
160 assert Object.get_by_ap_id(real_status["uri"])
161
162 real_status =
163 real_status
164 |> Map.put("id", nil)
165 |> Map.put("url", nil)
166 |> Map.put("uri", nil)
167 |> Map.put("created_at", nil)
168 |> Kernel.put_in(["pleroma", "conversation_id"], nil)
169
170 fake_conn =
171 conn
172 |> assign(:user, user)
173 |> post("/api/v1/statuses", %{
174 "status" =>
175 "\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it",
176 "preview" => true
177 })
178
179 fake_status = json_response(fake_conn, 200)
180
181 assert fake_status
182 refute Object.get_by_ap_id(fake_status["uri"])
183
184 fake_status =
185 fake_status
186 |> Map.put("id", nil)
187 |> Map.put("url", nil)
188 |> Map.put("uri", nil)
189 |> Map.put("created_at", nil)
190 |> Kernel.put_in(["pleroma", "conversation_id"], nil)
191
192 assert real_status == fake_status
193 end
194
195 test "posting a status with OGP link preview", %{conn: conn} do
196 Pleroma.Config.put([:rich_media, :enabled], true)
197 user = insert(:user)
198
199 conn =
200 conn
201 |> assign(:user, user)
202 |> post("/api/v1/statuses", %{
203 "status" => "http://example.com/ogp"
204 })
205
206 assert %{"id" => id, "card" => %{"title" => "The Rock"}} = json_response(conn, 200)
207 assert Activity.get_by_id(id)
208 Pleroma.Config.put([:rich_media, :enabled], false)
209 end
210
211 test "posting a direct status", %{conn: conn} do
212 user1 = insert(:user)
213 user2 = insert(:user)
214 content = "direct cofe @#{user2.nickname}"
215
216 conn =
217 conn
218 |> assign(:user, user1)
219 |> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"})
220
221 assert %{"id" => id, "visibility" => "direct"} = json_response(conn, 200)
222 assert activity = Activity.get_by_id(id)
223 assert activity.recipients == [user2.ap_id, user1.ap_id]
224 assert activity.data["to"] == [user2.ap_id]
225 assert activity.data["cc"] == []
226 end
227
228 test "direct timeline", %{conn: conn} do
229 user_one = insert(:user)
230 user_two = insert(:user)
231
232 {:ok, user_two} = User.follow(user_two, user_one)
233
234 {:ok, direct} =
235 CommonAPI.post(user_one, %{
236 "status" => "Hi @#{user_two.nickname}!",
237 "visibility" => "direct"
238 })
239
240 {:ok, _follower_only} =
241 CommonAPI.post(user_one, %{
242 "status" => "Hi @#{user_two.nickname}!",
243 "visibility" => "private"
244 })
245
246 # Only direct should be visible here
247 res_conn =
248 conn
249 |> assign(:user, user_two)
250 |> get("api/v1/timelines/direct")
251
252 [status] = json_response(res_conn, 200)
253
254 assert %{"visibility" => "direct"} = status
255 assert status["url"] != direct.data["id"]
256
257 # User should be able to see his own direct message
258 res_conn =
259 build_conn()
260 |> assign(:user, user_one)
261 |> get("api/v1/timelines/direct")
262
263 [status] = json_response(res_conn, 200)
264
265 assert %{"visibility" => "direct"} = status
266
267 # Both should be visible here
268 res_conn =
269 conn
270 |> assign(:user, user_two)
271 |> get("api/v1/timelines/home")
272
273 [_s1, _s2] = json_response(res_conn, 200)
274
275 # Test pagination
276 Enum.each(1..20, fn _ ->
277 {:ok, _} =
278 CommonAPI.post(user_one, %{
279 "status" => "Hi @#{user_two.nickname}!",
280 "visibility" => "direct"
281 })
282 end)
283
284 res_conn =
285 conn
286 |> assign(:user, user_two)
287 |> get("api/v1/timelines/direct")
288
289 statuses = json_response(res_conn, 200)
290 assert length(statuses) == 20
291
292 res_conn =
293 conn
294 |> assign(:user, user_two)
295 |> get("api/v1/timelines/direct", %{max_id: List.last(statuses)["id"]})
296
297 [status] = json_response(res_conn, 200)
298
299 assert status["url"] != direct.data["id"]
300 end
301
302 test "doesn't include DMs from blocked users", %{conn: conn} do
303 blocker = insert(:user)
304 blocked = insert(:user)
305 user = insert(:user)
306 {:ok, blocker} = User.block(blocker, blocked)
307
308 {:ok, _blocked_direct} =
309 CommonAPI.post(blocked, %{
310 "status" => "Hi @#{blocker.nickname}!",
311 "visibility" => "direct"
312 })
313
314 {:ok, direct} =
315 CommonAPI.post(user, %{
316 "status" => "Hi @#{blocker.nickname}!",
317 "visibility" => "direct"
318 })
319
320 res_conn =
321 conn
322 |> assign(:user, user)
323 |> get("api/v1/timelines/direct")
324
325 [status] = json_response(res_conn, 200)
326 assert status["id"] == direct.id
327 end
328
329 test "replying to a status", %{conn: conn} do
330 user = insert(:user)
331
332 {:ok, replied_to} = TwitterAPI.create_status(user, %{"status" => "cofe"})
333
334 conn =
335 conn
336 |> assign(:user, user)
337 |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id})
338
339 assert %{"content" => "xD", "id" => id} = json_response(conn, 200)
340
341 activity = Activity.get_by_id(id)
342
343 assert activity.data["context"] == replied_to.data["context"]
344 assert activity.data["object"]["inReplyToStatusId"] == replied_to.id
345 end
346
347 test "posting a status with an invalid in_reply_to_id", %{conn: conn} do
348 user = insert(:user)
349
350 conn =
351 conn
352 |> assign(:user, user)
353 |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""})
354
355 assert %{"content" => "xD", "id" => id} = json_response(conn, 200)
356
357 activity = Activity.get_by_id(id)
358
359 assert activity
360 end
361
362 test "verify_credentials", %{conn: conn} do
363 user = insert(:user)
364
365 conn =
366 conn
367 |> assign(:user, user)
368 |> get("/api/v1/accounts/verify_credentials")
369
370 assert %{"id" => id, "source" => %{"privacy" => "public"}} = json_response(conn, 200)
371 assert id == to_string(user.id)
372 end
373
374 test "verify_credentials default scope unlisted", %{conn: conn} do
375 user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "unlisted"}})
376
377 conn =
378 conn
379 |> assign(:user, user)
380 |> get("/api/v1/accounts/verify_credentials")
381
382 assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200)
383 assert id == to_string(user.id)
384 end
385
386 test "apps/verify_credentials", %{conn: conn} do
387 token = insert(:oauth_token)
388
389 conn =
390 conn
391 |> assign(:user, token.user)
392 |> assign(:token, token)
393 |> get("/api/v1/apps/verify_credentials")
394
395 app = Repo.preload(token, :app).app
396
397 expected = %{
398 "name" => app.client_name,
399 "website" => app.website,
400 "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key)
401 }
402
403 assert expected == json_response(conn, 200)
404 end
405
406 test "creates an oauth app", %{conn: conn} do
407 user = insert(:user)
408 app_attrs = build(:oauth_app)
409
410 conn =
411 conn
412 |> assign(:user, user)
413 |> post("/api/v1/apps", %{
414 client_name: app_attrs.client_name,
415 redirect_uris: app_attrs.redirect_uris
416 })
417
418 [app] = Repo.all(App)
419
420 expected = %{
421 "name" => app.client_name,
422 "website" => app.website,
423 "client_id" => app.client_id,
424 "client_secret" => app.client_secret,
425 "id" => app.id |> to_string(),
426 "redirect_uri" => app.redirect_uris,
427 "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key)
428 }
429
430 assert expected == json_response(conn, 200)
431 end
432
433 test "get a status", %{conn: conn} do
434 activity = insert(:note_activity)
435
436 conn =
437 conn
438 |> get("/api/v1/statuses/#{activity.id}")
439
440 assert %{"id" => id} = json_response(conn, 200)
441 assert id == to_string(activity.id)
442 end
443
444 describe "deleting a status" do
445 test "when you created it", %{conn: conn} do
446 activity = insert(:note_activity)
447 author = User.get_by_ap_id(activity.data["actor"])
448
449 conn =
450 conn
451 |> assign(:user, author)
452 |> delete("/api/v1/statuses/#{activity.id}")
453
454 assert %{} = json_response(conn, 200)
455
456 refute Activity.get_by_id(activity.id)
457 end
458
459 test "when you didn't create it", %{conn: conn} do
460 activity = insert(:note_activity)
461 user = insert(:user)
462
463 conn =
464 conn
465 |> assign(:user, user)
466 |> delete("/api/v1/statuses/#{activity.id}")
467
468 assert %{"error" => _} = json_response(conn, 403)
469
470 assert Activity.get_by_id(activity.id) == activity
471 end
472
473 test "when you're an admin or moderator", %{conn: conn} do
474 activity1 = insert(:note_activity)
475 activity2 = insert(:note_activity)
476 admin = insert(:user, info: %{is_admin: true})
477 moderator = insert(:user, info: %{is_moderator: true})
478
479 res_conn =
480 conn
481 |> assign(:user, admin)
482 |> delete("/api/v1/statuses/#{activity1.id}")
483
484 assert %{} = json_response(res_conn, 200)
485
486 res_conn =
487 conn
488 |> assign(:user, moderator)
489 |> delete("/api/v1/statuses/#{activity2.id}")
490
491 assert %{} = json_response(res_conn, 200)
492
493 refute Activity.get_by_id(activity1.id)
494 refute Activity.get_by_id(activity2.id)
495 end
496 end
497
498 describe "filters" do
499 test "creating a filter", %{conn: conn} do
500 user = insert(:user)
501
502 filter = %Pleroma.Filter{
503 phrase: "knights",
504 context: ["home"]
505 }
506
507 conn =
508 conn
509 |> assign(:user, user)
510 |> post("/api/v1/filters", %{"phrase" => filter.phrase, context: filter.context})
511
512 assert response = json_response(conn, 200)
513 assert response["phrase"] == filter.phrase
514 assert response["context"] == filter.context
515 assert response["id"] != nil
516 assert response["id"] != ""
517 end
518
519 test "fetching a list of filters", %{conn: conn} do
520 user = insert(:user)
521
522 query_one = %Pleroma.Filter{
523 user_id: user.id,
524 filter_id: 1,
525 phrase: "knights",
526 context: ["home"]
527 }
528
529 query_two = %Pleroma.Filter{
530 user_id: user.id,
531 filter_id: 2,
532 phrase: "who",
533 context: ["home"]
534 }
535
536 {:ok, filter_one} = Pleroma.Filter.create(query_one)
537 {:ok, filter_two} = Pleroma.Filter.create(query_two)
538
539 response =
540 conn
541 |> assign(:user, user)
542 |> get("/api/v1/filters")
543 |> json_response(200)
544
545 assert response ==
546 render_json(
547 FilterView,
548 "filters.json",
549 filters: [filter_two, filter_one]
550 )
551 end
552
553 test "get a filter", %{conn: conn} do
554 user = insert(:user)
555
556 query = %Pleroma.Filter{
557 user_id: user.id,
558 filter_id: 2,
559 phrase: "knight",
560 context: ["home"]
561 }
562
563 {:ok, filter} = Pleroma.Filter.create(query)
564
565 conn =
566 conn
567 |> assign(:user, user)
568 |> get("/api/v1/filters/#{filter.filter_id}")
569
570 assert _response = json_response(conn, 200)
571 end
572
573 test "update a filter", %{conn: conn} do
574 user = insert(:user)
575
576 query = %Pleroma.Filter{
577 user_id: user.id,
578 filter_id: 2,
579 phrase: "knight",
580 context: ["home"]
581 }
582
583 {:ok, _filter} = Pleroma.Filter.create(query)
584
585 new = %Pleroma.Filter{
586 phrase: "nii",
587 context: ["home"]
588 }
589
590 conn =
591 conn
592 |> assign(:user, user)
593 |> put("/api/v1/filters/#{query.filter_id}", %{
594 phrase: new.phrase,
595 context: new.context
596 })
597
598 assert response = json_response(conn, 200)
599 assert response["phrase"] == new.phrase
600 assert response["context"] == new.context
601 end
602
603 test "delete a filter", %{conn: conn} do
604 user = insert(:user)
605
606 query = %Pleroma.Filter{
607 user_id: user.id,
608 filter_id: 2,
609 phrase: "knight",
610 context: ["home"]
611 }
612
613 {:ok, filter} = Pleroma.Filter.create(query)
614
615 conn =
616 conn
617 |> assign(:user, user)
618 |> delete("/api/v1/filters/#{filter.filter_id}")
619
620 assert response = json_response(conn, 200)
621 assert response == %{}
622 end
623 end
624
625 describe "lists" do
626 test "creating a list", %{conn: conn} do
627 user = insert(:user)
628
629 conn =
630 conn
631 |> assign(:user, user)
632 |> post("/api/v1/lists", %{"title" => "cuties"})
633
634 assert %{"title" => title} = json_response(conn, 200)
635 assert title == "cuties"
636 end
637
638 test "adding users to a list", %{conn: conn} do
639 user = insert(:user)
640 other_user = insert(:user)
641 {:ok, list} = Pleroma.List.create("name", user)
642
643 conn =
644 conn
645 |> assign(:user, user)
646 |> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
647
648 assert %{} == json_response(conn, 200)
649 %Pleroma.List{following: following} = Pleroma.List.get(list.id, user)
650 assert following == [other_user.follower_address]
651 end
652
653 test "removing users from a list", %{conn: conn} do
654 user = insert(:user)
655 other_user = insert(:user)
656 third_user = insert(:user)
657 {:ok, list} = Pleroma.List.create("name", user)
658 {:ok, list} = Pleroma.List.follow(list, other_user)
659 {:ok, list} = Pleroma.List.follow(list, third_user)
660
661 conn =
662 conn
663 |> assign(:user, user)
664 |> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
665
666 assert %{} == json_response(conn, 200)
667 %Pleroma.List{following: following} = Pleroma.List.get(list.id, user)
668 assert following == [third_user.follower_address]
669 end
670
671 test "listing users in a list", %{conn: conn} do
672 user = insert(:user)
673 other_user = insert(:user)
674 {:ok, list} = Pleroma.List.create("name", user)
675 {:ok, list} = Pleroma.List.follow(list, other_user)
676
677 conn =
678 conn
679 |> assign(:user, user)
680 |> get("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
681
682 assert [%{"id" => id}] = json_response(conn, 200)
683 assert id == to_string(other_user.id)
684 end
685
686 test "retrieving a list", %{conn: conn} do
687 user = insert(:user)
688 {:ok, list} = Pleroma.List.create("name", user)
689
690 conn =
691 conn
692 |> assign(:user, user)
693 |> get("/api/v1/lists/#{list.id}")
694
695 assert %{"id" => id} = json_response(conn, 200)
696 assert id == to_string(list.id)
697 end
698
699 test "renaming a list", %{conn: conn} do
700 user = insert(:user)
701 {:ok, list} = Pleroma.List.create("name", user)
702
703 conn =
704 conn
705 |> assign(:user, user)
706 |> put("/api/v1/lists/#{list.id}", %{"title" => "newname"})
707
708 assert %{"title" => name} = json_response(conn, 200)
709 assert name == "newname"
710 end
711
712 test "deleting a list", %{conn: conn} do
713 user = insert(:user)
714 {:ok, list} = Pleroma.List.create("name", user)
715
716 conn =
717 conn
718 |> assign(:user, user)
719 |> delete("/api/v1/lists/#{list.id}")
720
721 assert %{} = json_response(conn, 200)
722 assert is_nil(Repo.get(Pleroma.List, list.id))
723 end
724
725 test "list timeline", %{conn: conn} do
726 user = insert(:user)
727 other_user = insert(:user)
728 {:ok, _activity_one} = TwitterAPI.create_status(user, %{"status" => "Marisa is cute."})
729 {:ok, activity_two} = TwitterAPI.create_status(other_user, %{"status" => "Marisa is cute."})
730 {:ok, list} = Pleroma.List.create("name", user)
731 {:ok, list} = Pleroma.List.follow(list, other_user)
732
733 conn =
734 conn
735 |> assign(:user, user)
736 |> get("/api/v1/timelines/list/#{list.id}")
737
738 assert [%{"id" => id}] = json_response(conn, 200)
739
740 assert id == to_string(activity_two.id)
741 end
742
743 test "list timeline does not leak non-public statuses for unfollowed users", %{conn: conn} do
744 user = insert(:user)
745 other_user = insert(:user)
746 {:ok, activity_one} = TwitterAPI.create_status(other_user, %{"status" => "Marisa is cute."})
747
748 {:ok, _activity_two} =
749 TwitterAPI.create_status(other_user, %{
750 "status" => "Marisa is cute.",
751 "visibility" => "private"
752 })
753
754 {:ok, list} = Pleroma.List.create("name", user)
755 {:ok, list} = Pleroma.List.follow(list, other_user)
756
757 conn =
758 conn
759 |> assign(:user, user)
760 |> get("/api/v1/timelines/list/#{list.id}")
761
762 assert [%{"id" => id}] = json_response(conn, 200)
763
764 assert id == to_string(activity_one.id)
765 end
766 end
767
768 describe "notifications" do
769 test "list of notifications", %{conn: conn} do
770 user = insert(:user)
771 other_user = insert(:user)
772
773 {:ok, activity} =
774 TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
775
776 {:ok, [_notification]} = Notification.create_notifications(activity)
777
778 conn =
779 conn
780 |> assign(:user, user)
781 |> get("/api/v1/notifications")
782
783 expected_response =
784 "hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{
785 user.ap_id
786 }\">@<span>#{user.nickname}</span></a></span>"
787
788 assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200)
789 assert response == expected_response
790 end
791
792 test "getting a single notification", %{conn: conn} do
793 user = insert(:user)
794 other_user = insert(:user)
795
796 {:ok, activity} =
797 TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
798
799 {:ok, [notification]} = Notification.create_notifications(activity)
800
801 conn =
802 conn
803 |> assign(:user, user)
804 |> get("/api/v1/notifications/#{notification.id}")
805
806 expected_response =
807 "hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{
808 user.ap_id
809 }\">@<span>#{user.nickname}</span></a></span>"
810
811 assert %{"status" => %{"content" => response}} = json_response(conn, 200)
812 assert response == expected_response
813 end
814
815 test "dismissing a single notification", %{conn: conn} do
816 user = insert(:user)
817 other_user = insert(:user)
818
819 {:ok, activity} =
820 TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
821
822 {:ok, [notification]} = Notification.create_notifications(activity)
823
824 conn =
825 conn
826 |> assign(:user, user)
827 |> post("/api/v1/notifications/dismiss", %{"id" => notification.id})
828
829 assert %{} = json_response(conn, 200)
830 end
831
832 test "clearing all notifications", %{conn: conn} do
833 user = insert(:user)
834 other_user = insert(:user)
835
836 {:ok, activity} =
837 TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})
838
839 {:ok, [_notification]} = Notification.create_notifications(activity)
840
841 conn =
842 conn
843 |> assign(:user, user)
844 |> post("/api/v1/notifications/clear")
845
846 assert %{} = json_response(conn, 200)
847
848 conn =
849 build_conn()
850 |> assign(:user, user)
851 |> get("/api/v1/notifications")
852
853 assert all = json_response(conn, 200)
854 assert all == []
855 end
856
857 test "paginates notifications using min_id, since_id, max_id, and limit", %{conn: conn} do
858 user = insert(:user)
859 other_user = insert(:user)
860
861 {:ok, activity1} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
862 {:ok, activity2} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
863 {:ok, activity3} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
864 {:ok, activity4} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
865
866 notification1_id = Repo.get_by(Notification, activity_id: activity1.id).id |> to_string()
867 notification2_id = Repo.get_by(Notification, activity_id: activity2.id).id |> to_string()
868 notification3_id = Repo.get_by(Notification, activity_id: activity3.id).id |> to_string()
869 notification4_id = Repo.get_by(Notification, activity_id: activity4.id).id |> to_string()
870
871 conn =
872 conn
873 |> assign(:user, user)
874
875 # min_id
876 conn_res =
877 conn
878 |> get("/api/v1/notifications?limit=2&min_id=#{notification1_id}")
879
880 result = json_response(conn_res, 200)
881 assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
882
883 # since_id
884 conn_res =
885 conn
886 |> get("/api/v1/notifications?limit=2&since_id=#{notification1_id}")
887
888 result = json_response(conn_res, 200)
889 assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
890
891 # max_id
892 conn_res =
893 conn
894 |> get("/api/v1/notifications?limit=2&max_id=#{notification4_id}")
895
896 result = json_response(conn_res, 200)
897 assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
898 end
899
900 test "filters notifications using exclude_types", %{conn: conn} do
901 user = insert(:user)
902 other_user = insert(:user)
903
904 {:ok, mention_activity} = CommonAPI.post(other_user, %{"status" => "hey @#{user.nickname}"})
905 {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"})
906 {:ok, favorite_activity, _} = CommonAPI.favorite(create_activity.id, other_user)
907 {:ok, reblog_activity, _} = CommonAPI.repeat(create_activity.id, other_user)
908 {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
909
910 mention_notification_id =
911 Repo.get_by(Notification, activity_id: mention_activity.id).id |> to_string()
912
913 favorite_notification_id =
914 Repo.get_by(Notification, activity_id: favorite_activity.id).id |> to_string()
915
916 reblog_notification_id =
917 Repo.get_by(Notification, activity_id: reblog_activity.id).id |> to_string()
918
919 follow_notification_id =
920 Repo.get_by(Notification, activity_id: follow_activity.id).id |> to_string()
921
922 conn =
923 conn
924 |> assign(:user, user)
925
926 conn_res =
927 get(conn, "/api/v1/notifications", %{exclude_types: ["mention", "favourite", "reblog"]})
928
929 assert [%{"id" => ^follow_notification_id}] = json_response(conn_res, 200)
930
931 conn_res =
932 get(conn, "/api/v1/notifications", %{exclude_types: ["favourite", "reblog", "follow"]})
933
934 assert [%{"id" => ^mention_notification_id}] = json_response(conn_res, 200)
935
936 conn_res =
937 get(conn, "/api/v1/notifications", %{exclude_types: ["reblog", "follow", "mention"]})
938
939 assert [%{"id" => ^favorite_notification_id}] = json_response(conn_res, 200)
940
941 conn_res =
942 get(conn, "/api/v1/notifications", %{exclude_types: ["follow", "mention", "favourite"]})
943
944 assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200)
945 end
946 end
947
948 describe "reblogging" do
949 test "reblogs and returns the reblogged status", %{conn: conn} do
950 activity = insert(:note_activity)
951 user = insert(:user)
952
953 conn =
954 conn
955 |> assign(:user, user)
956 |> post("/api/v1/statuses/#{activity.id}/reblog")
957
958 assert %{"reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}} =
959 json_response(conn, 200)
960
961 assert to_string(activity.id) == id
962 end
963 end
964
965 describe "unreblogging" do
966 test "unreblogs and returns the unreblogged status", %{conn: conn} do
967 activity = insert(:note_activity)
968 user = insert(:user)
969
970 {:ok, _, _} = CommonAPI.repeat(activity.id, user)
971
972 conn =
973 conn
974 |> assign(:user, user)
975 |> post("/api/v1/statuses/#{activity.id}/unreblog")
976
977 assert %{"id" => id, "reblogged" => false, "reblogs_count" => 0} = json_response(conn, 200)
978
979 assert to_string(activity.id) == id
980 end
981 end
982
983 describe "favoriting" do
984 test "favs a status and returns it", %{conn: conn} do
985 activity = insert(:note_activity)
986 user = insert(:user)
987
988 conn =
989 conn
990 |> assign(:user, user)
991 |> post("/api/v1/statuses/#{activity.id}/favourite")
992
993 assert %{"id" => id, "favourites_count" => 1, "favourited" => true} =
994 json_response(conn, 200)
995
996 assert to_string(activity.id) == id
997 end
998
999 test "returns 500 for a wrong id", %{conn: conn} do
1000 user = insert(:user)
1001
1002 resp =
1003 conn
1004 |> assign(:user, user)
1005 |> post("/api/v1/statuses/1/favourite")
1006 |> json_response(500)
1007
1008 assert resp == "Something went wrong"
1009 end
1010 end
1011
1012 describe "unfavoriting" do
1013 test "unfavorites a status and returns it", %{conn: conn} do
1014 activity = insert(:note_activity)
1015 user = insert(:user)
1016
1017 {:ok, _, _} = CommonAPI.favorite(activity.id, user)
1018
1019 conn =
1020 conn
1021 |> assign(:user, user)
1022 |> post("/api/v1/statuses/#{activity.id}/unfavourite")
1023
1024 assert %{"id" => id, "favourites_count" => 0, "favourited" => false} =
1025 json_response(conn, 200)
1026
1027 assert to_string(activity.id) == id
1028 end
1029 end
1030
1031 describe "user timelines" do
1032 test "gets a users statuses", %{conn: conn} do
1033 user_one = insert(:user)
1034 user_two = insert(:user)
1035 user_three = insert(:user)
1036
1037 {:ok, user_three} = User.follow(user_three, user_one)
1038
1039 {:ok, activity} = CommonAPI.post(user_one, %{"status" => "HI!!!"})
1040
1041 {:ok, direct_activity} =
1042 CommonAPI.post(user_one, %{
1043 "status" => "Hi, @#{user_two.nickname}.",
1044 "visibility" => "direct"
1045 })
1046
1047 {:ok, private_activity} =
1048 CommonAPI.post(user_one, %{"status" => "private", "visibility" => "private"})
1049
1050 resp =
1051 conn
1052 |> get("/api/v1/accounts/#{user_one.id}/statuses")
1053
1054 assert [%{"id" => id}] = json_response(resp, 200)
1055 assert id == to_string(activity.id)
1056
1057 resp =
1058 conn
1059 |> assign(:user, user_two)
1060 |> get("/api/v1/accounts/#{user_one.id}/statuses")
1061
1062 assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
1063 assert id_one == to_string(direct_activity.id)
1064 assert id_two == to_string(activity.id)
1065
1066 resp =
1067 conn
1068 |> assign(:user, user_three)
1069 |> get("/api/v1/accounts/#{user_one.id}/statuses")
1070
1071 assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
1072 assert id_one == to_string(private_activity.id)
1073 assert id_two == to_string(activity.id)
1074 end
1075
1076 test "unimplemented pinned statuses feature", %{conn: conn} do
1077 note = insert(:note_activity)
1078 user = User.get_by_ap_id(note.data["actor"])
1079
1080 conn =
1081 conn
1082 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
1083
1084 assert json_response(conn, 200) == []
1085 end
1086
1087 test "gets an users media", %{conn: conn} do
1088 note = insert(:note_activity)
1089 user = User.get_by_ap_id(note.data["actor"])
1090
1091 file = %Plug.Upload{
1092 content_type: "image/jpg",
1093 path: Path.absname("test/fixtures/image.jpg"),
1094 filename: "an_image.jpg"
1095 }
1096
1097 media =
1098 TwitterAPI.upload(file, user, "json")
1099 |> Poison.decode!()
1100
1101 {:ok, image_post} =
1102 TwitterAPI.create_status(user, %{"status" => "cofe", "media_ids" => [media["media_id"]]})
1103
1104 conn =
1105 conn
1106 |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "true"})
1107
1108 assert [%{"id" => id}] = json_response(conn, 200)
1109 assert id == to_string(image_post.id)
1110
1111 conn =
1112 build_conn()
1113 |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "1"})
1114
1115 assert [%{"id" => id}] = json_response(conn, 200)
1116 assert id == to_string(image_post.id)
1117 end
1118
1119 test "gets a user's statuses without reblogs", %{conn: conn} do
1120 user = insert(:user)
1121 {:ok, post} = CommonAPI.post(user, %{"status" => "HI!!!"})
1122 {:ok, _, _} = CommonAPI.repeat(post.id, user)
1123
1124 conn =
1125 conn
1126 |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"})
1127
1128 assert [%{"id" => id}] = json_response(conn, 200)
1129 assert id == to_string(post.id)
1130
1131 conn =
1132 conn
1133 |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "1"})
1134
1135 assert [%{"id" => id}] = json_response(conn, 200)
1136 assert id == to_string(post.id)
1137 end
1138 end
1139
1140 describe "user relationships" do
1141 test "returns the relationships for the current user", %{conn: conn} do
1142 user = insert(:user)
1143 other_user = insert(:user)
1144 {:ok, user} = User.follow(user, other_user)
1145
1146 conn =
1147 conn
1148 |> assign(:user, user)
1149 |> get("/api/v1/accounts/relationships", %{"id" => [other_user.id]})
1150
1151 assert [relationship] = json_response(conn, 200)
1152
1153 assert to_string(other_user.id) == relationship["id"]
1154 end
1155 end
1156
1157 describe "locked accounts" do
1158 test "/api/v1/follow_requests works" do
1159 user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
1160 other_user = insert(:user)
1161
1162 {:ok, _activity} = ActivityPub.follow(other_user, user)
1163
1164 user = User.get_by_id(user.id)
1165 other_user = User.get_by_id(other_user.id)
1166
1167 assert User.following?(other_user, user) == false
1168
1169 conn =
1170 build_conn()
1171 |> assign(:user, user)
1172 |> get("/api/v1/follow_requests")
1173
1174 assert [relationship] = json_response(conn, 200)
1175 assert to_string(other_user.id) == relationship["id"]
1176 end
1177
1178 test "/api/v1/follow_requests/:id/authorize works" do
1179 user = insert(:user, %{info: %User.Info{locked: true}})
1180 other_user = insert(:user)
1181
1182 {:ok, _activity} = ActivityPub.follow(other_user, user)
1183
1184 user = User.get_by_id(user.id)
1185 other_user = User.get_by_id(other_user.id)
1186
1187 assert User.following?(other_user, user) == false
1188
1189 conn =
1190 build_conn()
1191 |> assign(:user, user)
1192 |> post("/api/v1/follow_requests/#{other_user.id}/authorize")
1193
1194 assert relationship = json_response(conn, 200)
1195 assert to_string(other_user.id) == relationship["id"]
1196
1197 user = User.get_by_id(user.id)
1198 other_user = User.get_by_id(other_user.id)
1199
1200 assert User.following?(other_user, user) == true
1201 end
1202
1203 test "verify_credentials", %{conn: conn} do
1204 user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "private"}})
1205
1206 conn =
1207 conn
1208 |> assign(:user, user)
1209 |> get("/api/v1/accounts/verify_credentials")
1210
1211 assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
1212 assert id == to_string(user.id)
1213 end
1214
1215 test "/api/v1/follow_requests/:id/reject works" do
1216 user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
1217 other_user = insert(:user)
1218
1219 {:ok, _activity} = ActivityPub.follow(other_user, user)
1220
1221 user = User.get_by_id(user.id)
1222
1223 conn =
1224 build_conn()
1225 |> assign(:user, user)
1226 |> post("/api/v1/follow_requests/#{other_user.id}/reject")
1227
1228 assert relationship = json_response(conn, 200)
1229 assert to_string(other_user.id) == relationship["id"]
1230
1231 user = User.get_by_id(user.id)
1232 other_user = User.get_by_id(other_user.id)
1233
1234 assert User.following?(other_user, user) == false
1235 end
1236 end
1237
1238 test "account fetching", %{conn: conn} do
1239 user = insert(:user)
1240
1241 conn =
1242 conn
1243 |> get("/api/v1/accounts/#{user.id}")
1244
1245 assert %{"id" => id} = json_response(conn, 200)
1246 assert id == to_string(user.id)
1247
1248 conn =
1249 build_conn()
1250 |> get("/api/v1/accounts/-1")
1251
1252 assert %{"error" => "Can't find user"} = json_response(conn, 404)
1253 end
1254
1255 test "account fetching also works nickname", %{conn: conn} do
1256 user = insert(:user)
1257
1258 conn =
1259 conn
1260 |> get("/api/v1/accounts/#{user.nickname}")
1261
1262 assert %{"id" => id} = json_response(conn, 200)
1263 assert id == user.id
1264 end
1265
1266 test "media upload", %{conn: conn} do
1267 file = %Plug.Upload{
1268 content_type: "image/jpg",
1269 path: Path.absname("test/fixtures/image.jpg"),
1270 filename: "an_image.jpg"
1271 }
1272
1273 desc = "Description of the image"
1274
1275 user = insert(:user)
1276
1277 conn =
1278 conn
1279 |> assign(:user, user)
1280 |> post("/api/v1/media", %{"file" => file, "description" => desc})
1281
1282 assert media = json_response(conn, 200)
1283
1284 assert media["type"] == "image"
1285 assert media["description"] == desc
1286 assert media["id"]
1287
1288 object = Repo.get(Object, media["id"])
1289 assert object.data["actor"] == User.ap_id(user)
1290 end
1291
1292 test "hashtag timeline", %{conn: conn} do
1293 following = insert(:user)
1294
1295 capture_log(fn ->
1296 {:ok, activity} = TwitterAPI.create_status(following, %{"status" => "test #2hu"})
1297
1298 {:ok, [_activity]} =
1299 OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873")
1300
1301 nconn =
1302 conn
1303 |> get("/api/v1/timelines/tag/2hu")
1304
1305 assert [%{"id" => id}] = json_response(nconn, 200)
1306
1307 assert id == to_string(activity.id)
1308
1309 # works for different capitalization too
1310 nconn =
1311 conn
1312 |> get("/api/v1/timelines/tag/2HU")
1313
1314 assert [%{"id" => id}] = json_response(nconn, 200)
1315
1316 assert id == to_string(activity.id)
1317 end)
1318 end
1319
1320 test "multi-hashtag timeline", %{conn: conn} do
1321 user = insert(:user)
1322
1323 {:ok, activity_test} = CommonAPI.post(user, %{"status" => "#test"})
1324 {:ok, activity_test1} = CommonAPI.post(user, %{"status" => "#test #test1"})
1325 {:ok, activity_none} = CommonAPI.post(user, %{"status" => "#test #none"})
1326
1327 any_test =
1328 conn
1329 |> get("/api/v1/timelines/tag/test", %{"any" => ["test1"]})
1330
1331 [status_none, status_test1, status_test] = json_response(any_test, 200)
1332
1333 assert to_string(activity_test.id) == status_test["id"]
1334 assert to_string(activity_test1.id) == status_test1["id"]
1335 assert to_string(activity_none.id) == status_none["id"]
1336
1337 restricted_test =
1338 conn
1339 |> get("/api/v1/timelines/tag/test", %{"all" => ["test1"], "none" => ["none"]})
1340
1341 assert [status_test1] == json_response(restricted_test, 200)
1342
1343 all_test = conn |> get("/api/v1/timelines/tag/test", %{"all" => ["none"]})
1344
1345 assert [status_none] == json_response(all_test, 200)
1346 end
1347
1348 test "getting followers", %{conn: conn} do
1349 user = insert(:user)
1350 other_user = insert(:user)
1351 {:ok, user} = User.follow(user, other_user)
1352
1353 conn =
1354 conn
1355 |> get("/api/v1/accounts/#{other_user.id}/followers")
1356
1357 assert [%{"id" => id}] = json_response(conn, 200)
1358 assert id == to_string(user.id)
1359 end
1360
1361 test "getting followers, hide_followers", %{conn: conn} do
1362 user = insert(:user)
1363 other_user = insert(:user, %{info: %{hide_followers: true}})
1364 {:ok, _user} = User.follow(user, other_user)
1365
1366 conn =
1367 conn
1368 |> get("/api/v1/accounts/#{other_user.id}/followers")
1369
1370 assert [] == json_response(conn, 200)
1371 end
1372
1373 test "getting followers, hide_followers, same user requesting", %{conn: conn} do
1374 user = insert(:user)
1375 other_user = insert(:user, %{info: %{hide_followers: true}})
1376 {:ok, _user} = User.follow(user, other_user)
1377
1378 conn =
1379 conn
1380 |> assign(:user, other_user)
1381 |> get("/api/v1/accounts/#{other_user.id}/followers")
1382
1383 refute [] == json_response(conn, 200)
1384 end
1385
1386 test "getting followers, pagination", %{conn: conn} do
1387 user = insert(:user)
1388 follower1 = insert(:user)
1389 follower2 = insert(:user)
1390 follower3 = insert(:user)
1391 {:ok, _} = User.follow(follower1, user)
1392 {:ok, _} = User.follow(follower2, user)
1393 {:ok, _} = User.follow(follower3, user)
1394
1395 conn =
1396 conn
1397 |> assign(:user, user)
1398
1399 res_conn =
1400 conn
1401 |> get("/api/v1/accounts/#{user.id}/followers?since_id=#{follower1.id}")
1402
1403 assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200)
1404 assert id3 == follower3.id
1405 assert id2 == follower2.id
1406
1407 res_conn =
1408 conn
1409 |> get("/api/v1/accounts/#{user.id}/followers?max_id=#{follower3.id}")
1410
1411 assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200)
1412 assert id2 == follower2.id
1413 assert id1 == follower1.id
1414
1415 res_conn =
1416 conn
1417 |> get("/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3.id}")
1418
1419 assert [%{"id" => id2}] = json_response(res_conn, 200)
1420 assert id2 == follower2.id
1421
1422 assert [link_header] = get_resp_header(res_conn, "link")
1423 assert link_header =~ ~r/since_id=#{follower2.id}/
1424 assert link_header =~ ~r/max_id=#{follower2.id}/
1425 end
1426
1427 test "getting following", %{conn: conn} do
1428 user = insert(:user)
1429 other_user = insert(:user)
1430 {:ok, user} = User.follow(user, other_user)
1431
1432 conn =
1433 conn
1434 |> get("/api/v1/accounts/#{user.id}/following")
1435
1436 assert [%{"id" => id}] = json_response(conn, 200)
1437 assert id == to_string(other_user.id)
1438 end
1439
1440 test "getting following, hide_follows", %{conn: conn} do
1441 user = insert(:user, %{info: %{hide_follows: true}})
1442 other_user = insert(:user)
1443 {:ok, user} = User.follow(user, other_user)
1444
1445 conn =
1446 conn
1447 |> get("/api/v1/accounts/#{user.id}/following")
1448
1449 assert [] == json_response(conn, 200)
1450 end
1451
1452 test "getting following, hide_follows, same user requesting", %{conn: conn} do
1453 user = insert(:user, %{info: %{hide_follows: true}})
1454 other_user = insert(:user)
1455 {:ok, user} = User.follow(user, other_user)
1456
1457 conn =
1458 conn
1459 |> assign(:user, user)
1460 |> get("/api/v1/accounts/#{user.id}/following")
1461
1462 refute [] == json_response(conn, 200)
1463 end
1464
1465 test "getting following, pagination", %{conn: conn} do
1466 user = insert(:user)
1467 following1 = insert(:user)
1468 following2 = insert(:user)
1469 following3 = insert(:user)
1470 {:ok, _} = User.follow(user, following1)
1471 {:ok, _} = User.follow(user, following2)
1472 {:ok, _} = User.follow(user, following3)
1473
1474 conn =
1475 conn
1476 |> assign(:user, user)
1477
1478 res_conn =
1479 conn
1480 |> get("/api/v1/accounts/#{user.id}/following?since_id=#{following1.id}")
1481
1482 assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200)
1483 assert id3 == following3.id
1484 assert id2 == following2.id
1485
1486 res_conn =
1487 conn
1488 |> get("/api/v1/accounts/#{user.id}/following?max_id=#{following3.id}")
1489
1490 assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200)
1491 assert id2 == following2.id
1492 assert id1 == following1.id
1493
1494 res_conn =
1495 conn
1496 |> get("/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}")
1497
1498 assert [%{"id" => id2}] = json_response(res_conn, 200)
1499 assert id2 == following2.id
1500
1501 assert [link_header] = get_resp_header(res_conn, "link")
1502 assert link_header =~ ~r/since_id=#{following2.id}/
1503 assert link_header =~ ~r/max_id=#{following2.id}/
1504 end
1505
1506 test "following / unfollowing a user", %{conn: conn} do
1507 user = insert(:user)
1508 other_user = insert(:user)
1509
1510 conn =
1511 conn
1512 |> assign(:user, user)
1513 |> post("/api/v1/accounts/#{other_user.id}/follow")
1514
1515 assert %{"id" => _id, "following" => true} = json_response(conn, 200)
1516
1517 user = User.get_by_id(user.id)
1518
1519 conn =
1520 build_conn()
1521 |> assign(:user, user)
1522 |> post("/api/v1/accounts/#{other_user.id}/unfollow")
1523
1524 assert %{"id" => _id, "following" => false} = json_response(conn, 200)
1525
1526 user = User.get_by_id(user.id)
1527
1528 conn =
1529 build_conn()
1530 |> assign(:user, user)
1531 |> post("/api/v1/follows", %{"uri" => other_user.nickname})
1532
1533 assert %{"id" => id} = json_response(conn, 200)
1534 assert id == to_string(other_user.id)
1535 end
1536
1537 test "muting / unmuting a user", %{conn: conn} do
1538 user = insert(:user)
1539 other_user = insert(:user)
1540
1541 conn =
1542 conn
1543 |> assign(:user, user)
1544 |> post("/api/v1/accounts/#{other_user.id}/mute")
1545
1546 assert %{"id" => _id, "muting" => true} = json_response(conn, 200)
1547
1548 user = User.get_by_id(user.id)
1549
1550 conn =
1551 build_conn()
1552 |> assign(:user, user)
1553 |> post("/api/v1/accounts/#{other_user.id}/unmute")
1554
1555 assert %{"id" => _id, "muting" => false} = json_response(conn, 200)
1556 end
1557
1558 test "subscribing / unsubscribing to a user", %{conn: conn} do
1559 user = insert(:user)
1560 subscription_target = insert(:user)
1561
1562 conn =
1563 conn
1564 |> assign(:user, user)
1565 |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/subscribe")
1566
1567 assert %{"id" => _id, "subscribing" => true} = json_response(conn, 200)
1568
1569 conn =
1570 build_conn()
1571 |> assign(:user, user)
1572 |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/unsubscribe")
1573
1574 assert %{"id" => _id, "subscribing" => false} = json_response(conn, 200)
1575 end
1576
1577 test "getting a list of mutes", %{conn: conn} do
1578 user = insert(:user)
1579 other_user = insert(:user)
1580
1581 {:ok, user} = User.mute(user, other_user)
1582
1583 conn =
1584 conn
1585 |> assign(:user, user)
1586 |> get("/api/v1/mutes")
1587
1588 other_user_id = to_string(other_user.id)
1589 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
1590 end
1591
1592 test "blocking / unblocking a user", %{conn: conn} do
1593 user = insert(:user)
1594 other_user = insert(:user)
1595
1596 conn =
1597 conn
1598 |> assign(:user, user)
1599 |> post("/api/v1/accounts/#{other_user.id}/block")
1600
1601 assert %{"id" => _id, "blocking" => true} = json_response(conn, 200)
1602
1603 user = User.get_by_id(user.id)
1604
1605 conn =
1606 build_conn()
1607 |> assign(:user, user)
1608 |> post("/api/v1/accounts/#{other_user.id}/unblock")
1609
1610 assert %{"id" => _id, "blocking" => false} = json_response(conn, 200)
1611 end
1612
1613 test "getting a list of blocks", %{conn: conn} do
1614 user = insert(:user)
1615 other_user = insert(:user)
1616
1617 {:ok, user} = User.block(user, other_user)
1618
1619 conn =
1620 conn
1621 |> assign(:user, user)
1622 |> get("/api/v1/blocks")
1623
1624 other_user_id = to_string(other_user.id)
1625 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
1626 end
1627
1628 test "blocking / unblocking a domain", %{conn: conn} do
1629 user = insert(:user)
1630 other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"})
1631
1632 conn =
1633 conn
1634 |> assign(:user, user)
1635 |> post("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"})
1636
1637 assert %{} = json_response(conn, 200)
1638 user = User.get_cached_by_ap_id(user.ap_id)
1639 assert User.blocks?(user, other_user)
1640
1641 conn =
1642 build_conn()
1643 |> assign(:user, user)
1644 |> delete("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"})
1645
1646 assert %{} = json_response(conn, 200)
1647 user = User.get_cached_by_ap_id(user.ap_id)
1648 refute User.blocks?(user, other_user)
1649 end
1650
1651 test "getting a list of domain blocks", %{conn: conn} do
1652 user = insert(:user)
1653
1654 {:ok, user} = User.block_domain(user, "bad.site")
1655 {:ok, user} = User.block_domain(user, "even.worse.site")
1656
1657 conn =
1658 conn
1659 |> assign(:user, user)
1660 |> get("/api/v1/domain_blocks")
1661
1662 domain_blocks = json_response(conn, 200)
1663
1664 assert "bad.site" in domain_blocks
1665 assert "even.worse.site" in domain_blocks
1666 end
1667
1668 test "unimplemented follow_requests, blocks, domain blocks" do
1669 user = insert(:user)
1670
1671 ["blocks", "domain_blocks", "follow_requests"]
1672 |> Enum.each(fn endpoint ->
1673 conn =
1674 build_conn()
1675 |> assign(:user, user)
1676 |> get("/api/v1/#{endpoint}")
1677
1678 assert [] = json_response(conn, 200)
1679 end)
1680 end
1681
1682 test "account search", %{conn: conn} do
1683 user = insert(:user)
1684 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1685 user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
1686
1687 results =
1688 conn
1689 |> assign(:user, user)
1690 |> get("/api/v1/accounts/search", %{"q" => "shp"})
1691 |> json_response(200)
1692
1693 result_ids = for result <- results, do: result["acct"]
1694
1695 assert user_two.nickname in result_ids
1696 assert user_three.nickname in result_ids
1697
1698 results =
1699 conn
1700 |> assign(:user, user)
1701 |> get("/api/v1/accounts/search", %{"q" => "2hu"})
1702 |> json_response(200)
1703
1704 result_ids = for result <- results, do: result["acct"]
1705
1706 assert user_three.nickname in result_ids
1707 end
1708
1709 test "search", %{conn: conn} do
1710 user = insert(:user)
1711 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1712 user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
1713
1714 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1715
1716 {:ok, _activity} =
1717 CommonAPI.post(user, %{
1718 "status" => "This is about 2hu, but private",
1719 "visibility" => "private"
1720 })
1721
1722 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1723
1724 conn =
1725 conn
1726 |> get("/api/v1/search", %{"q" => "2hu"})
1727
1728 assert results = json_response(conn, 200)
1729
1730 [account | _] = results["accounts"]
1731 assert account["id"] == to_string(user_three.id)
1732
1733 assert results["hashtags"] == []
1734
1735 [status] = results["statuses"]
1736 assert status["id"] == to_string(activity.id)
1737 end
1738
1739 test "search fetches remote statuses", %{conn: conn} do
1740 capture_log(fn ->
1741 conn =
1742 conn
1743 |> get("/api/v1/search", %{"q" => "https://shitposter.club/notice/2827873"})
1744
1745 assert results = json_response(conn, 200)
1746
1747 [status] = results["statuses"]
1748 assert status["uri"] == "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
1749 end)
1750 end
1751
1752 test "search doesn't show statuses that it shouldn't", %{conn: conn} do
1753 {:ok, activity} =
1754 CommonAPI.post(insert(:user), %{
1755 "status" => "This is about 2hu, but private",
1756 "visibility" => "private"
1757 })
1758
1759 capture_log(fn ->
1760 conn =
1761 conn
1762 |> get("/api/v1/search", %{"q" => activity.data["object"]["id"]})
1763
1764 assert results = json_response(conn, 200)
1765
1766 [] = results["statuses"]
1767 end)
1768 end
1769
1770 test "search fetches remote accounts", %{conn: conn} do
1771 conn =
1772 conn
1773 |> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "true"})
1774
1775 assert results = json_response(conn, 200)
1776 [account] = results["accounts"]
1777 assert account["acct"] == "shp@social.heldscal.la"
1778 end
1779
1780 test "returns the favorites of a user", %{conn: conn} do
1781 user = insert(:user)
1782 other_user = insert(:user)
1783
1784 {:ok, _} = CommonAPI.post(other_user, %{"status" => "bla"})
1785 {:ok, activity} = CommonAPI.post(other_user, %{"status" => "traps are happy"})
1786
1787 {:ok, _, _} = CommonAPI.favorite(activity.id, user)
1788
1789 first_conn =
1790 conn
1791 |> assign(:user, user)
1792 |> get("/api/v1/favourites")
1793
1794 assert [status] = json_response(first_conn, 200)
1795 assert status["id"] == to_string(activity.id)
1796
1797 assert [{"link", _link_header}] =
1798 Enum.filter(first_conn.resp_headers, fn element -> match?({"link", _}, element) end)
1799
1800 # Honours query params
1801 {:ok, second_activity} =
1802 CommonAPI.post(other_user, %{
1803 "status" =>
1804 "Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful."
1805 })
1806
1807 {:ok, _, _} = CommonAPI.favorite(second_activity.id, user)
1808
1809 last_like = status["id"]
1810
1811 second_conn =
1812 conn
1813 |> assign(:user, user)
1814 |> get("/api/v1/favourites?since_id=#{last_like}")
1815
1816 assert [second_status] = json_response(second_conn, 200)
1817 assert second_status["id"] == to_string(second_activity.id)
1818
1819 third_conn =
1820 conn
1821 |> assign(:user, user)
1822 |> get("/api/v1/favourites?limit=0")
1823
1824 assert [] = json_response(third_conn, 200)
1825 end
1826
1827 describe "updating credentials" do
1828 test "updates the user's bio", %{conn: conn} do
1829 user = insert(:user)
1830 user2 = insert(:user)
1831
1832 conn =
1833 conn
1834 |> assign(:user, user)
1835 |> patch("/api/v1/accounts/update_credentials", %{
1836 "note" => "I drink #cofe with @#{user2.nickname}"
1837 })
1838
1839 assert user = json_response(conn, 200)
1840
1841 assert user["note"] ==
1842 ~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe" rel="tag">#cofe</a> with <span class="h-card"><a data-user=") <>
1843 user2.id <>
1844 ~s(" class="u-url mention" href=") <>
1845 user2.ap_id <> ~s(">@<span>) <> user2.nickname <> ~s(</span></a></span>)
1846 end
1847
1848 test "updates the user's locking status", %{conn: conn} do
1849 user = insert(:user)
1850
1851 conn =
1852 conn
1853 |> assign(:user, user)
1854 |> patch("/api/v1/accounts/update_credentials", %{locked: "true"})
1855
1856 assert user = json_response(conn, 200)
1857 assert user["locked"] == true
1858 end
1859
1860 test "updates the user's name", %{conn: conn} do
1861 user = insert(:user)
1862
1863 conn =
1864 conn
1865 |> assign(:user, user)
1866 |> patch("/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"})
1867
1868 assert user = json_response(conn, 200)
1869 assert user["display_name"] == "markorepairs"
1870 end
1871
1872 test "updates the user's avatar", %{conn: conn} do
1873 user = insert(:user)
1874
1875 new_avatar = %Plug.Upload{
1876 content_type: "image/jpg",
1877 path: Path.absname("test/fixtures/image.jpg"),
1878 filename: "an_image.jpg"
1879 }
1880
1881 conn =
1882 conn
1883 |> assign(:user, user)
1884 |> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
1885
1886 assert user_response = json_response(conn, 200)
1887 assert user_response["avatar"] != User.avatar_url(user)
1888 end
1889
1890 test "updates the user's banner", %{conn: conn} do
1891 user = insert(:user)
1892
1893 new_header = %Plug.Upload{
1894 content_type: "image/jpg",
1895 path: Path.absname("test/fixtures/image.jpg"),
1896 filename: "an_image.jpg"
1897 }
1898
1899 conn =
1900 conn
1901 |> assign(:user, user)
1902 |> patch("/api/v1/accounts/update_credentials", %{"header" => new_header})
1903
1904 assert user_response = json_response(conn, 200)
1905 assert user_response["header"] != User.banner_url(user)
1906 end
1907
1908 test "requires 'write' permission", %{conn: conn} do
1909 token1 = insert(:oauth_token, scopes: ["read"])
1910 token2 = insert(:oauth_token, scopes: ["write", "follow"])
1911
1912 for token <- [token1, token2] do
1913 conn =
1914 conn
1915 |> put_req_header("authorization", "Bearer #{token.token}")
1916 |> patch("/api/v1/accounts/update_credentials", %{})
1917
1918 if token == token1 do
1919 assert %{"error" => "Insufficient permissions: write."} == json_response(conn, 403)
1920 else
1921 assert json_response(conn, 200)
1922 end
1923 end
1924 end
1925 end
1926
1927 test "get instance information", %{conn: conn} do
1928 conn = get(conn, "/api/v1/instance")
1929 assert result = json_response(conn, 200)
1930
1931 # Note: not checking for "max_toot_chars" since it's optional
1932 assert %{
1933 "uri" => _,
1934 "title" => _,
1935 "description" => _,
1936 "version" => _,
1937 "email" => _,
1938 "urls" => %{
1939 "streaming_api" => _
1940 },
1941 "stats" => _,
1942 "thumbnail" => _,
1943 "languages" => _,
1944 "registrations" => _
1945 } = result
1946 end
1947
1948 test "get instance stats", %{conn: conn} do
1949 user = insert(:user, %{local: true})
1950
1951 user2 = insert(:user, %{local: true})
1952 {:ok, _user2} = User.deactivate(user2, !user2.info.deactivated)
1953
1954 insert(:user, %{local: false, nickname: "u@peer1.com"})
1955 insert(:user, %{local: false, nickname: "u@peer2.com"})
1956
1957 {:ok, _} = TwitterAPI.create_status(user, %{"status" => "cofe"})
1958
1959 # Stats should count users with missing or nil `info.deactivated` value
1960 user = User.get_by_id(user.id)
1961 info_change = Changeset.change(user.info, %{deactivated: nil})
1962
1963 {:ok, _user} =
1964 user
1965 |> Changeset.change()
1966 |> Changeset.put_embed(:info, info_change)
1967 |> User.update_and_set_cache()
1968
1969 Pleroma.Stats.update_stats()
1970
1971 conn = get(conn, "/api/v1/instance")
1972
1973 assert result = json_response(conn, 200)
1974
1975 stats = result["stats"]
1976
1977 assert stats
1978 assert stats["user_count"] == 1
1979 assert stats["status_count"] == 1
1980 assert stats["domain_count"] == 2
1981 end
1982
1983 test "get peers", %{conn: conn} do
1984 insert(:user, %{local: false, nickname: "u@peer1.com"})
1985 insert(:user, %{local: false, nickname: "u@peer2.com"})
1986
1987 Pleroma.Stats.update_stats()
1988
1989 conn = get(conn, "/api/v1/instance/peers")
1990
1991 assert result = json_response(conn, 200)
1992
1993 assert ["peer1.com", "peer2.com"] == Enum.sort(result)
1994 end
1995
1996 test "put settings", %{conn: conn} do
1997 user = insert(:user)
1998
1999 conn =
2000 conn
2001 |> assign(:user, user)
2002 |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}})
2003
2004 assert _result = json_response(conn, 200)
2005
2006 user = User.get_cached_by_ap_id(user.ap_id)
2007 assert user.info.settings == %{"programming" => "socks"}
2008 end
2009
2010 describe "pinned statuses" do
2011 setup do
2012 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
2013
2014 user = insert(:user)
2015 {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"})
2016
2017 [user: user, activity: activity]
2018 end
2019
2020 test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do
2021 {:ok, _} = CommonAPI.pin(activity.id, user)
2022
2023 result =
2024 conn
2025 |> assign(:user, user)
2026 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
2027 |> json_response(200)
2028
2029 id_str = to_string(activity.id)
2030
2031 assert [%{"id" => ^id_str, "pinned" => true}] = result
2032 end
2033
2034 test "pin status", %{conn: conn, user: user, activity: activity} do
2035 id_str = to_string(activity.id)
2036
2037 assert %{"id" => ^id_str, "pinned" => true} =
2038 conn
2039 |> assign(:user, user)
2040 |> post("/api/v1/statuses/#{activity.id}/pin")
2041 |> json_response(200)
2042
2043 assert [%{"id" => ^id_str, "pinned" => true}] =
2044 conn
2045 |> assign(:user, user)
2046 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
2047 |> json_response(200)
2048 end
2049
2050 test "unpin status", %{conn: conn, user: user, activity: activity} do
2051 {:ok, _} = CommonAPI.pin(activity.id, user)
2052
2053 id_str = to_string(activity.id)
2054 user = refresh_record(user)
2055
2056 assert %{"id" => ^id_str, "pinned" => false} =
2057 conn
2058 |> assign(:user, user)
2059 |> post("/api/v1/statuses/#{activity.id}/unpin")
2060 |> json_response(200)
2061
2062 assert [] =
2063 conn
2064 |> assign(:user, user)
2065 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
2066 |> json_response(200)
2067 end
2068
2069 test "max pinned statuses", %{conn: conn, user: user, activity: activity_one} do
2070 {:ok, activity_two} = CommonAPI.post(user, %{"status" => "HI!!!"})
2071
2072 id_str_one = to_string(activity_one.id)
2073
2074 assert %{"id" => ^id_str_one, "pinned" => true} =
2075 conn
2076 |> assign(:user, user)
2077 |> post("/api/v1/statuses/#{id_str_one}/pin")
2078 |> json_response(200)
2079
2080 user = refresh_record(user)
2081
2082 assert %{"error" => "You have already pinned the maximum number of statuses"} =
2083 conn
2084 |> assign(:user, user)
2085 |> post("/api/v1/statuses/#{activity_two.id}/pin")
2086 |> json_response(400)
2087 end
2088
2089 test "Status rich-media Card", %{conn: conn, user: user} do
2090 Pleroma.Config.put([:rich_media, :enabled], true)
2091 {:ok, activity} = CommonAPI.post(user, %{"status" => "http://example.com/ogp"})
2092
2093 response =
2094 conn
2095 |> get("/api/v1/statuses/#{activity.id}/card")
2096 |> json_response(200)
2097
2098 assert response == %{
2099 "image" => "http://ia.media-imdb.com/images/rock.jpg",
2100 "provider_name" => "www.imdb.com",
2101 "provider_url" => "http://www.imdb.com",
2102 "title" => "The Rock",
2103 "type" => "link",
2104 "url" => "http://www.imdb.com/title/tt0117500/",
2105 "description" => nil,
2106 "pleroma" => %{
2107 "opengraph" => %{
2108 "image" => "http://ia.media-imdb.com/images/rock.jpg",
2109 "title" => "The Rock",
2110 "type" => "video.movie",
2111 "url" => "http://www.imdb.com/title/tt0117500/"
2112 }
2113 }
2114 }
2115
2116 # works with private posts
2117 {:ok, activity} =
2118 CommonAPI.post(user, %{"status" => "http://example.com/ogp", "visibility" => "direct"})
2119
2120 response_two =
2121 conn
2122 |> assign(:user, user)
2123 |> get("/api/v1/statuses/#{activity.id}/card")
2124 |> json_response(200)
2125
2126 assert response_two == response
2127
2128 Pleroma.Config.put([:rich_media, :enabled], false)
2129 end
2130 end
2131
2132 test "bookmarks" do
2133 user = insert(:user)
2134 for_user = insert(:user)
2135
2136 {:ok, activity1} =
2137 CommonAPI.post(user, %{
2138 "status" => "heweoo?"
2139 })
2140
2141 {:ok, activity2} =
2142 CommonAPI.post(user, %{
2143 "status" => "heweoo!"
2144 })
2145
2146 response1 =
2147 build_conn()
2148 |> assign(:user, for_user)
2149 |> post("/api/v1/statuses/#{activity1.id}/bookmark")
2150
2151 assert json_response(response1, 200)["bookmarked"] == true
2152
2153 response2 =
2154 build_conn()
2155 |> assign(:user, for_user)
2156 |> post("/api/v1/statuses/#{activity2.id}/bookmark")
2157
2158 assert json_response(response2, 200)["bookmarked"] == true
2159
2160 bookmarks =
2161 build_conn()
2162 |> assign(:user, for_user)
2163 |> get("/api/v1/bookmarks")
2164
2165 assert [json_response(response2, 200), json_response(response1, 200)] ==
2166 json_response(bookmarks, 200)
2167
2168 response1 =
2169 build_conn()
2170 |> assign(:user, for_user)
2171 |> post("/api/v1/statuses/#{activity1.id}/unbookmark")
2172
2173 assert json_response(response1, 200)["bookmarked"] == false
2174
2175 bookmarks =
2176 build_conn()
2177 |> assign(:user, for_user)
2178 |> get("/api/v1/bookmarks")
2179
2180 assert [json_response(response2, 200)] == json_response(bookmarks, 200)
2181 end
2182
2183 describe "conversation muting" do
2184 setup do
2185 user = insert(:user)
2186 {:ok, activity} = CommonAPI.post(user, %{"status" => "HIE"})
2187
2188 [user: user, activity: activity]
2189 end
2190
2191 test "mute conversation", %{conn: conn, user: user, activity: activity} do
2192 id_str = to_string(activity.id)
2193
2194 assert %{"id" => ^id_str, "muted" => true} =
2195 conn
2196 |> assign(:user, user)
2197 |> post("/api/v1/statuses/#{activity.id}/mute")
2198 |> json_response(200)
2199 end
2200
2201 test "unmute conversation", %{conn: conn, user: user, activity: activity} do
2202 {:ok, _} = CommonAPI.add_mute(user, activity)
2203
2204 id_str = to_string(activity.id)
2205 user = refresh_record(user)
2206
2207 assert %{"id" => ^id_str, "muted" => false} =
2208 conn
2209 |> assign(:user, user)
2210 |> post("/api/v1/statuses/#{activity.id}/unmute")
2211 |> json_response(200)
2212 end
2213 end
2214
2215 test "flavours switching (Pleroma Extension)", %{conn: conn} do
2216 user = insert(:user)
2217
2218 get_old_flavour =
2219 conn
2220 |> assign(:user, user)
2221 |> get("/api/v1/pleroma/flavour")
2222
2223 assert "glitch" == json_response(get_old_flavour, 200)
2224
2225 set_flavour =
2226 conn
2227 |> assign(:user, user)
2228 |> post("/api/v1/pleroma/flavour/vanilla")
2229
2230 assert "vanilla" == json_response(set_flavour, 200)
2231
2232 get_new_flavour =
2233 conn
2234 |> assign(:user, user)
2235 |> post("/api/v1/pleroma/flavour/vanilla")
2236
2237 assert json_response(set_flavour, 200) == json_response(get_new_flavour, 200)
2238 end
2239
2240 describe "reports" do
2241 setup do
2242 reporter = insert(:user)
2243 target_user = insert(:user)
2244
2245 {:ok, activity} = CommonAPI.post(target_user, %{"status" => "foobar"})
2246
2247 [reporter: reporter, target_user: target_user, activity: activity]
2248 end
2249
2250 test "submit a basic report", %{conn: conn, reporter: reporter, target_user: target_user} do
2251 assert %{"action_taken" => false, "id" => _} =
2252 conn
2253 |> assign(:user, reporter)
2254 |> post("/api/v1/reports", %{"account_id" => target_user.id})
2255 |> json_response(200)
2256 end
2257
2258 test "submit a report with statuses and comment", %{
2259 conn: conn,
2260 reporter: reporter,
2261 target_user: target_user,
2262 activity: activity
2263 } do
2264 assert %{"action_taken" => false, "id" => _} =
2265 conn
2266 |> assign(:user, reporter)
2267 |> post("/api/v1/reports", %{
2268 "account_id" => target_user.id,
2269 "status_ids" => [activity.id],
2270 "comment" => "bad status!"
2271 })
2272 |> json_response(200)
2273 end
2274
2275 test "account_id is required", %{
2276 conn: conn,
2277 reporter: reporter,
2278 activity: activity
2279 } do
2280 assert %{"error" => "Valid `account_id` required"} =
2281 conn
2282 |> assign(:user, reporter)
2283 |> post("/api/v1/reports", %{"status_ids" => [activity.id]})
2284 |> json_response(400)
2285 end
2286
2287 test "comment must be up to the size specified in the config", %{
2288 conn: conn,
2289 reporter: reporter,
2290 target_user: target_user
2291 } do
2292 max_size = Pleroma.Config.get([:instance, :max_report_comment_size], 1000)
2293 comment = String.pad_trailing("a", max_size + 1, "a")
2294
2295 error = %{"error" => "Comment must be up to #{max_size} characters"}
2296
2297 assert ^error =
2298 conn
2299 |> assign(:user, reporter)
2300 |> post("/api/v1/reports", %{"account_id" => target_user.id, "comment" => comment})
2301 |> json_response(400)
2302 end
2303 end
2304
2305 describe "link headers" do
2306 test "preserves parameters in link headers", %{conn: conn} do
2307 user = insert(:user)
2308 other_user = insert(:user)
2309
2310 {:ok, activity1} =
2311 CommonAPI.post(other_user, %{
2312 "status" => "hi @#{user.nickname}",
2313 "visibility" => "public"
2314 })
2315
2316 {:ok, activity2} =
2317 CommonAPI.post(other_user, %{
2318 "status" => "hi @#{user.nickname}",
2319 "visibility" => "public"
2320 })
2321
2322 notification1 = Repo.get_by(Notification, activity_id: activity1.id)
2323 notification2 = Repo.get_by(Notification, activity_id: activity2.id)
2324
2325 conn =
2326 conn
2327 |> assign(:user, user)
2328 |> get("/api/v1/notifications", %{media_only: true})
2329
2330 assert [link_header] = get_resp_header(conn, "link")
2331 assert link_header =~ ~r/media_only=true/
2332 assert link_header =~ ~r/since_id=#{notification2.id}/
2333 assert link_header =~ ~r/max_id=#{notification1.id}/
2334 end
2335 end
2336
2337 test "accounts fetches correct account for nicknames beginning with numbers", %{conn: conn} do
2338 # Need to set an old-style integer ID to reproduce the problem
2339 # (these are no longer assigned to new accounts but were preserved
2340 # for existing accounts during the migration to flakeIDs)
2341 user_one = insert(:user, %{id: 1212})
2342 user_two = insert(:user, %{nickname: "#{user_one.id}garbage"})
2343
2344 resp_one =
2345 conn
2346 |> get("/api/v1/accounts/#{user_one.id}")
2347
2348 resp_two =
2349 conn
2350 |> get("/api/v1/accounts/#{user_two.nickname}")
2351
2352 resp_three =
2353 conn
2354 |> get("/api/v1/accounts/#{user_two.id}")
2355
2356 acc_one = json_response(resp_one, 200)
2357 acc_two = json_response(resp_two, 200)
2358 acc_three = json_response(resp_three, 200)
2359 refute acc_one == acc_two
2360 assert acc_two == acc_three
2361 end
2362 end