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