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