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