Merge branch 'develop' into fix/disable-rate-limiter-for-socket-localhost
[akkoma] / test / web / mastodon_api / controllers / account_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.AccountControllerTest do
6 use Pleroma.Web.ConnCase
7
8 alias Pleroma.Repo
9 alias Pleroma.User
10 alias Pleroma.Web.ActivityPub.ActivityPub
11 alias Pleroma.Web.ActivityPub.InternalFetchActor
12 alias Pleroma.Web.CommonAPI
13 alias Pleroma.Web.OAuth.Token
14
15 import Pleroma.Factory
16
17 describe "account fetching" do
18 test "works by id" do
19 user = insert(:user)
20
21 conn =
22 build_conn()
23 |> get("/api/v1/accounts/#{user.id}")
24
25 assert %{"id" => id} = json_response(conn, 200)
26 assert id == to_string(user.id)
27
28 conn =
29 build_conn()
30 |> get("/api/v1/accounts/-1")
31
32 assert %{"error" => "Can't find user"} = json_response(conn, 404)
33 end
34
35 test "works by nickname" do
36 user = insert(:user)
37
38 conn =
39 build_conn()
40 |> get("/api/v1/accounts/#{user.nickname}")
41
42 assert %{"id" => id} = json_response(conn, 200)
43 assert id == user.id
44 end
45
46 test "works by nickname for remote users" do
47 limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
48 Pleroma.Config.put([:instance, :limit_to_local_content], false)
49 user = insert(:user, nickname: "user@example.com", local: false)
50
51 conn =
52 build_conn()
53 |> get("/api/v1/accounts/#{user.nickname}")
54
55 Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
56 assert %{"id" => id} = json_response(conn, 200)
57 assert id == user.id
58 end
59
60 test "respects limit_to_local_content == :all for remote user nicknames" do
61 limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
62 Pleroma.Config.put([:instance, :limit_to_local_content], :all)
63
64 user = insert(:user, nickname: "user@example.com", local: false)
65
66 conn =
67 build_conn()
68 |> get("/api/v1/accounts/#{user.nickname}")
69
70 Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
71 assert json_response(conn, 404)
72 end
73
74 test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
75 limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
76 Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
77
78 user = insert(:user, nickname: "user@example.com", local: false)
79 reading_user = insert(:user)
80
81 conn =
82 build_conn()
83 |> get("/api/v1/accounts/#{user.nickname}")
84
85 assert json_response(conn, 404)
86
87 conn =
88 build_conn()
89 |> assign(:user, reading_user)
90 |> assign(:token, insert(:oauth_token, user: reading_user, scopes: ["read:accounts"]))
91 |> get("/api/v1/accounts/#{user.nickname}")
92
93 Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
94 assert %{"id" => id} = json_response(conn, 200)
95 assert id == user.id
96 end
97
98 test "accounts fetches correct account for nicknames beginning with numbers", %{conn: conn} do
99 # Need to set an old-style integer ID to reproduce the problem
100 # (these are no longer assigned to new accounts but were preserved
101 # for existing accounts during the migration to flakeIDs)
102 user_one = insert(:user, %{id: 1212})
103 user_two = insert(:user, %{nickname: "#{user_one.id}garbage"})
104
105 resp_one =
106 conn
107 |> get("/api/v1/accounts/#{user_one.id}")
108
109 resp_two =
110 conn
111 |> get("/api/v1/accounts/#{user_two.nickname}")
112
113 resp_three =
114 conn
115 |> get("/api/v1/accounts/#{user_two.id}")
116
117 acc_one = json_response(resp_one, 200)
118 acc_two = json_response(resp_two, 200)
119 acc_three = json_response(resp_three, 200)
120 refute acc_one == acc_two
121 assert acc_two == acc_three
122 end
123
124 test "returns 404 when user is invisible", %{conn: conn} do
125 user = insert(:user, %{invisible: true})
126
127 resp =
128 conn
129 |> get("/api/v1/accounts/#{user.nickname}")
130 |> json_response(404)
131
132 assert %{"error" => "Can't find user"} = resp
133 end
134
135 test "returns 404 for internal.fetch actor", %{conn: conn} do
136 %User{nickname: "internal.fetch"} = InternalFetchActor.get_actor()
137
138 resp =
139 conn
140 |> get("/api/v1/accounts/internal.fetch")
141 |> json_response(404)
142
143 assert %{"error" => "Can't find user"} = resp
144 end
145 end
146
147 describe "user timelines" do
148 setup do: oauth_access(["read:statuses"])
149
150 test "respects blocks", %{user: user_one, conn: conn} do
151 user_two = insert(:user)
152 user_three = insert(:user)
153
154 User.block(user_one, user_two)
155
156 {:ok, activity} = CommonAPI.post(user_two, %{"status" => "User one sux0rz"})
157 {:ok, repeat, _} = CommonAPI.repeat(activity.id, user_three)
158
159 resp = get(conn, "/api/v1/accounts/#{user_two.id}/statuses")
160
161 assert [%{"id" => id}] = json_response(resp, 200)
162 assert id == activity.id
163
164 # Even a blocked user will deliver the full user timeline, there would be
165 # no point in looking at a blocked users timeline otherwise
166 resp = get(conn, "/api/v1/accounts/#{user_two.id}/statuses")
167
168 assert [%{"id" => id}] = json_response(resp, 200)
169 assert id == activity.id
170
171 # Third user's timeline includes the repeat when viewed by unauthenticated user
172 resp = get(build_conn(), "/api/v1/accounts/#{user_three.id}/statuses")
173 assert [%{"id" => id}] = json_response(resp, 200)
174 assert id == repeat.id
175
176 # When viewing a third user's timeline, the blocked users' statuses will NOT be shown
177 resp = get(conn, "/api/v1/accounts/#{user_three.id}/statuses")
178
179 assert [] = json_response(resp, 200)
180 end
181
182 test "gets users statuses", %{conn: conn} do
183 user_one = insert(:user)
184 user_two = insert(:user)
185 user_three = insert(:user)
186
187 {:ok, _user_three} = User.follow(user_three, user_one)
188
189 {:ok, activity} = CommonAPI.post(user_one, %{"status" => "HI!!!"})
190
191 {:ok, direct_activity} =
192 CommonAPI.post(user_one, %{
193 "status" => "Hi, @#{user_two.nickname}.",
194 "visibility" => "direct"
195 })
196
197 {:ok, private_activity} =
198 CommonAPI.post(user_one, %{"status" => "private", "visibility" => "private"})
199
200 resp = get(conn, "/api/v1/accounts/#{user_one.id}/statuses")
201
202 assert [%{"id" => id}] = json_response(resp, 200)
203 assert id == to_string(activity.id)
204
205 resp =
206 conn
207 |> assign(:user, user_two)
208 |> assign(:token, insert(:oauth_token, user: user_two, scopes: ["read:statuses"]))
209 |> get("/api/v1/accounts/#{user_one.id}/statuses")
210
211 assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
212 assert id_one == to_string(direct_activity.id)
213 assert id_two == to_string(activity.id)
214
215 resp =
216 conn
217 |> assign(:user, user_three)
218 |> assign(:token, insert(:oauth_token, user: user_three, scopes: ["read:statuses"]))
219 |> get("/api/v1/accounts/#{user_one.id}/statuses")
220
221 assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
222 assert id_one == to_string(private_activity.id)
223 assert id_two == to_string(activity.id)
224 end
225
226 test "unimplemented pinned statuses feature", %{conn: conn} do
227 note = insert(:note_activity)
228 user = User.get_cached_by_ap_id(note.data["actor"])
229
230 conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?pinned=true")
231
232 assert json_response(conn, 200) == []
233 end
234
235 test "gets an users media", %{conn: conn} do
236 note = insert(:note_activity)
237 user = User.get_cached_by_ap_id(note.data["actor"])
238
239 file = %Plug.Upload{
240 content_type: "image/jpg",
241 path: Path.absname("test/fixtures/image.jpg"),
242 filename: "an_image.jpg"
243 }
244
245 {:ok, %{id: media_id}} = ActivityPub.upload(file, actor: user.ap_id)
246
247 {:ok, image_post} = CommonAPI.post(user, %{"status" => "cofe", "media_ids" => [media_id]})
248
249 conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "true"})
250
251 assert [%{"id" => id}] = json_response(conn, 200)
252 assert id == to_string(image_post.id)
253
254 conn = get(build_conn(), "/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "1"})
255
256 assert [%{"id" => id}] = json_response(conn, 200)
257 assert id == to_string(image_post.id)
258 end
259
260 test "gets a user's statuses without reblogs", %{user: user, conn: conn} do
261 {:ok, post} = CommonAPI.post(user, %{"status" => "HI!!!"})
262 {:ok, _, _} = CommonAPI.repeat(post.id, user)
263
264 conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"})
265
266 assert [%{"id" => id}] = json_response(conn, 200)
267 assert id == to_string(post.id)
268
269 conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "1"})
270
271 assert [%{"id" => id}] = json_response(conn, 200)
272 assert id == to_string(post.id)
273 end
274
275 test "filters user's statuses by a hashtag", %{user: user, conn: conn} do
276 {:ok, post} = CommonAPI.post(user, %{"status" => "#hashtag"})
277 {:ok, _post} = CommonAPI.post(user, %{"status" => "hashtag"})
278
279 conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"tagged" => "hashtag"})
280
281 assert [%{"id" => id}] = json_response(conn, 200)
282 assert id == to_string(post.id)
283 end
284
285 test "the user views their own timelines and excludes direct messages", %{
286 user: user,
287 conn: conn
288 } do
289 {:ok, public_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "public"})
290 {:ok, _direct_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"})
291
292 conn =
293 get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_visibilities" => ["direct"]})
294
295 assert [%{"id" => id}] = json_response(conn, 200)
296 assert id == to_string(public_activity.id)
297 end
298 end
299
300 describe "followers" do
301 setup do: oauth_access(["read:accounts"])
302
303 test "getting followers", %{user: user, conn: conn} do
304 other_user = insert(:user)
305 {:ok, user} = User.follow(user, other_user)
306
307 conn = get(conn, "/api/v1/accounts/#{other_user.id}/followers")
308
309 assert [%{"id" => id}] = json_response(conn, 200)
310 assert id == to_string(user.id)
311 end
312
313 test "getting followers, hide_followers", %{user: user, conn: conn} do
314 other_user = insert(:user, hide_followers: true)
315 {:ok, _user} = User.follow(user, other_user)
316
317 conn = get(conn, "/api/v1/accounts/#{other_user.id}/followers")
318
319 assert [] == json_response(conn, 200)
320 end
321
322 test "getting followers, hide_followers, same user requesting" do
323 user = insert(:user)
324 other_user = insert(:user, hide_followers: true)
325 {:ok, _user} = User.follow(user, other_user)
326
327 conn =
328 build_conn()
329 |> assign(:user, other_user)
330 |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"]))
331 |> get("/api/v1/accounts/#{other_user.id}/followers")
332
333 refute [] == json_response(conn, 200)
334 end
335
336 test "getting followers, pagination", %{user: user, conn: conn} do
337 follower1 = insert(:user)
338 follower2 = insert(:user)
339 follower3 = insert(:user)
340 {:ok, _} = User.follow(follower1, user)
341 {:ok, _} = User.follow(follower2, user)
342 {:ok, _} = User.follow(follower3, user)
343
344 res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?since_id=#{follower1.id}")
345
346 assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200)
347 assert id3 == follower3.id
348 assert id2 == follower2.id
349
350 res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?max_id=#{follower3.id}")
351
352 assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200)
353 assert id2 == follower2.id
354 assert id1 == follower1.id
355
356 res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3.id}")
357
358 assert [%{"id" => id2}] = json_response(res_conn, 200)
359 assert id2 == follower2.id
360
361 assert [link_header] = get_resp_header(res_conn, "link")
362 assert link_header =~ ~r/min_id=#{follower2.id}/
363 assert link_header =~ ~r/max_id=#{follower2.id}/
364 end
365 end
366
367 describe "following" do
368 setup do: oauth_access(["read:accounts"])
369
370 test "getting following", %{user: user, conn: conn} do
371 other_user = insert(:user)
372 {:ok, user} = User.follow(user, other_user)
373
374 conn = get(conn, "/api/v1/accounts/#{user.id}/following")
375
376 assert [%{"id" => id}] = json_response(conn, 200)
377 assert id == to_string(other_user.id)
378 end
379
380 test "getting following, hide_follows, other user requesting" do
381 user = insert(:user, hide_follows: true)
382 other_user = insert(:user)
383 {:ok, user} = User.follow(user, other_user)
384
385 conn =
386 build_conn()
387 |> assign(:user, other_user)
388 |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"]))
389 |> get("/api/v1/accounts/#{user.id}/following")
390
391 assert [] == json_response(conn, 200)
392 end
393
394 test "getting following, hide_follows, same user requesting" do
395 user = insert(:user, hide_follows: true)
396 other_user = insert(:user)
397 {:ok, user} = User.follow(user, other_user)
398
399 conn =
400 build_conn()
401 |> assign(:user, user)
402 |> assign(:token, insert(:oauth_token, user: user, scopes: ["read:accounts"]))
403 |> get("/api/v1/accounts/#{user.id}/following")
404
405 refute [] == json_response(conn, 200)
406 end
407
408 test "getting following, pagination", %{user: user, conn: conn} do
409 following1 = insert(:user)
410 following2 = insert(:user)
411 following3 = insert(:user)
412 {:ok, _} = User.follow(user, following1)
413 {:ok, _} = User.follow(user, following2)
414 {:ok, _} = User.follow(user, following3)
415
416 res_conn = get(conn, "/api/v1/accounts/#{user.id}/following?since_id=#{following1.id}")
417
418 assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200)
419 assert id3 == following3.id
420 assert id2 == following2.id
421
422 res_conn = get(conn, "/api/v1/accounts/#{user.id}/following?max_id=#{following3.id}")
423
424 assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200)
425 assert id2 == following2.id
426 assert id1 == following1.id
427
428 res_conn =
429 get(conn, "/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}")
430
431 assert [%{"id" => id2}] = json_response(res_conn, 200)
432 assert id2 == following2.id
433
434 assert [link_header] = get_resp_header(res_conn, "link")
435 assert link_header =~ ~r/min_id=#{following2.id}/
436 assert link_header =~ ~r/max_id=#{following2.id}/
437 end
438 end
439
440 describe "follow/unfollow" do
441 setup do: oauth_access(["follow"])
442
443 test "following / unfollowing a user", %{conn: conn} do
444 other_user = insert(:user)
445
446 ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/follow")
447
448 assert %{"id" => _id, "following" => true} = json_response(ret_conn, 200)
449
450 ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/unfollow")
451
452 assert %{"id" => _id, "following" => false} = json_response(ret_conn, 200)
453
454 conn = post(conn, "/api/v1/follows", %{"uri" => other_user.nickname})
455
456 assert %{"id" => id} = json_response(conn, 200)
457 assert id == to_string(other_user.id)
458 end
459
460 test "following without reblogs" do
461 %{conn: conn} = oauth_access(["follow", "read:statuses"])
462 followed = insert(:user)
463 other_user = insert(:user)
464
465 ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=false")
466
467 assert %{"showing_reblogs" => false} = json_response(ret_conn, 200)
468
469 {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey"})
470 {:ok, reblog, _} = CommonAPI.repeat(activity.id, followed)
471
472 ret_conn = get(conn, "/api/v1/timelines/home")
473
474 assert [] == json_response(ret_conn, 200)
475
476 ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=true")
477
478 assert %{"showing_reblogs" => true} = json_response(ret_conn, 200)
479
480 conn = get(conn, "/api/v1/timelines/home")
481
482 expected_activity_id = reblog.id
483 assert [%{"id" => ^expected_activity_id}] = json_response(conn, 200)
484 end
485
486 test "following / unfollowing errors", %{user: user, conn: conn} do
487 # self follow
488 conn_res = post(conn, "/api/v1/accounts/#{user.id}/follow")
489 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
490
491 # self unfollow
492 user = User.get_cached_by_id(user.id)
493 conn_res = post(conn, "/api/v1/accounts/#{user.id}/unfollow")
494 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
495
496 # self follow via uri
497 user = User.get_cached_by_id(user.id)
498 conn_res = post(conn, "/api/v1/follows", %{"uri" => user.nickname})
499 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
500
501 # follow non existing user
502 conn_res = post(conn, "/api/v1/accounts/doesntexist/follow")
503 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
504
505 # follow non existing user via uri
506 conn_res = post(conn, "/api/v1/follows", %{"uri" => "doesntexist"})
507 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
508
509 # unfollow non existing user
510 conn_res = post(conn, "/api/v1/accounts/doesntexist/unfollow")
511 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
512 end
513 end
514
515 describe "mute/unmute" do
516 setup do: oauth_access(["write:mutes"])
517
518 test "with notifications", %{conn: conn} do
519 other_user = insert(:user)
520
521 ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/mute")
522
523 response = json_response(ret_conn, 200)
524
525 assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = response
526
527 conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute")
528
529 response = json_response(conn, 200)
530 assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response
531 end
532
533 test "without notifications", %{conn: conn} do
534 other_user = insert(:user)
535
536 ret_conn =
537 post(conn, "/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"})
538
539 response = json_response(ret_conn, 200)
540
541 assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = response
542
543 conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute")
544
545 response = json_response(conn, 200)
546 assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response
547 end
548 end
549
550 describe "pinned statuses" do
551 setup do
552 user = insert(:user)
553 {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"})
554 %{conn: conn} = oauth_access(["read:statuses"], user: user)
555
556 [conn: conn, user: user, activity: activity]
557 end
558
559 test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do
560 {:ok, _} = CommonAPI.pin(activity.id, user)
561
562 result =
563 conn
564 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
565 |> json_response(200)
566
567 id_str = to_string(activity.id)
568
569 assert [%{"id" => ^id_str, "pinned" => true}] = result
570 end
571 end
572
573 test "blocking / unblocking a user" do
574 %{conn: conn} = oauth_access(["follow"])
575 other_user = insert(:user)
576
577 ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/block")
578
579 assert %{"id" => _id, "blocking" => true} = json_response(ret_conn, 200)
580
581 conn = post(conn, "/api/v1/accounts/#{other_user.id}/unblock")
582
583 assert %{"id" => _id, "blocking" => false} = json_response(conn, 200)
584 end
585
586 describe "create account by app" do
587 setup do
588 valid_params = %{
589 username: "lain",
590 email: "lain@example.org",
591 password: "PlzDontHackLain",
592 agreement: true
593 }
594
595 [valid_params: valid_params]
596 end
597
598 test "Account registration via Application", %{conn: conn} do
599 conn =
600 post(conn, "/api/v1/apps", %{
601 client_name: "client_name",
602 redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
603 scopes: "read, write, follow"
604 })
605
606 %{
607 "client_id" => client_id,
608 "client_secret" => client_secret,
609 "id" => _,
610 "name" => "client_name",
611 "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
612 "vapid_key" => _,
613 "website" => nil
614 } = json_response(conn, 200)
615
616 conn =
617 post(conn, "/oauth/token", %{
618 grant_type: "client_credentials",
619 client_id: client_id,
620 client_secret: client_secret
621 })
622
623 assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
624 json_response(conn, 200)
625
626 assert token
627 token_from_db = Repo.get_by(Token, token: token)
628 assert token_from_db
629 assert refresh
630 assert scope == "read write follow"
631
632 conn =
633 build_conn()
634 |> put_req_header("authorization", "Bearer " <> token)
635 |> post("/api/v1/accounts", %{
636 username: "lain",
637 email: "lain@example.org",
638 password: "PlzDontHackLain",
639 bio: "Test Bio",
640 agreement: true
641 })
642
643 %{
644 "access_token" => token,
645 "created_at" => _created_at,
646 "scope" => _scope,
647 "token_type" => "Bearer"
648 } = json_response(conn, 200)
649
650 token_from_db = Repo.get_by(Token, token: token)
651 assert token_from_db
652 token_from_db = Repo.preload(token_from_db, :user)
653 assert token_from_db.user
654
655 assert token_from_db.user.confirmation_pending
656 end
657
658 test "returns error when user already registred", %{conn: conn, valid_params: valid_params} do
659 _user = insert(:user, email: "lain@example.org")
660 app_token = insert(:oauth_token, user: nil)
661
662 conn =
663 conn
664 |> put_req_header("authorization", "Bearer " <> app_token.token)
665
666 res = post(conn, "/api/v1/accounts", valid_params)
667 assert json_response(res, 400) == %{"error" => "{\"email\":[\"has already been taken\"]}"}
668 end
669
670 test "rate limit", %{conn: conn} do
671 Pleroma.Config.put([Pleroma.Plugs.RemoteIp, :enabled], true)
672 app_token = insert(:oauth_token, user: nil)
673
674 conn =
675 conn
676 |> put_req_header("authorization", "Bearer " <> app_token.token)
677 |> Map.put(:remote_ip, {15, 15, 15, 15})
678
679 for i <- 1..5 do
680 conn =
681 post(conn, "/api/v1/accounts", %{
682 username: "#{i}lain",
683 email: "#{i}lain@example.org",
684 password: "PlzDontHackLain",
685 agreement: true
686 })
687
688 %{
689 "access_token" => token,
690 "created_at" => _created_at,
691 "scope" => _scope,
692 "token_type" => "Bearer"
693 } = json_response(conn, 200)
694
695 token_from_db = Repo.get_by(Token, token: token)
696 assert token_from_db
697 token_from_db = Repo.preload(token_from_db, :user)
698 assert token_from_db.user
699
700 assert token_from_db.user.confirmation_pending
701 end
702
703 conn =
704 post(conn, "/api/v1/accounts", %{
705 username: "6lain",
706 email: "6lain@example.org",
707 password: "PlzDontHackLain",
708 agreement: true
709 })
710
711 assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"}
712 end
713
714 test "returns bad_request if missing required params", %{
715 conn: conn,
716 valid_params: valid_params
717 } do
718 app_token = insert(:oauth_token, user: nil)
719
720 conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token)
721
722 res = post(conn, "/api/v1/accounts", valid_params)
723 assert json_response(res, 200)
724
725 [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}]
726 |> Stream.zip(valid_params)
727 |> Enum.each(fn {ip, {attr, _}} ->
728 res =
729 conn
730 |> Map.put(:remote_ip, ip)
731 |> post("/api/v1/accounts", Map.delete(valid_params, attr))
732 |> json_response(400)
733
734 assert res == %{"error" => "Missing parameters"}
735 end)
736 end
737
738 test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do
739 conn = put_req_header(conn, "authorization", "Bearer " <> "invalid-token")
740
741 res = post(conn, "/api/v1/accounts", valid_params)
742 assert json_response(res, 403) == %{"error" => "Invalid credentials"}
743 end
744 end
745
746 describe "GET /api/v1/accounts/:id/lists - account_lists" do
747 test "returns lists to which the account belongs" do
748 %{user: user, conn: conn} = oauth_access(["read:lists"])
749 other_user = insert(:user)
750 assert {:ok, %Pleroma.List{} = list} = Pleroma.List.create("Test List", user)
751 {:ok, %{following: _following}} = Pleroma.List.follow(list, other_user)
752
753 res =
754 conn
755 |> get("/api/v1/accounts/#{other_user.id}/lists")
756 |> json_response(200)
757
758 assert res == [%{"id" => to_string(list.id), "title" => "Test List"}]
759 end
760 end
761
762 describe "verify_credentials" do
763 test "verify_credentials" do
764 %{user: user, conn: conn} = oauth_access(["read:accounts"])
765 conn = get(conn, "/api/v1/accounts/verify_credentials")
766
767 response = json_response(conn, 200)
768
769 assert %{"id" => id, "source" => %{"privacy" => "public"}} = response
770 assert response["pleroma"]["chat_token"]
771 assert id == to_string(user.id)
772 end
773
774 test "verify_credentials default scope unlisted" do
775 user = insert(:user, default_scope: "unlisted")
776 %{conn: conn} = oauth_access(["read:accounts"], user: user)
777
778 conn = get(conn, "/api/v1/accounts/verify_credentials")
779
780 assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200)
781 assert id == to_string(user.id)
782 end
783
784 test "locked accounts" do
785 user = insert(:user, default_scope: "private")
786 %{conn: conn} = oauth_access(["read:accounts"], user: user)
787
788 conn = get(conn, "/api/v1/accounts/verify_credentials")
789
790 assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
791 assert id == to_string(user.id)
792 end
793 end
794
795 describe "user relationships" do
796 setup do: oauth_access(["read:follows"])
797
798 test "returns the relationships for the current user", %{user: user, conn: conn} do
799 other_user = insert(:user)
800 {:ok, _user} = User.follow(user, other_user)
801
802 conn = get(conn, "/api/v1/accounts/relationships", %{"id" => [other_user.id]})
803
804 assert [relationship] = json_response(conn, 200)
805
806 assert to_string(other_user.id) == relationship["id"]
807 end
808
809 test "returns an empty list on a bad request", %{conn: conn} do
810 conn = get(conn, "/api/v1/accounts/relationships", %{})
811
812 assert [] = json_response(conn, 200)
813 end
814 end
815
816 test "getting a list of mutes" do
817 %{user: user, conn: conn} = oauth_access(["read:mutes"])
818 other_user = insert(:user)
819
820 {:ok, _user_relationships} = User.mute(user, other_user)
821
822 conn = get(conn, "/api/v1/mutes")
823
824 other_user_id = to_string(other_user.id)
825 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
826 end
827
828 test "getting a list of blocks" do
829 %{user: user, conn: conn} = oauth_access(["read:blocks"])
830 other_user = insert(:user)
831
832 {:ok, _user_relationship} = User.block(user, other_user)
833
834 conn =
835 conn
836 |> assign(:user, user)
837 |> get("/api/v1/blocks")
838
839 other_user_id = to_string(other_user.id)
840 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
841 end
842 end