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