Merge remote-tracking branch 'origin/develop' into fix-slow-relationships
[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 = User.get_by_id(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 = User.get_by_id(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 = User.get_by_id(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 = User.get_by_id(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 = User.get_by_id(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 = User.get_by_id(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_user_activities deletes all create activities" do
803 user = insert(:user)
804
805 {:ok, activity} = CommonAPI.post(user, %{"status" => "2hu"})
806 {:ok, _} = User.delete_user_activities(user)
807
808 # TODO: Remove favorites, repeats, delete activities.
809 refute Activity.get_by_id(activity.id)
810 end
811
812 test ".delete deactivates a user, all follow relationships and all create activities" do
813 user = insert(:user)
814 followed = insert(:user)
815 follower = insert(:user)
816
817 {:ok, user} = User.follow(user, followed)
818 {:ok, follower} = User.follow(follower, user)
819
820 {:ok, activity} = CommonAPI.post(user, %{"status" => "2hu"})
821 {:ok, activity_two} = CommonAPI.post(follower, %{"status" => "3hu"})
822
823 {:ok, _, _} = CommonAPI.favorite(activity_two.id, user)
824 {:ok, _, _} = CommonAPI.favorite(activity.id, follower)
825 {:ok, _, _} = CommonAPI.repeat(activity.id, follower)
826
827 {:ok, _} = User.delete(user)
828
829 followed = User.get_by_id(followed.id)
830 follower = User.get_by_id(follower.id)
831 user = User.get_by_id(user.id)
832
833 assert user.info.deactivated
834
835 refute User.following?(user, followed)
836 refute User.following?(followed, follower)
837
838 # TODO: Remove favorites, repeats, delete activities.
839
840 refute Activity.get_by_id(activity.id)
841 end
842
843 test "get_public_key_for_ap_id fetches a user that's not in the db" do
844 assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
845 end
846
847 test "insert or update a user from given data" do
848 user = insert(:user, %{nickname: "nick@name.de"})
849 data = %{ap_id: user.ap_id <> "xxx", name: user.name, nickname: user.nickname}
850
851 assert {:ok, %User{}} = User.insert_or_update_user(data)
852 end
853
854 describe "per-user rich-text filtering" do
855 test "html_filter_policy returns default policies, when rich-text is enabled" do
856 user = insert(:user)
857
858 assert Pleroma.Config.get([:markup, :scrub_policy]) == User.html_filter_policy(user)
859 end
860
861 test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do
862 user = insert(:user, %{info: %{no_rich_text: true}})
863
864 assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)
865 end
866 end
867
868 describe "caching" do
869 test "invalidate_cache works" do
870 user = insert(:user)
871 _user_info = User.get_cached_user_info(user)
872
873 User.invalidate_cache(user)
874
875 {:ok, nil} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
876 {:ok, nil} = Cachex.get(:user_cache, "nickname:#{user.nickname}")
877 {:ok, nil} = Cachex.get(:user_cache, "user_info:#{user.id}")
878 end
879
880 test "User.delete() plugs any possible zombie objects" do
881 user = insert(:user)
882
883 {:ok, _} = User.delete(user)
884
885 {:ok, cached_user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
886
887 assert cached_user != user
888
889 {:ok, cached_user} = Cachex.get(:user_cache, "nickname:#{user.ap_id}")
890
891 assert cached_user != user
892 end
893 end
894
895 describe "User.search" do
896 test "finds a user by full or partial nickname" do
897 user = insert(:user, %{nickname: "john"})
898
899 Enum.each(["john", "jo", "j"], fn query ->
900 assert user ==
901 User.search(query)
902 |> List.first()
903 |> Map.put(:search_rank, nil)
904 |> Map.put(:search_type, nil)
905 end)
906 end
907
908 test "finds a user by full or partial name" do
909 user = insert(:user, %{name: "John Doe"})
910
911 Enum.each(["John Doe", "JOHN", "doe", "j d", "j", "d"], fn query ->
912 assert user ==
913 User.search(query)
914 |> List.first()
915 |> Map.put(:search_rank, nil)
916 |> Map.put(:search_type, nil)
917 end)
918 end
919
920 test "finds users, preferring nickname matches over name matches" do
921 u1 = insert(:user, %{name: "lain", nickname: "nick1"})
922 u2 = insert(:user, %{nickname: "lain", name: "nick1"})
923
924 assert [u2.id, u1.id] == Enum.map(User.search("lain"), & &1.id)
925 end
926
927 test "finds users, considering density of matched tokens" do
928 u1 = insert(:user, %{name: "Bar Bar plus Word Word"})
929 u2 = insert(:user, %{name: "Word Word Bar Bar Bar"})
930
931 assert [u2.id, u1.id] == Enum.map(User.search("bar word"), & &1.id)
932 end
933
934 test "finds users, ranking by similarity" do
935 u1 = insert(:user, %{name: "lain"})
936 _u2 = insert(:user, %{name: "ean"})
937 u3 = insert(:user, %{name: "ebn", nickname: "lain@mastodon.social"})
938 u4 = insert(:user, %{nickname: "lain@pleroma.soykaf.com"})
939
940 assert [u4.id, u3.id, u1.id] == Enum.map(User.search("lain@ple"), & &1.id)
941 end
942
943 test "finds users, handling misspelled requests" do
944 u1 = insert(:user, %{name: "lain"})
945
946 assert [u1.id] == Enum.map(User.search("laiin"), & &1.id)
947 end
948
949 test "finds users, boosting ranks of friends and followers" do
950 u1 = insert(:user)
951 u2 = insert(:user, %{name: "Doe"})
952 follower = insert(:user, %{name: "Doe"})
953 friend = insert(:user, %{name: "Doe"})
954
955 {:ok, follower} = User.follow(follower, u1)
956 {:ok, u1} = User.follow(u1, friend)
957
958 assert [friend.id, follower.id, u2.id] --
959 Enum.map(User.search("doe", resolve: false, for_user: u1), & &1.id) == []
960 end
961
962 test "finds a user whose name is nil" do
963 _user = insert(:user, %{name: "notamatch", nickname: "testuser@pleroma.amplifie.red"})
964 user_two = insert(:user, %{name: nil, nickname: "lain@pleroma.soykaf.com"})
965
966 assert user_two ==
967 User.search("lain@pleroma.soykaf.com")
968 |> List.first()
969 |> Map.put(:search_rank, nil)
970 |> Map.put(:search_type, nil)
971 end
972
973 test "does not yield false-positive matches" do
974 insert(:user, %{name: "John Doe"})
975
976 Enum.each(["mary", "a", ""], fn query ->
977 assert [] == User.search(query)
978 end)
979 end
980
981 test "works with URIs" do
982 results = User.search("http://mastodon.example.org/users/admin", resolve: true)
983 result = results |> List.first()
984
985 user = User.get_by_ap_id("http://mastodon.example.org/users/admin")
986
987 assert length(results) == 1
988 assert user == result |> Map.put(:search_rank, nil) |> Map.put(:search_type, nil)
989 end
990 end
991
992 test "auth_active?/1 works correctly" do
993 Pleroma.Config.put([:instance, :account_activation_required], true)
994
995 local_user = insert(:user, local: true, info: %{confirmation_pending: true})
996 confirmed_user = insert(:user, local: true, info: %{confirmation_pending: false})
997 remote_user = insert(:user, local: false)
998
999 refute User.auth_active?(local_user)
1000 assert User.auth_active?(confirmed_user)
1001 assert User.auth_active?(remote_user)
1002
1003 Pleroma.Config.put([:instance, :account_activation_required], false)
1004 end
1005
1006 describe "superuser?/1" do
1007 test "returns false for unprivileged users" do
1008 user = insert(:user, local: true)
1009
1010 refute User.superuser?(user)
1011 end
1012
1013 test "returns false for remote users" do
1014 user = insert(:user, local: false)
1015 remote_admin_user = insert(:user, local: false, info: %{is_admin: true})
1016
1017 refute User.superuser?(user)
1018 refute User.superuser?(remote_admin_user)
1019 end
1020
1021 test "returns true for local moderators" do
1022 user = insert(:user, local: true, info: %{is_moderator: true})
1023
1024 assert User.superuser?(user)
1025 end
1026
1027 test "returns true for local admins" do
1028 user = insert(:user, local: true, info: %{is_admin: true})
1029
1030 assert User.superuser?(user)
1031 end
1032 end
1033
1034 describe "visible_for?/2" do
1035 test "returns true when the account is itself" do
1036 user = insert(:user, local: true)
1037
1038 assert User.visible_for?(user, user)
1039 end
1040
1041 test "returns false when the account is unauthenticated and auth is required" do
1042 Pleroma.Config.put([:instance, :account_activation_required], true)
1043
1044 user = insert(:user, local: true, info: %{confirmation_pending: true})
1045 other_user = insert(:user, local: true)
1046
1047 refute User.visible_for?(user, other_user)
1048
1049 Pleroma.Config.put([:instance, :account_activation_required], false)
1050 end
1051
1052 test "returns true when the account is unauthenticated and auth is not required" do
1053 user = insert(:user, local: true, info: %{confirmation_pending: true})
1054 other_user = insert(:user, local: true)
1055
1056 assert User.visible_for?(user, other_user)
1057 end
1058
1059 test "returns true when the account is unauthenticated and being viewed by a privileged account (auth required)" do
1060 Pleroma.Config.put([:instance, :account_activation_required], true)
1061
1062 user = insert(:user, local: true, info: %{confirmation_pending: true})
1063 other_user = insert(:user, local: true, info: %{is_admin: true})
1064
1065 assert User.visible_for?(user, other_user)
1066
1067 Pleroma.Config.put([:instance, :account_activation_required], false)
1068 end
1069 end
1070
1071 describe "parse_bio/2" do
1072 test "preserves hosts in user links text" do
1073 remote_user = insert(:user, local: false, nickname: "nick@domain.com")
1074 user = insert(:user)
1075 bio = "A.k.a. @nick@domain.com"
1076
1077 expected_text =
1078 "A.k.a. <span class='h-card'><a data-user='#{remote_user.id}' class='u-url mention' href='#{
1079 remote_user.ap_id
1080 }'>" <> "@<span>nick@domain.com</span></a></span>"
1081
1082 assert expected_text == User.parse_bio(bio, user)
1083 end
1084
1085 test "Adds rel=me on linkbacked urls" do
1086 user = insert(:user, ap_id: "http://social.example.org/users/lain")
1087
1088 bio = "http://example.org/rel_me/null"
1089 expected_text = "<a href=\"#{bio}\">#{bio}</a>"
1090 assert expected_text == User.parse_bio(bio, user)
1091
1092 bio = "http://example.org/rel_me/link"
1093 expected_text = "<a href=\"#{bio}\">#{bio}</a>"
1094 assert expected_text == User.parse_bio(bio, user)
1095
1096 bio = "http://example.org/rel_me/anchor"
1097 expected_text = "<a href=\"#{bio}\">#{bio}</a>"
1098 assert expected_text == User.parse_bio(bio, user)
1099 end
1100 end
1101
1102 test "bookmarks" do
1103 user = insert(:user)
1104
1105 {:ok, activity1} =
1106 CommonAPI.post(user, %{
1107 "status" => "heweoo!"
1108 })
1109
1110 id1 = activity1.data["object"]["id"]
1111
1112 {:ok, activity2} =
1113 CommonAPI.post(user, %{
1114 "status" => "heweoo!"
1115 })
1116
1117 id2 = activity2.data["object"]["id"]
1118
1119 assert {:ok, user_state1} = User.bookmark(user, id1)
1120 assert user_state1.bookmarks == [id1]
1121
1122 assert {:ok, user_state2} = User.unbookmark(user, id1)
1123 assert user_state2.bookmarks == []
1124
1125 assert {:ok, user_state3} = User.bookmark(user, id2)
1126 assert user_state3.bookmarks == [id2]
1127 end
1128 end