Merge branch 'feature/add-pagination-to-users-admin-api' into 'develop'
[akkoma] / test / user_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.UserTest do
6 alias Pleroma.Builders.UserBuilder
7 alias Pleroma.Activity
8 alias Pleroma.Repo
9 alias Pleroma.User
10 alias Pleroma.Web.CommonAPI
11 use Pleroma.DataCase
12
13 import Pleroma.Factory
14
15 setup_all do
16 Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
17 :ok
18 end
19
20 describe "when tags are nil" do
21 test "tagging a user" do
22 user = insert(:user, %{tags: nil})
23 user = User.tag(user, ["cool", "dude"])
24
25 assert "cool" in user.tags
26 assert "dude" in user.tags
27 end
28
29 test "untagging a user" do
30 user = insert(:user, %{tags: nil})
31 user = User.untag(user, ["cool", "dude"])
32
33 assert user.tags == []
34 end
35 end
36
37 test "ap_id returns the activity pub id for the user" do
38 user = UserBuilder.build()
39
40 expected_ap_id = "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
41
42 assert expected_ap_id == User.ap_id(user)
43 end
44
45 test "ap_followers returns the followers collection for the user" do
46 user = UserBuilder.build()
47
48 expected_followers_collection = "#{User.ap_id(user)}/followers"
49
50 assert expected_followers_collection == User.ap_followers(user)
51 end
52
53 test "returns all pending follow requests" do
54 unlocked = insert(:user)
55 locked = insert(:user, %{info: %{locked: true}})
56 follower = insert(:user)
57
58 Pleroma.Web.TwitterAPI.TwitterAPI.follow(follower, %{"user_id" => unlocked.id})
59 Pleroma.Web.TwitterAPI.TwitterAPI.follow(follower, %{"user_id" => locked.id})
60
61 assert {:ok, []} = User.get_follow_requests(unlocked)
62 assert {:ok, [activity]} = User.get_follow_requests(locked)
63
64 assert activity
65 end
66
67 test "doesn't return already accepted or duplicate follow requests" do
68 locked = insert(:user, %{info: %{locked: true}})
69 pending_follower = insert(:user)
70 accepted_follower = insert(:user)
71
72 Pleroma.Web.TwitterAPI.TwitterAPI.follow(pending_follower, %{"user_id" => locked.id})
73 Pleroma.Web.TwitterAPI.TwitterAPI.follow(pending_follower, %{"user_id" => locked.id})
74 Pleroma.Web.TwitterAPI.TwitterAPI.follow(accepted_follower, %{"user_id" => locked.id})
75 User.maybe_follow(accepted_follower, locked)
76
77 assert {:ok, [activity]} = User.get_follow_requests(locked)
78 assert activity
79 end
80
81 test "follow_all follows mutliple users" do
82 user = insert(:user)
83 followed_zero = insert(:user)
84 followed_one = insert(:user)
85 followed_two = insert(:user)
86 blocked = insert(:user)
87 not_followed = insert(:user)
88 reverse_blocked = insert(:user)
89
90 {:ok, user} = User.block(user, blocked)
91 {:ok, reverse_blocked} = User.block(reverse_blocked, user)
92
93 {:ok, user} = User.follow(user, followed_zero)
94
95 {:ok, user} = User.follow_all(user, [followed_one, followed_two, blocked, reverse_blocked])
96
97 assert User.following?(user, followed_one)
98 assert User.following?(user, followed_two)
99 assert User.following?(user, followed_zero)
100 refute User.following?(user, not_followed)
101 refute User.following?(user, blocked)
102 refute User.following?(user, reverse_blocked)
103 end
104
105 test "follow_all follows mutliple users without duplicating" do
106 user = insert(:user)
107 followed_zero = insert(:user)
108 followed_one = insert(:user)
109 followed_two = insert(:user)
110
111 {:ok, user} = User.follow_all(user, [followed_zero, followed_one])
112 assert length(user.following) == 3
113
114 {:ok, user} = User.follow_all(user, [followed_one, followed_two])
115 assert length(user.following) == 4
116 end
117
118 test "follow takes a user and another user" do
119 user = insert(:user)
120 followed = insert(:user)
121
122 {:ok, user} = User.follow(user, followed)
123
124 user = Repo.get(User, user.id)
125
126 followed = User.get_by_ap_id(followed.ap_id)
127 assert followed.info.follower_count == 1
128
129 assert User.ap_followers(followed) in user.following
130 end
131
132 test "can't follow a deactivated users" do
133 user = insert(:user)
134 followed = insert(:user, info: %{deactivated: true})
135
136 {:error, _} = User.follow(user, followed)
137 end
138
139 test "can't follow a user who blocked us" do
140 blocker = insert(:user)
141 blockee = insert(:user)
142
143 {:ok, blocker} = User.block(blocker, blockee)
144
145 {:error, _} = User.follow(blockee, blocker)
146 end
147
148 test "local users do not automatically follow local locked accounts" do
149 follower = insert(:user, info: %{locked: true})
150 followed = insert(:user, info: %{locked: true})
151
152 {:ok, follower} = User.maybe_direct_follow(follower, followed)
153
154 refute User.following?(follower, followed)
155 end
156
157 # This is a somewhat useless test.
158 # test "following a remote user will ensure a websub subscription is present" do
159 # user = insert(:user)
160 # {:ok, followed} = OStatus.make_user("shp@social.heldscal.la")
161
162 # assert followed.local == false
163
164 # {:ok, user} = User.follow(user, followed)
165 # assert User.ap_followers(followed) in user.following
166
167 # query = from w in WebsubClientSubscription,
168 # where: w.topic == ^followed.info["topic"]
169 # websub = Repo.one(query)
170
171 # assert websub
172 # end
173
174 test "unfollow takes a user and another user" do
175 followed = insert(:user)
176 user = insert(:user, %{following: [User.ap_followers(followed)]})
177
178 {:ok, user, _activity} = User.unfollow(user, followed)
179
180 user = Repo.get(User, user.id)
181
182 assert user.following == []
183 end
184
185 test "unfollow doesn't unfollow yourself" do
186 user = insert(:user)
187
188 {:error, _} = User.unfollow(user, user)
189
190 user = Repo.get(User, user.id)
191 assert user.following == [user.ap_id]
192 end
193
194 test "test if a user is following another user" do
195 followed = insert(:user)
196 user = insert(:user, %{following: [User.ap_followers(followed)]})
197
198 assert User.following?(user, followed)
199 refute User.following?(followed, user)
200 end
201
202 describe "user registration" do
203 @full_user_data %{
204 bio: "A guy",
205 name: "my name",
206 nickname: "nick",
207 password: "test",
208 password_confirmation: "test",
209 email: "email@example.com"
210 }
211
212 test "it autofollows accounts that are set for it" do
213 user = insert(:user)
214 remote_user = insert(:user, %{local: false})
215
216 Pleroma.Config.put([:instance, :autofollowed_nicknames], [
217 user.nickname,
218 remote_user.nickname
219 ])
220
221 cng = User.register_changeset(%User{}, @full_user_data)
222
223 {:ok, registered_user} = User.register(cng)
224
225 assert User.following?(registered_user, user)
226 refute User.following?(registered_user, remote_user)
227
228 Pleroma.Config.put([:instance, :autofollowed_nicknames], [])
229 end
230
231 test "it sends a welcome message if it is set" do
232 welcome_user = insert(:user)
233
234 Pleroma.Config.put([:instance, :welcome_user_nickname], welcome_user.nickname)
235 Pleroma.Config.put([:instance, :welcome_message], "Hello, this is a cool site")
236
237 cng = User.register_changeset(%User{}, @full_user_data)
238 {:ok, registered_user} = User.register(cng)
239
240 activity = Repo.one(Pleroma.Activity)
241 assert registered_user.ap_id in activity.recipients
242 assert activity.data["object"]["content"] =~ "cool site"
243 assert activity.actor == welcome_user.ap_id
244
245 Pleroma.Config.put([:instance, :welcome_user_nickname], nil)
246 Pleroma.Config.put([:instance, :welcome_message], nil)
247 end
248
249 test "it requires an email, name, nickname and password, bio is optional" do
250 @full_user_data
251 |> Map.keys()
252 |> Enum.each(fn key ->
253 params = Map.delete(@full_user_data, key)
254 changeset = User.register_changeset(%User{}, params)
255
256 assert if key == :bio, do: changeset.valid?, else: not changeset.valid?
257 end)
258 end
259
260 test "it restricts certain nicknames" do
261 [restricted_name | _] = Pleroma.Config.get([Pleroma.User, :restricted_nicknames])
262
263 assert is_bitstring(restricted_name)
264
265 params =
266 @full_user_data
267 |> Map.put(:nickname, restricted_name)
268
269 changeset = User.register_changeset(%User{}, params)
270
271 refute changeset.valid?
272 end
273
274 test "it sets the password_hash, ap_id and following fields" do
275 changeset = User.register_changeset(%User{}, @full_user_data)
276
277 assert changeset.valid?
278
279 assert is_binary(changeset.changes[:password_hash])
280 assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname})
281
282 assert changeset.changes[:following] == [
283 User.ap_followers(%User{nickname: @full_user_data.nickname})
284 ]
285
286 assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
287 end
288
289 test "it ensures info is not nil" do
290 changeset = User.register_changeset(%User{}, @full_user_data)
291
292 assert changeset.valid?
293
294 {:ok, user} =
295 changeset
296 |> Repo.insert()
297
298 refute is_nil(user.info)
299 end
300 end
301
302 describe "user registration, with :account_activation_required" do
303 @full_user_data %{
304 bio: "A guy",
305 name: "my name",
306 nickname: "nick",
307 password: "test",
308 password_confirmation: "test",
309 email: "email@example.com"
310 }
311
312 setup do
313 setting = Pleroma.Config.get([:instance, :account_activation_required])
314
315 unless setting do
316 Pleroma.Config.put([:instance, :account_activation_required], true)
317 on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
318 end
319
320 :ok
321 end
322
323 test "it creates unconfirmed user" do
324 changeset = User.register_changeset(%User{}, @full_user_data)
325 assert changeset.valid?
326
327 {:ok, user} = Repo.insert(changeset)
328
329 assert user.info.confirmation_pending
330 assert user.info.confirmation_token
331 end
332
333 test "it creates confirmed user if :confirmed option is given" do
334 changeset = User.register_changeset(%User{}, @full_user_data, confirmed: true)
335 assert changeset.valid?
336
337 {:ok, user} = Repo.insert(changeset)
338
339 refute user.info.confirmation_pending
340 refute user.info.confirmation_token
341 end
342 end
343
344 describe "get_or_fetch/1" do
345 test "gets an existing user by nickname" do
346 user = insert(:user)
347 fetched_user = User.get_or_fetch(user.nickname)
348
349 assert user == fetched_user
350 end
351
352 test "gets an existing user by ap_id" do
353 ap_id = "http://mastodon.example.org/users/admin"
354
355 user =
356 insert(
357 :user,
358 local: false,
359 nickname: "admin@mastodon.example.org",
360 ap_id: ap_id,
361 info: %{}
362 )
363
364 fetched_user = User.get_or_fetch(ap_id)
365 freshed_user = refresh_record(user)
366 assert freshed_user == fetched_user
367 end
368 end
369
370 describe "fetching a user from nickname or trying to build one" do
371 test "gets an existing user" do
372 user = insert(:user)
373 fetched_user = User.get_or_fetch_by_nickname(user.nickname)
374
375 assert user == fetched_user
376 end
377
378 test "gets an existing user, case insensitive" do
379 user = insert(:user, nickname: "nick")
380 fetched_user = User.get_or_fetch_by_nickname("NICK")
381
382 assert user == fetched_user
383 end
384
385 test "gets an existing user by fully qualified nickname" do
386 user = insert(:user)
387
388 fetched_user =
389 User.get_or_fetch_by_nickname(user.nickname <> "@" <> Pleroma.Web.Endpoint.host())
390
391 assert user == fetched_user
392 end
393
394 test "gets an existing user by fully qualified nickname, case insensitive" do
395 user = insert(:user, nickname: "nick")
396 casing_altered_fqn = String.upcase(user.nickname <> "@" <> Pleroma.Web.Endpoint.host())
397
398 fetched_user = User.get_or_fetch_by_nickname(casing_altered_fqn)
399
400 assert user == fetched_user
401 end
402
403 test "fetches an external user via ostatus if no user exists" do
404 fetched_user = User.get_or_fetch_by_nickname("shp@social.heldscal.la")
405 assert fetched_user.nickname == "shp@social.heldscal.la"
406 end
407
408 test "returns nil if no user could be fetched" do
409 fetched_user = User.get_or_fetch_by_nickname("nonexistant@social.heldscal.la")
410 assert fetched_user == nil
411 end
412
413 test "returns nil for nonexistant local user" do
414 fetched_user = User.get_or_fetch_by_nickname("nonexistant")
415 assert fetched_user == nil
416 end
417
418 test "updates an existing user, if stale" do
419 a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)
420
421 orig_user =
422 insert(
423 :user,
424 local: false,
425 nickname: "admin@mastodon.example.org",
426 ap_id: "http://mastodon.example.org/users/admin",
427 last_refreshed_at: a_week_ago,
428 info: %{}
429 )
430
431 assert orig_user.last_refreshed_at == a_week_ago
432
433 user = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
434 assert user.info.source_data["endpoints"]
435
436 refute user.last_refreshed_at == orig_user.last_refreshed_at
437 end
438 end
439
440 test "returns an ap_id for a user" do
441 user = insert(:user)
442
443 assert User.ap_id(user) ==
444 Pleroma.Web.Router.Helpers.o_status_url(
445 Pleroma.Web.Endpoint,
446 :feed_redirect,
447 user.nickname
448 )
449 end
450
451 test "returns an ap_followers link for a user" do
452 user = insert(:user)
453
454 assert User.ap_followers(user) ==
455 Pleroma.Web.Router.Helpers.o_status_url(
456 Pleroma.Web.Endpoint,
457 :feed_redirect,
458 user.nickname
459 ) <> "/followers"
460 end
461
462 describe "remote user creation changeset" do
463 @valid_remote %{
464 bio: "hello",
465 name: "Someone",
466 nickname: "a@b.de",
467 ap_id: "http...",
468 info: %{some: "info"},
469 avatar: %{some: "avatar"}
470 }
471
472 test "it confirms validity" do
473 cs = User.remote_user_creation(@valid_remote)
474 assert cs.valid?
475 end
476
477 test "it sets the follower_adress" do
478 cs = User.remote_user_creation(@valid_remote)
479 # remote users get a fake local follower address
480 assert cs.changes.follower_address ==
481 User.ap_followers(%User{nickname: @valid_remote[:nickname]})
482 end
483
484 test "it enforces the fqn format for nicknames" do
485 cs = User.remote_user_creation(%{@valid_remote | nickname: "bla"})
486 assert cs.changes.local == false
487 assert cs.changes.avatar
488 refute cs.valid?
489 end
490
491 test "it has required fields" do
492 [:name, :ap_id]
493 |> Enum.each(fn field ->
494 cs = User.remote_user_creation(Map.delete(@valid_remote, field))
495 refute cs.valid?
496 end)
497 end
498
499 test "it restricts some sizes" do
500 [bio: 5000, name: 100]
501 |> Enum.each(fn {field, size} ->
502 string = String.pad_leading(".", size)
503 cs = User.remote_user_creation(Map.put(@valid_remote, field, string))
504 assert cs.valid?
505
506 string = String.pad_leading(".", size + 1)
507 cs = User.remote_user_creation(Map.put(@valid_remote, field, string))
508 refute cs.valid?
509 end)
510 end
511 end
512
513 describe "followers and friends" do
514 test "gets all followers for a given user" do
515 user = insert(:user)
516 follower_one = insert(:user)
517 follower_two = insert(:user)
518 not_follower = insert(:user)
519
520 {:ok, follower_one} = User.follow(follower_one, user)
521 {:ok, follower_two} = User.follow(follower_two, user)
522
523 {:ok, res} = User.get_followers(user)
524
525 assert Enum.member?(res, follower_one)
526 assert Enum.member?(res, follower_two)
527 refute Enum.member?(res, not_follower)
528 end
529
530 test "gets all friends (followed users) for a given user" do
531 user = insert(:user)
532 followed_one = insert(:user)
533 followed_two = insert(:user)
534 not_followed = insert(:user)
535
536 {:ok, user} = User.follow(user, followed_one)
537 {:ok, user} = User.follow(user, followed_two)
538
539 {:ok, res} = User.get_friends(user)
540
541 followed_one = User.get_by_ap_id(followed_one.ap_id)
542 followed_two = User.get_by_ap_id(followed_two.ap_id)
543 assert Enum.member?(res, followed_one)
544 assert Enum.member?(res, followed_two)
545 refute Enum.member?(res, not_followed)
546 end
547 end
548
549 describe "updating note and follower count" do
550 test "it sets the info->note_count property" do
551 note = insert(:note)
552
553 user = User.get_by_ap_id(note.data["actor"])
554
555 assert user.info.note_count == 0
556
557 {:ok, user} = User.update_note_count(user)
558
559 assert user.info.note_count == 1
560 end
561
562 test "it increases the info->note_count property" do
563 note = insert(:note)
564 user = User.get_by_ap_id(note.data["actor"])
565
566 assert user.info.note_count == 0
567
568 {:ok, user} = User.increase_note_count(user)
569
570 assert user.info.note_count == 1
571
572 {:ok, user} = User.increase_note_count(user)
573
574 assert user.info.note_count == 2
575 end
576
577 test "it decreases the info->note_count property" do
578 note = insert(:note)
579 user = User.get_by_ap_id(note.data["actor"])
580
581 assert user.info.note_count == 0
582
583 {:ok, user} = User.increase_note_count(user)
584
585 assert user.info.note_count == 1
586
587 {:ok, user} = User.decrease_note_count(user)
588
589 assert user.info.note_count == 0
590
591 {:ok, user} = User.decrease_note_count(user)
592
593 assert user.info.note_count == 0
594 end
595
596 test "it sets the info->follower_count property" do
597 user = insert(:user)
598 follower = insert(:user)
599
600 User.follow(follower, user)
601
602 assert user.info.follower_count == 0
603
604 {:ok, user} = User.update_follower_count(user)
605
606 assert user.info.follower_count == 1
607 end
608 end
609
610 describe "follow_import" do
611 test "it imports user followings from list" do
612 [user1, user2, user3] = insert_list(3, :user)
613
614 identifiers = [
615 user2.ap_id,
616 user3.nickname
617 ]
618
619 result = User.follow_import(user1, identifiers)
620 assert is_list(result)
621 assert result == [user2, user3]
622 end
623 end
624
625 describe "mutes" do
626 test "it mutes people" do
627 user = insert(:user)
628 muted_user = insert(:user)
629
630 refute User.mutes?(user, muted_user)
631
632 {:ok, user} = User.mute(user, muted_user)
633
634 assert User.mutes?(user, muted_user)
635 end
636
637 test "it unmutes users" do
638 user = insert(:user)
639 muted_user = insert(:user)
640
641 {:ok, user} = User.mute(user, muted_user)
642 {:ok, user} = User.unmute(user, muted_user)
643
644 refute User.mutes?(user, muted_user)
645 end
646 end
647
648 describe "blocks" do
649 test "it blocks people" do
650 user = insert(:user)
651 blocked_user = insert(:user)
652
653 refute User.blocks?(user, blocked_user)
654
655 {:ok, user} = User.block(user, blocked_user)
656
657 assert User.blocks?(user, blocked_user)
658 end
659
660 test "it unblocks users" do
661 user = insert(:user)
662 blocked_user = insert(:user)
663
664 {:ok, user} = User.block(user, blocked_user)
665 {:ok, user} = User.unblock(user, blocked_user)
666
667 refute User.blocks?(user, blocked_user)
668 end
669
670 test "blocks tear down cyclical follow relationships" do
671 blocker = insert(:user)
672 blocked = insert(:user)
673
674 {:ok, blocker} = User.follow(blocker, blocked)
675 {:ok, blocked} = User.follow(blocked, blocker)
676
677 assert User.following?(blocker, blocked)
678 assert User.following?(blocked, blocker)
679
680 {:ok, blocker} = User.block(blocker, blocked)
681 blocked = Repo.get(User, blocked.id)
682
683 assert User.blocks?(blocker, blocked)
684
685 refute User.following?(blocker, blocked)
686 refute User.following?(blocked, blocker)
687 end
688
689 test "blocks tear down blocker->blocked follow relationships" do
690 blocker = insert(:user)
691 blocked = insert(:user)
692
693 {:ok, blocker} = User.follow(blocker, blocked)
694
695 assert User.following?(blocker, blocked)
696 refute User.following?(blocked, blocker)
697
698 {:ok, blocker} = User.block(blocker, blocked)
699 blocked = Repo.get(User, blocked.id)
700
701 assert User.blocks?(blocker, blocked)
702
703 refute User.following?(blocker, blocked)
704 refute User.following?(blocked, blocker)
705 end
706
707 test "blocks tear down blocked->blocker follow relationships" do
708 blocker = insert(:user)
709 blocked = insert(:user)
710
711 {:ok, blocked} = User.follow(blocked, blocker)
712
713 refute User.following?(blocker, blocked)
714 assert User.following?(blocked, blocker)
715
716 {:ok, blocker} = User.block(blocker, blocked)
717 blocked = Repo.get(User, blocked.id)
718
719 assert User.blocks?(blocker, blocked)
720
721 refute User.following?(blocker, blocked)
722 refute User.following?(blocked, blocker)
723 end
724 end
725
726 describe "domain blocking" do
727 test "blocks domains" do
728 user = insert(:user)
729 collateral_user = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"})
730
731 {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com")
732
733 assert User.blocks?(user, collateral_user)
734 end
735
736 test "unblocks domains" do
737 user = insert(:user)
738 collateral_user = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"})
739
740 {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com")
741 {:ok, user} = User.unblock_domain(user, "awful-and-rude-instance.com")
742
743 refute User.blocks?(user, collateral_user)
744 end
745 end
746
747 describe "blocks_import" do
748 test "it imports user blocks from list" do
749 [user1, user2, user3] = insert_list(3, :user)
750
751 identifiers = [
752 user2.ap_id,
753 user3.nickname
754 ]
755
756 result = User.blocks_import(user1, identifiers)
757 assert is_list(result)
758 assert result == [user2, user3]
759 end
760 end
761
762 test "get recipients from activity" do
763 actor = insert(:user)
764 user = insert(:user, local: true)
765 user_two = insert(:user, local: false)
766 addressed = insert(:user, local: true)
767 addressed_remote = insert(:user, local: false)
768
769 {:ok, activity} =
770 CommonAPI.post(actor, %{
771 "status" => "hey @#{addressed.nickname} @#{addressed_remote.nickname}"
772 })
773
774 assert Enum.map([actor, addressed], & &1.ap_id) --
775 Enum.map(User.get_recipients_from_activity(activity), & &1.ap_id) == []
776
777 {:ok, user} = User.follow(user, actor)
778 {:ok, _user_two} = User.follow(user_two, actor)
779 recipients = User.get_recipients_from_activity(activity)
780 assert length(recipients) == 3
781 assert user in recipients
782 assert addressed in recipients
783 end
784
785 test ".deactivate can de-activate then re-activate a user" do
786 user = insert(:user)
787 assert false == user.info.deactivated
788 {:ok, user} = User.deactivate(user)
789 assert true == user.info.deactivated
790 {:ok, user} = User.deactivate(user, false)
791 assert false == user.info.deactivated
792 end
793
794 test ".delete deactivates a user, all follow relationships and all create activities" do
795 user = insert(:user)
796 followed = insert(:user)
797 follower = insert(:user)
798
799 {:ok, user} = User.follow(user, followed)
800 {:ok, follower} = User.follow(follower, user)
801
802 {:ok, activity} = CommonAPI.post(user, %{"status" => "2hu"})
803 {:ok, activity_two} = CommonAPI.post(follower, %{"status" => "3hu"})
804
805 {:ok, _, _} = CommonAPI.favorite(activity_two.id, user)
806 {:ok, _, _} = CommonAPI.favorite(activity.id, follower)
807 {:ok, _, _} = CommonAPI.repeat(activity.id, follower)
808
809 {:ok, _} = User.delete(user)
810
811 followed = Repo.get(User, followed.id)
812 follower = Repo.get(User, follower.id)
813 user = Repo.get(User, user.id)
814
815 assert user.info.deactivated
816
817 refute User.following?(user, followed)
818 refute User.following?(followed, follower)
819
820 # TODO: Remove favorites, repeats, delete activities.
821
822 refute Repo.get(Activity, activity.id)
823 end
824
825 test "get_public_key_for_ap_id fetches a user that's not in the db" do
826 assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
827 end
828
829 test "insert or update a user from given data" do
830 user = insert(:user, %{nickname: "nick@name.de"})
831 data = %{ap_id: user.ap_id <> "xxx", name: user.name, nickname: user.nickname}
832
833 assert {:ok, %User{}} = User.insert_or_update_user(data)
834 end
835
836 describe "per-user rich-text filtering" do
837 test "html_filter_policy returns default policies, when rich-text is enabled" do
838 user = insert(:user)
839
840 assert Pleroma.Config.get([:markup, :scrub_policy]) == User.html_filter_policy(user)
841 end
842
843 test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do
844 user = insert(:user, %{info: %{no_rich_text: true}})
845
846 assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)
847 end
848 end
849
850 describe "caching" do
851 test "invalidate_cache works" do
852 user = insert(:user)
853 _user_info = User.get_cached_user_info(user)
854
855 User.invalidate_cache(user)
856
857 {:ok, nil} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
858 {:ok, nil} = Cachex.get(:user_cache, "nickname:#{user.nickname}")
859 {:ok, nil} = Cachex.get(:user_cache, "user_info:#{user.id}")
860 end
861
862 test "User.delete() plugs any possible zombie objects" do
863 user = insert(:user)
864
865 {:ok, _} = User.delete(user)
866
867 {:ok, cached_user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
868
869 assert cached_user != user
870
871 {:ok, cached_user} = Cachex.get(:user_cache, "nickname:#{user.ap_id}")
872
873 assert cached_user != user
874 end
875 end
876
877 describe "User.search" do
878 test "finds a user by full or partial nickname" do
879 user = insert(:user, %{nickname: "john"})
880
881 Enum.each(["john", "jo", "j"], fn query ->
882 assert user == User.search(query) |> List.first() |> Map.put(:search_rank, nil)
883 end)
884 end
885
886 test "finds a user by full or partial name" do
887 user = insert(:user, %{name: "John Doe"})
888
889 Enum.each(["John Doe", "JOHN", "doe", "j d", "j", "d"], fn query ->
890 assert user == User.search(query) |> List.first() |> Map.put(:search_rank, nil)
891 end)
892 end
893
894 test "finds users, preferring nickname matches over name matches" do
895 u1 = insert(:user, %{name: "lain", nickname: "nick1"})
896 u2 = insert(:user, %{nickname: "lain", name: "nick1"})
897
898 assert [u2.id, u1.id] == Enum.map(User.search("lain"), & &1.id)
899 end
900
901 test "finds users, considering density of matched tokens" do
902 u1 = insert(:user, %{name: "Bar Bar plus Word Word"})
903 u2 = insert(:user, %{name: "Word Word Bar Bar Bar"})
904
905 assert [u2.id, u1.id] == Enum.map(User.search("bar word"), & &1.id)
906 end
907
908 test "finds users, ranking by similarity" do
909 u1 = insert(:user, %{name: "lain"})
910 _u2 = insert(:user, %{name: "ean"})
911 u3 = insert(:user, %{name: "ebn", nickname: "lain@mastodon.social"})
912 u4 = insert(:user, %{nickname: "lain@pleroma.soykaf.com"})
913
914 assert [u4.id, u3.id, u1.id] == Enum.map(User.search("lain@ple"), & &1.id)
915 end
916
917 test "finds users, handling misspelled requests" do
918 u1 = insert(:user, %{name: "lain"})
919
920 assert [u1.id] == Enum.map(User.search("laiin"), & &1.id)
921 end
922
923 test "finds users, boosting ranks of friends and followers" do
924 u1 = insert(:user)
925 u2 = insert(:user, %{name: "Doe"})
926 follower = insert(:user, %{name: "Doe"})
927 friend = insert(:user, %{name: "Doe"})
928
929 {:ok, follower} = User.follow(follower, u1)
930 {:ok, u1} = User.follow(u1, friend)
931
932 assert [friend.id, follower.id, u2.id] --
933 Enum.map(User.search("doe", resolve: false, for_user: u1), & &1.id) == []
934 end
935
936 test "finds a user whose name is nil" do
937 _user = insert(:user, %{name: "notamatch", nickname: "testuser@pleroma.amplifie.red"})
938 user_two = insert(:user, %{name: nil, nickname: "lain@pleroma.soykaf.com"})
939
940 assert user_two ==
941 User.search("lain@pleroma.soykaf.com")
942 |> List.first()
943 |> Map.put(:search_rank, nil)
944 end
945
946 test "does not yield false-positive matches" do
947 insert(:user, %{name: "John Doe"})
948
949 Enum.each(["mary", "a", ""], fn query ->
950 assert [] == User.search(query)
951 end)
952 end
953
954 test "works with URIs" do
955 results = User.search("http://mastodon.example.org/users/admin", resolve: true)
956 result = results |> List.first()
957
958 user = User.get_by_ap_id("http://mastodon.example.org/users/admin")
959
960 assert length(results) == 1
961 assert user == result |> Map.put(:search_rank, nil)
962 end
963 end
964
965 test "auth_active?/1 works correctly" do
966 Pleroma.Config.put([:instance, :account_activation_required], true)
967
968 local_user = insert(:user, local: true, info: %{confirmation_pending: true})
969 confirmed_user = insert(:user, local: true, info: %{confirmation_pending: false})
970 remote_user = insert(:user, local: false)
971
972 refute User.auth_active?(local_user)
973 assert User.auth_active?(confirmed_user)
974 assert User.auth_active?(remote_user)
975
976 Pleroma.Config.put([:instance, :account_activation_required], false)
977 end
978
979 describe "superuser?/1" do
980 test "returns false for unprivileged users" do
981 user = insert(:user, local: true)
982
983 refute User.superuser?(user)
984 end
985
986 test "returns false for remote users" do
987 user = insert(:user, local: false)
988 remote_admin_user = insert(:user, local: false, info: %{is_admin: true})
989
990 refute User.superuser?(user)
991 refute User.superuser?(remote_admin_user)
992 end
993
994 test "returns true for local moderators" do
995 user = insert(:user, local: true, info: %{is_moderator: true})
996
997 assert User.superuser?(user)
998 end
999
1000 test "returns true for local admins" do
1001 user = insert(:user, local: true, info: %{is_admin: true})
1002
1003 assert User.superuser?(user)
1004 end
1005 end
1006
1007 describe "visible_for?/2" do
1008 test "returns true when the account is itself" do
1009 user = insert(:user, local: true)
1010
1011 assert User.visible_for?(user, user)
1012 end
1013
1014 test "returns false when the account is unauthenticated and auth is required" do
1015 Pleroma.Config.put([:instance, :account_activation_required], true)
1016
1017 user = insert(:user, local: true, info: %{confirmation_pending: true})
1018 other_user = insert(:user, local: true)
1019
1020 refute User.visible_for?(user, other_user)
1021
1022 Pleroma.Config.put([:instance, :account_activation_required], false)
1023 end
1024
1025 test "returns true when the account is unauthenticated and auth is not required" do
1026 user = insert(:user, local: true, info: %{confirmation_pending: true})
1027 other_user = insert(:user, local: true)
1028
1029 assert User.visible_for?(user, other_user)
1030 end
1031
1032 test "returns true when the account is unauthenticated and being viewed by a privileged account (auth required)" do
1033 Pleroma.Config.put([:instance, :account_activation_required], true)
1034
1035 user = insert(:user, local: true, info: %{confirmation_pending: true})
1036 other_user = insert(:user, local: true, info: %{is_admin: true})
1037
1038 assert User.visible_for?(user, other_user)
1039
1040 Pleroma.Config.put([:instance, :account_activation_required], false)
1041 end
1042 end
1043
1044 describe "parse_bio/2" do
1045 test "preserves hosts in user links text" do
1046 remote_user = insert(:user, local: false, nickname: "nick@domain.com")
1047 user = insert(:user)
1048 bio = "A.k.a. @nick@domain.com"
1049
1050 expected_text =
1051 "A.k.a. <span class='h-card'><a data-user='#{remote_user.id}' class='u-url mention' href='#{
1052 remote_user.ap_id
1053 }'>" <> "@<span>nick@domain.com</span></a></span>"
1054
1055 assert expected_text == User.parse_bio(bio, user)
1056 end
1057 end
1058
1059 test "bookmarks" do
1060 user = insert(:user)
1061
1062 {:ok, activity1} =
1063 CommonAPI.post(user, %{
1064 "status" => "heweoo!"
1065 })
1066
1067 id1 = activity1.data["object"]["id"]
1068
1069 {:ok, activity2} =
1070 CommonAPI.post(user, %{
1071 "status" => "heweoo!"
1072 })
1073
1074 id2 = activity2.data["object"]["id"]
1075
1076 assert {:ok, user_state1} = User.bookmark(user, id1)
1077 assert user_state1.bookmarks == [id1]
1078
1079 assert {:ok, user_state2} = User.unbookmark(user, id1)
1080 assert user_state2.bookmarks == []
1081
1082 assert {:ok, user_state3} = User.bookmark(user, id2)
1083 assert user_state3.bookmarks == [id2]
1084 end
1085 end