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