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