Merge branch 'feature/add-pagination-to-users-admin-api' 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
950 conn =
951 build_conn()
952 |> assign(:user, user)
953 |> post("/api/v1/follow_requests/#{other_user.id}/authorize")
954
955 assert relationship = json_response(conn, 200)
956 assert to_string(other_user.id) == relationship["id"]
957
958 user = Repo.get(User, user.id)
959 other_user = Repo.get(User, other_user.id)
960
961 assert User.following?(other_user, user) == true
962 end
963
964 test "verify_credentials", %{conn: conn} do
965 user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "private"}})
966
967 conn =
968 conn
969 |> assign(:user, user)
970 |> get("/api/v1/accounts/verify_credentials")
971
972 assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
973 assert id == to_string(user.id)
974 end
975
976 test "/api/v1/follow_requests/:id/reject works" do
977 user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
978 other_user = insert(:user)
979
980 {:ok, _activity} = ActivityPub.follow(other_user, user)
981
982 user = Repo.get(User, user.id)
983
984 conn =
985 build_conn()
986 |> assign(:user, user)
987 |> post("/api/v1/follow_requests/#{other_user.id}/reject")
988
989 assert relationship = json_response(conn, 200)
990 assert to_string(other_user.id) == relationship["id"]
991
992 user = Repo.get(User, user.id)
993 other_user = Repo.get(User, other_user.id)
994
995 assert User.following?(other_user, user) == false
996 end
997 end
998
999 test "account fetching", %{conn: conn} do
1000 user = insert(:user)
1001
1002 conn =
1003 conn
1004 |> get("/api/v1/accounts/#{user.id}")
1005
1006 assert %{"id" => id} = json_response(conn, 200)
1007 assert id == to_string(user.id)
1008
1009 conn =
1010 build_conn()
1011 |> get("/api/v1/accounts/-1")
1012
1013 assert %{"error" => "Can't find user"} = json_response(conn, 404)
1014 end
1015
1016 test "media upload", %{conn: conn} do
1017 file = %Plug.Upload{
1018 content_type: "image/jpg",
1019 path: Path.absname("test/fixtures/image.jpg"),
1020 filename: "an_image.jpg"
1021 }
1022
1023 desc = "Description of the image"
1024
1025 user = insert(:user)
1026
1027 conn =
1028 conn
1029 |> assign(:user, user)
1030 |> post("/api/v1/media", %{"file" => file, "description" => desc})
1031
1032 assert media = json_response(conn, 200)
1033
1034 assert media["type"] == "image"
1035 assert media["description"] == desc
1036 assert media["id"]
1037
1038 object = Repo.get(Object, media["id"])
1039 assert object.data["actor"] == User.ap_id(user)
1040 end
1041
1042 test "hashtag timeline", %{conn: conn} do
1043 following = insert(:user)
1044
1045 capture_log(fn ->
1046 {:ok, activity} = TwitterAPI.create_status(following, %{"status" => "test #2hu"})
1047
1048 {:ok, [_activity]} =
1049 OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873")
1050
1051 nconn =
1052 conn
1053 |> get("/api/v1/timelines/tag/2hu")
1054
1055 assert [%{"id" => id}] = json_response(nconn, 200)
1056
1057 assert id == to_string(activity.id)
1058
1059 # works for different capitalization too
1060 nconn =
1061 conn
1062 |> get("/api/v1/timelines/tag/2HU")
1063
1064 assert [%{"id" => id}] = json_response(nconn, 200)
1065
1066 assert id == to_string(activity.id)
1067 end)
1068 end
1069
1070 test "multi-hashtag timeline", %{conn: conn} do
1071 user = insert(:user)
1072
1073 {:ok, activity_test} = CommonAPI.post(user, %{"status" => "#test"})
1074 {:ok, activity_test1} = CommonAPI.post(user, %{"status" => "#test #test1"})
1075 {:ok, activity_none} = CommonAPI.post(user, %{"status" => "#test #none"})
1076
1077 any_test =
1078 conn
1079 |> get("/api/v1/timelines/tag/test", %{"any" => ["test1"]})
1080
1081 [status_none, status_test1, status_test] = json_response(any_test, 200)
1082
1083 assert to_string(activity_test.id) == status_test["id"]
1084 assert to_string(activity_test1.id) == status_test1["id"]
1085 assert to_string(activity_none.id) == status_none["id"]
1086
1087 restricted_test =
1088 conn
1089 |> get("/api/v1/timelines/tag/test", %{"all" => ["test1"], "none" => ["none"]})
1090
1091 assert [status_test1] == json_response(restricted_test, 200)
1092
1093 all_test = conn |> get("/api/v1/timelines/tag/test", %{"all" => ["none"]})
1094
1095 assert [status_none] == json_response(all_test, 200)
1096 end
1097
1098 test "getting followers", %{conn: conn} do
1099 user = insert(:user)
1100 other_user = insert(:user)
1101 {:ok, user} = User.follow(user, other_user)
1102
1103 conn =
1104 conn
1105 |> get("/api/v1/accounts/#{other_user.id}/followers")
1106
1107 assert [%{"id" => id}] = json_response(conn, 200)
1108 assert id == to_string(user.id)
1109 end
1110
1111 test "getting followers, hide_followers", %{conn: conn} do
1112 user = insert(:user)
1113 other_user = insert(:user, %{info: %{hide_followers: true}})
1114 {:ok, _user} = User.follow(user, other_user)
1115
1116 conn =
1117 conn
1118 |> get("/api/v1/accounts/#{other_user.id}/followers")
1119
1120 assert [] == json_response(conn, 200)
1121 end
1122
1123 test "getting followers, hide_followers, same user requesting", %{conn: conn} do
1124 user = insert(:user)
1125 other_user = insert(:user, %{info: %{hide_followers: true}})
1126 {:ok, _user} = User.follow(user, other_user)
1127
1128 conn =
1129 conn
1130 |> assign(:user, other_user)
1131 |> get("/api/v1/accounts/#{other_user.id}/followers")
1132
1133 refute [] == json_response(conn, 200)
1134 end
1135
1136 test "getting following", %{conn: conn} do
1137 user = insert(:user)
1138 other_user = insert(:user)
1139 {:ok, user} = User.follow(user, other_user)
1140
1141 conn =
1142 conn
1143 |> get("/api/v1/accounts/#{user.id}/following")
1144
1145 assert [%{"id" => id}] = json_response(conn, 200)
1146 assert id == to_string(other_user.id)
1147 end
1148
1149 test "getting following, hide_follows", %{conn: conn} do
1150 user = insert(:user, %{info: %{hide_follows: true}})
1151 other_user = insert(:user)
1152 {:ok, user} = User.follow(user, other_user)
1153
1154 conn =
1155 conn
1156 |> get("/api/v1/accounts/#{user.id}/following")
1157
1158 assert [] == json_response(conn, 200)
1159 end
1160
1161 test "getting following, hide_follows, same user requesting", %{conn: conn} do
1162 user = insert(:user, %{info: %{hide_follows: true}})
1163 other_user = insert(:user)
1164 {:ok, user} = User.follow(user, other_user)
1165
1166 conn =
1167 conn
1168 |> assign(:user, user)
1169 |> get("/api/v1/accounts/#{user.id}/following")
1170
1171 refute [] == json_response(conn, 200)
1172 end
1173
1174 test "following / unfollowing a user", %{conn: conn} do
1175 user = insert(:user)
1176 other_user = insert(:user)
1177
1178 conn =
1179 conn
1180 |> assign(:user, user)
1181 |> post("/api/v1/accounts/#{other_user.id}/follow")
1182
1183 assert %{"id" => _id, "following" => true} = json_response(conn, 200)
1184
1185 user = Repo.get(User, user.id)
1186
1187 conn =
1188 build_conn()
1189 |> assign(:user, user)
1190 |> post("/api/v1/accounts/#{other_user.id}/unfollow")
1191
1192 assert %{"id" => _id, "following" => false} = json_response(conn, 200)
1193
1194 user = Repo.get(User, user.id)
1195
1196 conn =
1197 build_conn()
1198 |> assign(:user, user)
1199 |> post("/api/v1/follows", %{"uri" => other_user.nickname})
1200
1201 assert %{"id" => id} = json_response(conn, 200)
1202 assert id == to_string(other_user.id)
1203 end
1204
1205 test "muting / unmuting a user", %{conn: conn} do
1206 user = insert(:user)
1207 other_user = insert(:user)
1208
1209 conn =
1210 conn
1211 |> assign(:user, user)
1212 |> post("/api/v1/accounts/#{other_user.id}/mute")
1213
1214 assert %{"id" => _id, "muting" => true} = json_response(conn, 200)
1215
1216 user = Repo.get(User, user.id)
1217
1218 conn =
1219 build_conn()
1220 |> assign(:user, user)
1221 |> post("/api/v1/accounts/#{other_user.id}/unmute")
1222
1223 assert %{"id" => _id, "muting" => false} = json_response(conn, 200)
1224 end
1225
1226 test "getting a list of mutes", %{conn: conn} do
1227 user = insert(:user)
1228 other_user = insert(:user)
1229
1230 {:ok, user} = User.mute(user, other_user)
1231
1232 conn =
1233 conn
1234 |> assign(:user, user)
1235 |> get("/api/v1/mutes")
1236
1237 other_user_id = to_string(other_user.id)
1238 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
1239 end
1240
1241 test "blocking / unblocking a user", %{conn: conn} do
1242 user = insert(:user)
1243 other_user = insert(:user)
1244
1245 conn =
1246 conn
1247 |> assign(:user, user)
1248 |> post("/api/v1/accounts/#{other_user.id}/block")
1249
1250 assert %{"id" => _id, "blocking" => true} = json_response(conn, 200)
1251
1252 user = Repo.get(User, user.id)
1253
1254 conn =
1255 build_conn()
1256 |> assign(:user, user)
1257 |> post("/api/v1/accounts/#{other_user.id}/unblock")
1258
1259 assert %{"id" => _id, "blocking" => false} = json_response(conn, 200)
1260 end
1261
1262 test "getting a list of blocks", %{conn: conn} do
1263 user = insert(:user)
1264 other_user = insert(:user)
1265
1266 {:ok, user} = User.block(user, other_user)
1267
1268 conn =
1269 conn
1270 |> assign(:user, user)
1271 |> get("/api/v1/blocks")
1272
1273 other_user_id = to_string(other_user.id)
1274 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
1275 end
1276
1277 test "blocking / unblocking a domain", %{conn: conn} do
1278 user = insert(:user)
1279 other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"})
1280
1281 conn =
1282 conn
1283 |> assign(:user, user)
1284 |> post("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"})
1285
1286 assert %{} = json_response(conn, 200)
1287 user = User.get_cached_by_ap_id(user.ap_id)
1288 assert User.blocks?(user, other_user)
1289
1290 conn =
1291 build_conn()
1292 |> assign(:user, user)
1293 |> delete("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"})
1294
1295 assert %{} = json_response(conn, 200)
1296 user = User.get_cached_by_ap_id(user.ap_id)
1297 refute User.blocks?(user, other_user)
1298 end
1299
1300 test "getting a list of domain blocks", %{conn: conn} do
1301 user = insert(:user)
1302
1303 {:ok, user} = User.block_domain(user, "bad.site")
1304 {:ok, user} = User.block_domain(user, "even.worse.site")
1305
1306 conn =
1307 conn
1308 |> assign(:user, user)
1309 |> get("/api/v1/domain_blocks")
1310
1311 domain_blocks = json_response(conn, 200)
1312
1313 assert "bad.site" in domain_blocks
1314 assert "even.worse.site" in domain_blocks
1315 end
1316
1317 test "unimplemented follow_requests, blocks, domain blocks" do
1318 user = insert(:user)
1319
1320 ["blocks", "domain_blocks", "follow_requests"]
1321 |> Enum.each(fn endpoint ->
1322 conn =
1323 build_conn()
1324 |> assign(:user, user)
1325 |> get("/api/v1/#{endpoint}")
1326
1327 assert [] = json_response(conn, 200)
1328 end)
1329 end
1330
1331 test "account search", %{conn: conn} do
1332 user = insert(:user)
1333 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1334 user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
1335
1336 results =
1337 conn
1338 |> assign(:user, user)
1339 |> get("/api/v1/accounts/search", %{"q" => "shp"})
1340 |> json_response(200)
1341
1342 result_ids = for result <- results, do: result["acct"]
1343
1344 assert user_two.nickname in result_ids
1345 assert user_three.nickname in result_ids
1346
1347 results =
1348 conn
1349 |> assign(:user, user)
1350 |> get("/api/v1/accounts/search", %{"q" => "2hu"})
1351 |> json_response(200)
1352
1353 result_ids = for result <- results, do: result["acct"]
1354
1355 assert user_three.nickname in result_ids
1356 end
1357
1358 test "search", %{conn: conn} do
1359 user = insert(:user)
1360 user_two = insert(:user, %{nickname: "shp@shitposter.club"})
1361 user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
1362
1363 {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
1364
1365 {:ok, _activity} =
1366 CommonAPI.post(user, %{
1367 "status" => "This is about 2hu, but private",
1368 "visibility" => "private"
1369 })
1370
1371 {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
1372
1373 conn =
1374 conn
1375 |> get("/api/v1/search", %{"q" => "2hu"})
1376
1377 assert results = json_response(conn, 200)
1378
1379 [account | _] = results["accounts"]
1380 assert account["id"] == to_string(user_three.id)
1381
1382 assert results["hashtags"] == []
1383
1384 [status] = results["statuses"]
1385 assert status["id"] == to_string(activity.id)
1386 end
1387
1388 test "search fetches remote statuses", %{conn: conn} do
1389 capture_log(fn ->
1390 conn =
1391 conn
1392 |> get("/api/v1/search", %{"q" => "https://shitposter.club/notice/2827873"})
1393
1394 assert results = json_response(conn, 200)
1395
1396 [status] = results["statuses"]
1397 assert status["uri"] == "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
1398 end)
1399 end
1400
1401 test "search doesn't show statuses that it shouldn't", %{conn: conn} do
1402 {:ok, activity} =
1403 CommonAPI.post(insert(:user), %{
1404 "status" => "This is about 2hu, but private",
1405 "visibility" => "private"
1406 })
1407
1408 capture_log(fn ->
1409 conn =
1410 conn
1411 |> get("/api/v1/search", %{"q" => activity.data["object"]["id"]})
1412
1413 assert results = json_response(conn, 200)
1414
1415 [] = results["statuses"]
1416 end)
1417 end
1418
1419 test "search fetches remote accounts", %{conn: conn} do
1420 conn =
1421 conn
1422 |> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "true"})
1423
1424 assert results = json_response(conn, 200)
1425 [account] = results["accounts"]
1426 assert account["acct"] == "shp@social.heldscal.la"
1427 end
1428
1429 test "returns the favorites of a user", %{conn: conn} do
1430 user = insert(:user)
1431 other_user = insert(:user)
1432
1433 {:ok, _} = CommonAPI.post(other_user, %{"status" => "bla"})
1434 {:ok, activity} = CommonAPI.post(other_user, %{"status" => "traps are happy"})
1435
1436 {:ok, _, _} = CommonAPI.favorite(activity.id, user)
1437
1438 first_conn =
1439 conn
1440 |> assign(:user, user)
1441 |> get("/api/v1/favourites")
1442
1443 assert [status] = json_response(first_conn, 200)
1444 assert status["id"] == to_string(activity.id)
1445
1446 assert [{"link", _link_header}] =
1447 Enum.filter(first_conn.resp_headers, fn element -> match?({"link", _}, element) end)
1448
1449 # Honours query params
1450 {:ok, second_activity} =
1451 CommonAPI.post(other_user, %{
1452 "status" =>
1453 "Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful."
1454 })
1455
1456 {:ok, _, _} = CommonAPI.favorite(second_activity.id, user)
1457
1458 last_like = status["id"]
1459
1460 second_conn =
1461 conn
1462 |> assign(:user, user)
1463 |> get("/api/v1/favourites?since_id=#{last_like}")
1464
1465 assert [second_status] = json_response(second_conn, 200)
1466 assert second_status["id"] == to_string(second_activity.id)
1467
1468 third_conn =
1469 conn
1470 |> assign(:user, user)
1471 |> get("/api/v1/favourites?limit=0")
1472
1473 assert [] = json_response(third_conn, 200)
1474 end
1475
1476 describe "updating credentials" do
1477 test "updates the user's bio", %{conn: conn} do
1478 user = insert(:user)
1479 user2 = insert(:user)
1480
1481 conn =
1482 conn
1483 |> assign(:user, user)
1484 |> patch("/api/v1/accounts/update_credentials", %{
1485 "note" => "I drink #cofe with @#{user2.nickname}"
1486 })
1487
1488 assert user = json_response(conn, 200)
1489
1490 assert user["note"] ==
1491 "I drink <a class=\"hashtag\" data-tag=\"cofe\" href=\"http://localhost:4001/tag/cofe\">#cofe</a> with <span class=\"h-card\"><a data-user=\"#{
1492 user2.id
1493 }\" class=\"u-url mention\" href=\"#{user2.ap_id}\">@<span>#{user2.nickname}</span></a></span>"
1494 end
1495
1496 test "updates the user's locking status", %{conn: conn} do
1497 user = insert(:user)
1498
1499 conn =
1500 conn
1501 |> assign(:user, user)
1502 |> patch("/api/v1/accounts/update_credentials", %{locked: "true"})
1503
1504 assert user = json_response(conn, 200)
1505 assert user["locked"] == true
1506 end
1507
1508 test "updates the user's name", %{conn: conn} do
1509 user = insert(:user)
1510
1511 conn =
1512 conn
1513 |> assign(:user, user)
1514 |> patch("/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"})
1515
1516 assert user = json_response(conn, 200)
1517 assert user["display_name"] == "markorepairs"
1518 end
1519
1520 test "updates the user's avatar", %{conn: conn} do
1521 user = insert(:user)
1522
1523 new_avatar = %Plug.Upload{
1524 content_type: "image/jpg",
1525 path: Path.absname("test/fixtures/image.jpg"),
1526 filename: "an_image.jpg"
1527 }
1528
1529 conn =
1530 conn
1531 |> assign(:user, user)
1532 |> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
1533
1534 assert user_response = json_response(conn, 200)
1535 assert user_response["avatar"] != User.avatar_url(user)
1536 end
1537
1538 test "updates the user's banner", %{conn: conn} do
1539 user = insert(:user)
1540
1541 new_header = %Plug.Upload{
1542 content_type: "image/jpg",
1543 path: Path.absname("test/fixtures/image.jpg"),
1544 filename: "an_image.jpg"
1545 }
1546
1547 conn =
1548 conn
1549 |> assign(:user, user)
1550 |> patch("/api/v1/accounts/update_credentials", %{"header" => new_header})
1551
1552 assert user_response = json_response(conn, 200)
1553 assert user_response["header"] != User.banner_url(user)
1554 end
1555
1556 test "requires 'write' permission", %{conn: conn} do
1557 token1 = insert(:oauth_token, scopes: ["read"])
1558 token2 = insert(:oauth_token, scopes: ["write", "follow"])
1559
1560 for token <- [token1, token2] do
1561 conn =
1562 conn
1563 |> put_req_header("authorization", "Bearer #{token.token}")
1564 |> patch("/api/v1/accounts/update_credentials", %{})
1565
1566 if token == token1 do
1567 assert %{"error" => "Insufficient permissions: write."} == json_response(conn, 403)
1568 else
1569 assert json_response(conn, 200)
1570 end
1571 end
1572 end
1573 end
1574
1575 test "get instance information", %{conn: conn} do
1576 user = insert(:user, %{local: true})
1577
1578 user2 = insert(:user, %{local: true})
1579 {:ok, _user2} = User.deactivate(user2, !user2.info.deactivated)
1580
1581 insert(:user, %{local: false, nickname: "u@peer1.com"})
1582 insert(:user, %{local: false, nickname: "u@peer2.com"})
1583
1584 {:ok, _} = TwitterAPI.create_status(user, %{"status" => "cofe"})
1585
1586 # Stats should count users with missing or nil `info.deactivated` value
1587 user = Repo.get(User, user.id)
1588 info_change = Changeset.change(user.info, %{deactivated: nil})
1589
1590 {:ok, _user} =
1591 user
1592 |> Changeset.change()
1593 |> Changeset.put_embed(:info, info_change)
1594 |> User.update_and_set_cache()
1595
1596 Pleroma.Stats.update_stats()
1597
1598 conn = get(conn, "/api/v1/instance")
1599
1600 assert result = json_response(conn, 200)
1601
1602 stats = result["stats"]
1603
1604 assert stats
1605 assert stats["user_count"] == 1
1606 assert stats["status_count"] == 1
1607 assert stats["domain_count"] == 2
1608 end
1609
1610 test "get peers", %{conn: conn} do
1611 insert(:user, %{local: false, nickname: "u@peer1.com"})
1612 insert(:user, %{local: false, nickname: "u@peer2.com"})
1613
1614 Pleroma.Stats.update_stats()
1615
1616 conn = get(conn, "/api/v1/instance/peers")
1617
1618 assert result = json_response(conn, 200)
1619
1620 assert ["peer1.com", "peer2.com"] == Enum.sort(result)
1621 end
1622
1623 test "put settings", %{conn: conn} do
1624 user = insert(:user)
1625
1626 conn =
1627 conn
1628 |> assign(:user, user)
1629 |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}})
1630
1631 assert _result = json_response(conn, 200)
1632
1633 user = User.get_cached_by_ap_id(user.ap_id)
1634 assert user.info.settings == %{"programming" => "socks"}
1635 end
1636
1637 describe "pinned statuses" do
1638 setup do
1639 Pleroma.Config.put([:instance, :max_pinned_statuses], 1)
1640
1641 user = insert(:user)
1642 {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"})
1643
1644 [user: user, activity: activity]
1645 end
1646
1647 test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do
1648 {:ok, _} = CommonAPI.pin(activity.id, user)
1649
1650 result =
1651 conn
1652 |> assign(:user, user)
1653 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
1654 |> json_response(200)
1655
1656 id_str = to_string(activity.id)
1657
1658 assert [%{"id" => ^id_str, "pinned" => true}] = result
1659 end
1660
1661 test "pin status", %{conn: conn, user: user, activity: activity} do
1662 id_str = to_string(activity.id)
1663
1664 assert %{"id" => ^id_str, "pinned" => true} =
1665 conn
1666 |> assign(:user, user)
1667 |> post("/api/v1/statuses/#{activity.id}/pin")
1668 |> json_response(200)
1669
1670 assert [%{"id" => ^id_str, "pinned" => true}] =
1671 conn
1672 |> assign(:user, user)
1673 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
1674 |> json_response(200)
1675 end
1676
1677 test "unpin status", %{conn: conn, user: user, activity: activity} do
1678 {:ok, _} = CommonAPI.pin(activity.id, user)
1679
1680 id_str = to_string(activity.id)
1681 user = refresh_record(user)
1682
1683 assert %{"id" => ^id_str, "pinned" => false} =
1684 conn
1685 |> assign(:user, user)
1686 |> post("/api/v1/statuses/#{activity.id}/unpin")
1687 |> json_response(200)
1688
1689 assert [] =
1690 conn
1691 |> assign(:user, user)
1692 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
1693 |> json_response(200)
1694 end
1695
1696 test "max pinned statuses", %{conn: conn, user: user, activity: activity_one} do
1697 {:ok, activity_two} = CommonAPI.post(user, %{"status" => "HI!!!"})
1698
1699 id_str_one = to_string(activity_one.id)
1700
1701 assert %{"id" => ^id_str_one, "pinned" => true} =
1702 conn
1703 |> assign(:user, user)
1704 |> post("/api/v1/statuses/#{id_str_one}/pin")
1705 |> json_response(200)
1706
1707 user = refresh_record(user)
1708
1709 assert %{"error" => "You have already pinned the maximum number of statuses"} =
1710 conn
1711 |> assign(:user, user)
1712 |> post("/api/v1/statuses/#{activity_two.id}/pin")
1713 |> json_response(400)
1714 end
1715
1716 test "Status rich-media Card", %{conn: conn, user: user} do
1717 Pleroma.Config.put([:rich_media, :enabled], true)
1718 {:ok, activity} = CommonAPI.post(user, %{"status" => "http://example.com/ogp"})
1719
1720 response =
1721 conn
1722 |> get("/api/v1/statuses/#{activity.id}/card")
1723 |> json_response(200)
1724
1725 assert response == %{
1726 "image" => "http://ia.media-imdb.com/images/rock.jpg",
1727 "provider_name" => "www.imdb.com",
1728 "provider_url" => "http://www.imdb.com",
1729 "title" => "The Rock",
1730 "type" => "link",
1731 "url" => "http://www.imdb.com/title/tt0117500/",
1732 "description" => nil,
1733 "pleroma" => %{
1734 "opengraph" => %{
1735 "image" => "http://ia.media-imdb.com/images/rock.jpg",
1736 "title" => "The Rock",
1737 "type" => "video.movie",
1738 "url" => "http://www.imdb.com/title/tt0117500/"
1739 }
1740 }
1741 }
1742
1743 # works with private posts
1744 {:ok, activity} =
1745 CommonAPI.post(user, %{"status" => "http://example.com/ogp", "visibility" => "direct"})
1746
1747 response_two =
1748 conn
1749 |> assign(:user, user)
1750 |> get("/api/v1/statuses/#{activity.id}/card")
1751 |> json_response(200)
1752
1753 assert response_two == response
1754
1755 Pleroma.Config.put([:rich_media, :enabled], false)
1756 end
1757 end
1758
1759 test "bookmarks" do
1760 user = insert(:user)
1761 for_user = insert(:user)
1762
1763 {:ok, activity1} =
1764 CommonAPI.post(user, %{
1765 "status" => "heweoo?"
1766 })
1767
1768 {:ok, activity2} =
1769 CommonAPI.post(user, %{
1770 "status" => "heweoo!"
1771 })
1772
1773 response1 =
1774 build_conn()
1775 |> assign(:user, for_user)
1776 |> post("/api/v1/statuses/#{activity1.id}/bookmark")
1777
1778 assert json_response(response1, 200)["bookmarked"] == true
1779
1780 response2 =
1781 build_conn()
1782 |> assign(:user, for_user)
1783 |> post("/api/v1/statuses/#{activity2.id}/bookmark")
1784
1785 assert json_response(response2, 200)["bookmarked"] == true
1786
1787 bookmarks =
1788 build_conn()
1789 |> assign(:user, for_user)
1790 |> get("/api/v1/bookmarks")
1791
1792 assert [json_response(response2, 200), json_response(response1, 200)] ==
1793 json_response(bookmarks, 200)
1794
1795 response1 =
1796 build_conn()
1797 |> assign(:user, for_user)
1798 |> post("/api/v1/statuses/#{activity1.id}/unbookmark")
1799
1800 assert json_response(response1, 200)["bookmarked"] == false
1801
1802 bookmarks =
1803 build_conn()
1804 |> assign(:user, for_user)
1805 |> get("/api/v1/bookmarks")
1806
1807 assert [json_response(response2, 200)] == json_response(bookmarks, 200)
1808 end
1809
1810 describe "conversation muting" do
1811 setup do
1812 user = insert(:user)
1813 {:ok, activity} = CommonAPI.post(user, %{"status" => "HIE"})
1814
1815 [user: user, activity: activity]
1816 end
1817
1818 test "mute conversation", %{conn: conn, user: user, activity: activity} do
1819 id_str = to_string(activity.id)
1820
1821 assert %{"id" => ^id_str, "muted" => true} =
1822 conn
1823 |> assign(:user, user)
1824 |> post("/api/v1/statuses/#{activity.id}/mute")
1825 |> json_response(200)
1826 end
1827
1828 test "unmute conversation", %{conn: conn, user: user, activity: activity} do
1829 {:ok, _} = CommonAPI.add_mute(user, activity)
1830
1831 id_str = to_string(activity.id)
1832 user = refresh_record(user)
1833
1834 assert %{"id" => ^id_str, "muted" => false} =
1835 conn
1836 |> assign(:user, user)
1837 |> post("/api/v1/statuses/#{activity.id}/unmute")
1838 |> json_response(200)
1839 end
1840 end
1841
1842 test "flavours switching (Pleroma Extension)", %{conn: conn} do
1843 user = insert(:user)
1844
1845 get_old_flavour =
1846 conn
1847 |> assign(:user, user)
1848 |> get("/api/v1/pleroma/flavour")
1849
1850 assert "glitch" == json_response(get_old_flavour, 200)
1851
1852 set_flavour =
1853 conn
1854 |> assign(:user, user)
1855 |> post("/api/v1/pleroma/flavour/vanilla")
1856
1857 assert "vanilla" == json_response(set_flavour, 200)
1858
1859 get_new_flavour =
1860 conn
1861 |> assign(:user, user)
1862 |> post("/api/v1/pleroma/flavour/vanilla")
1863
1864 assert json_response(set_flavour, 200) == json_response(get_new_flavour, 200)
1865 end
1866
1867 describe "reports" do
1868 setup do
1869 reporter = insert(:user)
1870 target_user = insert(:user)
1871
1872 {:ok, activity} = CommonAPI.post(target_user, %{"status" => "foobar"})
1873
1874 [reporter: reporter, target_user: target_user, activity: activity]
1875 end
1876
1877 test "submit a basic report", %{conn: conn, reporter: reporter, target_user: target_user} do
1878 assert %{"action_taken" => false, "id" => _} =
1879 conn
1880 |> assign(:user, reporter)
1881 |> post("/api/v1/reports", %{"account_id" => target_user.id})
1882 |> json_response(200)
1883 end
1884
1885 test "submit a report with statuses and comment", %{
1886 conn: conn,
1887 reporter: reporter,
1888 target_user: target_user,
1889 activity: activity
1890 } do
1891 assert %{"action_taken" => false, "id" => _} =
1892 conn
1893 |> assign(:user, reporter)
1894 |> post("/api/v1/reports", %{
1895 "account_id" => target_user.id,
1896 "status_ids" => [activity.id],
1897 "comment" => "bad status!"
1898 })
1899 |> json_response(200)
1900 end
1901
1902 test "accound_id is required", %{
1903 conn: conn,
1904 reporter: reporter,
1905 activity: activity
1906 } do
1907 assert %{"error" => "Valid `account_id` required"} =
1908 conn
1909 |> assign(:user, reporter)
1910 |> post("/api/v1/reports", %{"status_ids" => [activity.id]})
1911 |> json_response(400)
1912 end
1913
1914 test "comment must be up to the size specified in the config", %{
1915 conn: conn,
1916 reporter: reporter,
1917 target_user: target_user
1918 } do
1919 max_size = Pleroma.Config.get([:instance, :max_report_comment_size], 1000)
1920 comment = String.pad_trailing("a", max_size + 1, "a")
1921
1922 error = %{"error" => "Comment must be up to #{max_size} characters"}
1923
1924 assert ^error =
1925 conn
1926 |> assign(:user, reporter)
1927 |> post("/api/v1/reports", %{"account_id" => target_user.id, "comment" => comment})
1928 |> json_response(400)
1929 end
1930 end
1931 end