Merge branch 'fix/upload-limit-otp' into 'develop'
[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 "cancelling follow request", %{conn: conn} do
461 %{id: other_user_id} = insert(:user, %{locked: true})
462
463 assert %{"id" => ^other_user_id, "following" => false, "requested" => true} =
464 conn |> post("/api/v1/accounts/#{other_user_id}/follow") |> json_response(:ok)
465
466 assert %{"id" => ^other_user_id, "following" => false, "requested" => false} =
467 conn |> post("/api/v1/accounts/#{other_user_id}/unfollow") |> json_response(:ok)
468 end
469
470 test "following without reblogs" do
471 %{conn: conn} = oauth_access(["follow", "read:statuses"])
472 followed = insert(:user)
473 other_user = insert(:user)
474
475 ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=false")
476
477 assert %{"showing_reblogs" => false} = json_response(ret_conn, 200)
478
479 {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey"})
480 {:ok, reblog, _} = CommonAPI.repeat(activity.id, followed)
481
482 ret_conn = get(conn, "/api/v1/timelines/home")
483
484 assert [] == json_response(ret_conn, 200)
485
486 ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=true")
487
488 assert %{"showing_reblogs" => true} = json_response(ret_conn, 200)
489
490 conn = get(conn, "/api/v1/timelines/home")
491
492 expected_activity_id = reblog.id
493 assert [%{"id" => ^expected_activity_id}] = json_response(conn, 200)
494 end
495
496 test "following / unfollowing errors", %{user: user, conn: conn} do
497 # self follow
498 conn_res = post(conn, "/api/v1/accounts/#{user.id}/follow")
499 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
500
501 # self unfollow
502 user = User.get_cached_by_id(user.id)
503 conn_res = post(conn, "/api/v1/accounts/#{user.id}/unfollow")
504 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
505
506 # self follow via uri
507 user = User.get_cached_by_id(user.id)
508 conn_res = post(conn, "/api/v1/follows", %{"uri" => user.nickname})
509 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
510
511 # follow non existing user
512 conn_res = post(conn, "/api/v1/accounts/doesntexist/follow")
513 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
514
515 # follow non existing user via uri
516 conn_res = post(conn, "/api/v1/follows", %{"uri" => "doesntexist"})
517 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
518
519 # unfollow non existing user
520 conn_res = post(conn, "/api/v1/accounts/doesntexist/unfollow")
521 assert %{"error" => "Record not found"} = json_response(conn_res, 404)
522 end
523 end
524
525 describe "mute/unmute" do
526 setup do: oauth_access(["write:mutes"])
527
528 test "with notifications", %{conn: conn} do
529 other_user = insert(:user)
530
531 ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/mute")
532
533 response = json_response(ret_conn, 200)
534
535 assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = response
536
537 conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute")
538
539 response = json_response(conn, 200)
540 assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response
541 end
542
543 test "without notifications", %{conn: conn} do
544 other_user = insert(:user)
545
546 ret_conn =
547 post(conn, "/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"})
548
549 response = json_response(ret_conn, 200)
550
551 assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = response
552
553 conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute")
554
555 response = json_response(conn, 200)
556 assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response
557 end
558 end
559
560 describe "pinned statuses" do
561 setup do
562 user = insert(:user)
563 {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"})
564 %{conn: conn} = oauth_access(["read:statuses"], user: user)
565
566 [conn: conn, user: user, activity: activity]
567 end
568
569 test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do
570 {:ok, _} = CommonAPI.pin(activity.id, user)
571
572 result =
573 conn
574 |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
575 |> json_response(200)
576
577 id_str = to_string(activity.id)
578
579 assert [%{"id" => ^id_str, "pinned" => true}] = result
580 end
581 end
582
583 test "blocking / unblocking a user" do
584 %{conn: conn} = oauth_access(["follow"])
585 other_user = insert(:user)
586
587 ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/block")
588
589 assert %{"id" => _id, "blocking" => true} = json_response(ret_conn, 200)
590
591 conn = post(conn, "/api/v1/accounts/#{other_user.id}/unblock")
592
593 assert %{"id" => _id, "blocking" => false} = json_response(conn, 200)
594 end
595
596 describe "create account by app" do
597 setup do
598 valid_params = %{
599 username: "lain",
600 email: "lain@example.org",
601 password: "PlzDontHackLain",
602 agreement: true
603 }
604
605 [valid_params: valid_params]
606 end
607
608 test "Account registration via Application", %{conn: conn} do
609 conn =
610 post(conn, "/api/v1/apps", %{
611 client_name: "client_name",
612 redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
613 scopes: "read, write, follow"
614 })
615
616 %{
617 "client_id" => client_id,
618 "client_secret" => client_secret,
619 "id" => _,
620 "name" => "client_name",
621 "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
622 "vapid_key" => _,
623 "website" => nil
624 } = json_response(conn, 200)
625
626 conn =
627 post(conn, "/oauth/token", %{
628 grant_type: "client_credentials",
629 client_id: client_id,
630 client_secret: client_secret
631 })
632
633 assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
634 json_response(conn, 200)
635
636 assert token
637 token_from_db = Repo.get_by(Token, token: token)
638 assert token_from_db
639 assert refresh
640 assert scope == "read write follow"
641
642 conn =
643 build_conn()
644 |> put_req_header("authorization", "Bearer " <> token)
645 |> post("/api/v1/accounts", %{
646 username: "lain",
647 email: "lain@example.org",
648 password: "PlzDontHackLain",
649 bio: "Test Bio",
650 agreement: true
651 })
652
653 %{
654 "access_token" => token,
655 "created_at" => _created_at,
656 "scope" => _scope,
657 "token_type" => "Bearer"
658 } = json_response(conn, 200)
659
660 token_from_db = Repo.get_by(Token, token: token)
661 assert token_from_db
662 token_from_db = Repo.preload(token_from_db, :user)
663 assert token_from_db.user
664
665 assert token_from_db.user.confirmation_pending
666 end
667
668 test "returns error when user already registred", %{conn: conn, valid_params: valid_params} do
669 _user = insert(:user, email: "lain@example.org")
670 app_token = insert(:oauth_token, user: nil)
671
672 conn =
673 conn
674 |> put_req_header("authorization", "Bearer " <> app_token.token)
675
676 res = post(conn, "/api/v1/accounts", valid_params)
677 assert json_response(res, 400) == %{"error" => "{\"email\":[\"has already been taken\"]}"}
678 end
679
680 test "rate limit", %{conn: conn} do
681 Pleroma.Config.put([Pleroma.Plugs.RemoteIp, :enabled], true)
682 app_token = insert(:oauth_token, user: nil)
683
684 conn =
685 conn
686 |> put_req_header("authorization", "Bearer " <> app_token.token)
687 |> Map.put(:remote_ip, {15, 15, 15, 15})
688
689 for i <- 1..5 do
690 conn =
691 post(conn, "/api/v1/accounts", %{
692 username: "#{i}lain",
693 email: "#{i}lain@example.org",
694 password: "PlzDontHackLain",
695 agreement: true
696 })
697
698 %{
699 "access_token" => token,
700 "created_at" => _created_at,
701 "scope" => _scope,
702 "token_type" => "Bearer"
703 } = json_response(conn, 200)
704
705 token_from_db = Repo.get_by(Token, token: token)
706 assert token_from_db
707 token_from_db = Repo.preload(token_from_db, :user)
708 assert token_from_db.user
709
710 assert token_from_db.user.confirmation_pending
711 end
712
713 conn =
714 post(conn, "/api/v1/accounts", %{
715 username: "6lain",
716 email: "6lain@example.org",
717 password: "PlzDontHackLain",
718 agreement: true
719 })
720
721 assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"}
722 end
723
724 test "returns bad_request if missing required params", %{
725 conn: conn,
726 valid_params: valid_params
727 } do
728 app_token = insert(:oauth_token, user: nil)
729
730 conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token)
731
732 res = post(conn, "/api/v1/accounts", valid_params)
733 assert json_response(res, 200)
734
735 [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}]
736 |> Stream.zip(valid_params)
737 |> Enum.each(fn {ip, {attr, _}} ->
738 res =
739 conn
740 |> Map.put(:remote_ip, ip)
741 |> post("/api/v1/accounts", Map.delete(valid_params, attr))
742 |> json_response(400)
743
744 assert res == %{"error" => "Missing parameters"}
745 end)
746 end
747
748 test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do
749 conn = put_req_header(conn, "authorization", "Bearer " <> "invalid-token")
750
751 res = post(conn, "/api/v1/accounts", valid_params)
752 assert json_response(res, 403) == %{"error" => "Invalid credentials"}
753 end
754 end
755
756 describe "GET /api/v1/accounts/:id/lists - account_lists" do
757 test "returns lists to which the account belongs" do
758 %{user: user, conn: conn} = oauth_access(["read:lists"])
759 other_user = insert(:user)
760 assert {:ok, %Pleroma.List{} = list} = Pleroma.List.create("Test List", user)
761 {:ok, %{following: _following}} = Pleroma.List.follow(list, other_user)
762
763 res =
764 conn
765 |> get("/api/v1/accounts/#{other_user.id}/lists")
766 |> json_response(200)
767
768 assert res == [%{"id" => to_string(list.id), "title" => "Test List"}]
769 end
770 end
771
772 describe "verify_credentials" do
773 test "verify_credentials" do
774 %{user: user, conn: conn} = oauth_access(["read:accounts"])
775 conn = get(conn, "/api/v1/accounts/verify_credentials")
776
777 response = json_response(conn, 200)
778
779 assert %{"id" => id, "source" => %{"privacy" => "public"}} = response
780 assert response["pleroma"]["chat_token"]
781 assert id == to_string(user.id)
782 end
783
784 test "verify_credentials default scope unlisted" do
785 user = insert(:user, default_scope: "unlisted")
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" => "unlisted"}} = json_response(conn, 200)
791 assert id == to_string(user.id)
792 end
793
794 test "locked accounts" do
795 user = insert(:user, default_scope: "private")
796 %{conn: conn} = oauth_access(["read:accounts"], user: user)
797
798 conn = get(conn, "/api/v1/accounts/verify_credentials")
799
800 assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
801 assert id == to_string(user.id)
802 end
803 end
804
805 describe "user relationships" do
806 setup do: oauth_access(["read:follows"])
807
808 test "returns the relationships for the current user", %{user: user, conn: conn} do
809 other_user = insert(:user)
810 {:ok, _user} = User.follow(user, other_user)
811
812 conn = get(conn, "/api/v1/accounts/relationships", %{"id" => [other_user.id]})
813
814 assert [relationship] = json_response(conn, 200)
815
816 assert to_string(other_user.id) == relationship["id"]
817 end
818
819 test "returns an empty list on a bad request", %{conn: conn} do
820 conn = get(conn, "/api/v1/accounts/relationships", %{})
821
822 assert [] = json_response(conn, 200)
823 end
824 end
825
826 test "getting a list of mutes" do
827 %{user: user, conn: conn} = oauth_access(["read:mutes"])
828 other_user = insert(:user)
829
830 {:ok, _user_relationships} = User.mute(user, other_user)
831
832 conn = get(conn, "/api/v1/mutes")
833
834 other_user_id = to_string(other_user.id)
835 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
836 end
837
838 test "getting a list of blocks" do
839 %{user: user, conn: conn} = oauth_access(["read:blocks"])
840 other_user = insert(:user)
841
842 {:ok, _user_relationship} = User.block(user, other_user)
843
844 conn =
845 conn
846 |> assign(:user, user)
847 |> get("/api/v1/blocks")
848
849 other_user_id = to_string(other_user.id)
850 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
851 end
852 end