clients.md: Add Kyclos
[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 app_token = insert(:oauth_token, user: nil)
672
673 conn =
674 conn
675 |> put_req_header("authorization", "Bearer " <> app_token.token)
676 |> Map.put(:remote_ip, {15, 15, 15, 15})
677
678 for i <- 1..5 do
679 conn =
680 post(conn, "/api/v1/accounts", %{
681 username: "#{i}lain",
682 email: "#{i}lain@example.org",
683 password: "PlzDontHackLain",
684 agreement: true
685 })
686
687 %{
688 "access_token" => token,
689 "created_at" => _created_at,
690 "scope" => _scope,
691 "token_type" => "Bearer"
692 } = json_response(conn, 200)
693
694 token_from_db = Repo.get_by(Token, token: token)
695 assert token_from_db
696 token_from_db = Repo.preload(token_from_db, :user)
697 assert token_from_db.user
698
699 assert token_from_db.user.confirmation_pending
700 end
701
702 conn =
703 post(conn, "/api/v1/accounts", %{
704 username: "6lain",
705 email: "6lain@example.org",
706 password: "PlzDontHackLain",
707 agreement: true
708 })
709
710 assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"}
711 end
712
713 test "returns bad_request if missing required params", %{
714 conn: conn,
715 valid_params: valid_params
716 } do
717 app_token = insert(:oauth_token, user: nil)
718
719 conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token)
720
721 res = post(conn, "/api/v1/accounts", valid_params)
722 assert json_response(res, 200)
723
724 [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}]
725 |> Stream.zip(valid_params)
726 |> Enum.each(fn {ip, {attr, _}} ->
727 res =
728 conn
729 |> Map.put(:remote_ip, ip)
730 |> post("/api/v1/accounts", Map.delete(valid_params, attr))
731 |> json_response(400)
732
733 assert res == %{"error" => "Missing parameters"}
734 end)
735 end
736
737 test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do
738 conn = put_req_header(conn, "authorization", "Bearer " <> "invalid-token")
739
740 res = post(conn, "/api/v1/accounts", valid_params)
741 assert json_response(res, 403) == %{"error" => "Invalid credentials"}
742 end
743 end
744
745 describe "GET /api/v1/accounts/:id/lists - account_lists" do
746 test "returns lists to which the account belongs" do
747 %{user: user, conn: conn} = oauth_access(["read:lists"])
748 other_user = insert(:user)
749 assert {:ok, %Pleroma.List{} = list} = Pleroma.List.create("Test List", user)
750 {:ok, %{following: _following}} = Pleroma.List.follow(list, other_user)
751
752 res =
753 conn
754 |> get("/api/v1/accounts/#{other_user.id}/lists")
755 |> json_response(200)
756
757 assert res == [%{"id" => to_string(list.id), "title" => "Test List"}]
758 end
759 end
760
761 describe "verify_credentials" do
762 test "verify_credentials" do
763 %{user: user, conn: conn} = oauth_access(["read:accounts"])
764 conn = get(conn, "/api/v1/accounts/verify_credentials")
765
766 response = json_response(conn, 200)
767
768 assert %{"id" => id, "source" => %{"privacy" => "public"}} = response
769 assert response["pleroma"]["chat_token"]
770 assert id == to_string(user.id)
771 end
772
773 test "verify_credentials default scope unlisted" do
774 user = insert(:user, default_scope: "unlisted")
775 %{conn: conn} = oauth_access(["read:accounts"], user: user)
776
777 conn = get(conn, "/api/v1/accounts/verify_credentials")
778
779 assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200)
780 assert id == to_string(user.id)
781 end
782
783 test "locked accounts" do
784 user = insert(:user, default_scope: "private")
785 %{conn: conn} = oauth_access(["read:accounts"], user: user)
786
787 conn = get(conn, "/api/v1/accounts/verify_credentials")
788
789 assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
790 assert id == to_string(user.id)
791 end
792 end
793
794 describe "user relationships" do
795 setup do: oauth_access(["read:follows"])
796
797 test "returns the relationships for the current user", %{user: user, conn: conn} do
798 other_user = insert(:user)
799 {:ok, _user} = User.follow(user, other_user)
800
801 conn = get(conn, "/api/v1/accounts/relationships", %{"id" => [other_user.id]})
802
803 assert [relationship] = json_response(conn, 200)
804
805 assert to_string(other_user.id) == relationship["id"]
806 end
807
808 test "returns an empty list on a bad request", %{conn: conn} do
809 conn = get(conn, "/api/v1/accounts/relationships", %{})
810
811 assert [] = json_response(conn, 200)
812 end
813 end
814
815 test "getting a list of mutes" do
816 %{user: user, conn: conn} = oauth_access(["read:mutes"])
817 other_user = insert(:user)
818
819 {:ok, _user_relationships} = User.mute(user, other_user)
820
821 conn = get(conn, "/api/v1/mutes")
822
823 other_user_id = to_string(other_user.id)
824 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
825 end
826
827 test "getting a list of blocks" do
828 %{user: user, conn: conn} = oauth_access(["read:blocks"])
829 other_user = insert(:user)
830
831 {:ok, _user_relationship} = User.block(user, other_user)
832
833 conn =
834 conn
835 |> assign(:user, user)
836 |> get("/api/v1/blocks")
837
838 other_user_id = to_string(other_user.id)
839 assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
840 end
841 end