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