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