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