Make User.confirm/1 and User.approve/1 idempotent
[akkoma] / test / user_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 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.Object
9 alias Pleroma.Repo
10 alias Pleroma.Tests.ObanHelpers
11 alias Pleroma.User
12 alias Pleroma.Web.ActivityPub.ActivityPub
13 alias Pleroma.Web.CommonAPI
14
15 use Pleroma.DataCase
16 use Oban.Testing, repo: Pleroma.Repo
17
18 import Pleroma.Factory
19 import ExUnit.CaptureLog
20 import Swoosh.TestAssertions
21
22 setup_all do
23 Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
24 :ok
25 end
26
27 setup do: clear_config([:instance, :account_activation_required])
28
29 describe "service actors" do
30 test "returns updated invisible actor" do
31 uri = "#{Pleroma.Web.Endpoint.url()}/relay"
32 followers_uri = "#{uri}/followers"
33
34 insert(
35 :user,
36 %{
37 nickname: "relay",
38 invisible: false,
39 local: true,
40 ap_id: uri,
41 follower_address: followers_uri
42 }
43 )
44
45 actor = User.get_or_create_service_actor_by_ap_id(uri, "relay")
46 assert actor.invisible
47 end
48
49 test "returns relay user" do
50 uri = "#{Pleroma.Web.Endpoint.url()}/relay"
51 followers_uri = "#{uri}/followers"
52
53 assert %User{
54 nickname: "relay",
55 invisible: true,
56 local: true,
57 ap_id: ^uri,
58 follower_address: ^followers_uri
59 } = User.get_or_create_service_actor_by_ap_id(uri, "relay")
60
61 assert capture_log(fn ->
62 refute User.get_or_create_service_actor_by_ap_id("/relay", "relay")
63 end) =~ "Cannot create service actor:"
64 end
65
66 test "returns invisible actor" do
67 uri = "#{Pleroma.Web.Endpoint.url()}/internal/fetch-test"
68 followers_uri = "#{uri}/followers"
69 user = User.get_or_create_service_actor_by_ap_id(uri, "internal.fetch-test")
70
71 assert %User{
72 nickname: "internal.fetch-test",
73 invisible: true,
74 local: true,
75 ap_id: ^uri,
76 follower_address: ^followers_uri
77 } = user
78
79 user2 = User.get_or_create_service_actor_by_ap_id(uri, "internal.fetch-test")
80 assert user.id == user2.id
81 end
82 end
83
84 describe "AP ID user relationships" do
85 setup do
86 {:ok, user: insert(:user)}
87 end
88
89 test "outgoing_relationships_ap_ids/1", %{user: user} do
90 rel_types = [:block, :mute, :notification_mute, :reblog_mute, :inverse_subscription]
91
92 ap_ids_by_rel =
93 Enum.into(
94 rel_types,
95 %{},
96 fn rel_type ->
97 rel_records =
98 insert_list(2, :user_relationship, %{source: user, relationship_type: rel_type})
99
100 ap_ids = Enum.map(rel_records, fn rr -> Repo.preload(rr, :target).target.ap_id end)
101 {rel_type, Enum.sort(ap_ids)}
102 end
103 )
104
105 assert ap_ids_by_rel[:block] == Enum.sort(User.blocked_users_ap_ids(user))
106 assert ap_ids_by_rel[:block] == Enum.sort(Enum.map(User.blocked_users(user), & &1.ap_id))
107
108 assert ap_ids_by_rel[:mute] == Enum.sort(User.muted_users_ap_ids(user))
109 assert ap_ids_by_rel[:mute] == Enum.sort(Enum.map(User.muted_users(user), & &1.ap_id))
110
111 assert ap_ids_by_rel[:notification_mute] ==
112 Enum.sort(User.notification_muted_users_ap_ids(user))
113
114 assert ap_ids_by_rel[:notification_mute] ==
115 Enum.sort(Enum.map(User.notification_muted_users(user), & &1.ap_id))
116
117 assert ap_ids_by_rel[:reblog_mute] == Enum.sort(User.reblog_muted_users_ap_ids(user))
118
119 assert ap_ids_by_rel[:reblog_mute] ==
120 Enum.sort(Enum.map(User.reblog_muted_users(user), & &1.ap_id))
121
122 assert ap_ids_by_rel[:inverse_subscription] == Enum.sort(User.subscriber_users_ap_ids(user))
123
124 assert ap_ids_by_rel[:inverse_subscription] ==
125 Enum.sort(Enum.map(User.subscriber_users(user), & &1.ap_id))
126
127 outgoing_relationships_ap_ids = User.outgoing_relationships_ap_ids(user, rel_types)
128
129 assert ap_ids_by_rel ==
130 Enum.into(outgoing_relationships_ap_ids, %{}, fn {k, v} -> {k, Enum.sort(v)} end)
131 end
132 end
133
134 describe "when tags are nil" do
135 test "tagging a user" do
136 user = insert(:user, %{tags: nil})
137 user = User.tag(user, ["cool", "dude"])
138
139 assert "cool" in user.tags
140 assert "dude" in user.tags
141 end
142
143 test "untagging a user" do
144 user = insert(:user, %{tags: nil})
145 user = User.untag(user, ["cool", "dude"])
146
147 assert user.tags == []
148 end
149 end
150
151 test "ap_id returns the activity pub id for the user" do
152 user = UserBuilder.build()
153
154 expected_ap_id = "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
155
156 assert expected_ap_id == User.ap_id(user)
157 end
158
159 test "ap_followers returns the followers collection for the user" do
160 user = UserBuilder.build()
161
162 expected_followers_collection = "#{User.ap_id(user)}/followers"
163
164 assert expected_followers_collection == User.ap_followers(user)
165 end
166
167 test "ap_following returns the following collection for the user" do
168 user = UserBuilder.build()
169
170 expected_followers_collection = "#{User.ap_id(user)}/following"
171
172 assert expected_followers_collection == User.ap_following(user)
173 end
174
175 test "returns all pending follow requests" do
176 unlocked = insert(:user)
177 locked = insert(:user, locked: true)
178 follower = insert(:user)
179
180 CommonAPI.follow(follower, unlocked)
181 CommonAPI.follow(follower, locked)
182
183 assert [] = User.get_follow_requests(unlocked)
184 assert [activity] = User.get_follow_requests(locked)
185
186 assert activity
187 end
188
189 test "doesn't return already accepted or duplicate follow requests" do
190 locked = insert(:user, locked: true)
191 pending_follower = insert(:user)
192 accepted_follower = insert(:user)
193
194 CommonAPI.follow(pending_follower, locked)
195 CommonAPI.follow(pending_follower, locked)
196 CommonAPI.follow(accepted_follower, locked)
197
198 Pleroma.FollowingRelationship.update(accepted_follower, locked, :follow_accept)
199
200 assert [^pending_follower] = User.get_follow_requests(locked)
201 end
202
203 test "doesn't return follow requests for deactivated accounts" do
204 locked = insert(:user, locked: true)
205 pending_follower = insert(:user, %{deactivated: true})
206
207 CommonAPI.follow(pending_follower, locked)
208
209 assert true == pending_follower.deactivated
210 assert [] = User.get_follow_requests(locked)
211 end
212
213 test "clears follow requests when requester is blocked" do
214 followed = insert(:user, locked: true)
215 follower = insert(:user)
216
217 CommonAPI.follow(follower, followed)
218 assert [_activity] = User.get_follow_requests(followed)
219
220 {:ok, _user_relationship} = User.block(followed, follower)
221 assert [] = User.get_follow_requests(followed)
222 end
223
224 test "follow_all follows mutliple users" do
225 user = insert(:user)
226 followed_zero = insert(:user)
227 followed_one = insert(:user)
228 followed_two = insert(:user)
229 blocked = insert(:user)
230 not_followed = insert(:user)
231 reverse_blocked = insert(:user)
232
233 {:ok, _user_relationship} = User.block(user, blocked)
234 {:ok, _user_relationship} = User.block(reverse_blocked, user)
235
236 {:ok, user} = User.follow(user, followed_zero)
237
238 {:ok, user} = User.follow_all(user, [followed_one, followed_two, blocked, reverse_blocked])
239
240 assert User.following?(user, followed_one)
241 assert User.following?(user, followed_two)
242 assert User.following?(user, followed_zero)
243 refute User.following?(user, not_followed)
244 refute User.following?(user, blocked)
245 refute User.following?(user, reverse_blocked)
246 end
247
248 test "follow_all follows mutliple users without duplicating" do
249 user = insert(:user)
250 followed_zero = insert(:user)
251 followed_one = insert(:user)
252 followed_two = insert(:user)
253
254 {:ok, user} = User.follow_all(user, [followed_zero, followed_one])
255 assert length(User.following(user)) == 3
256
257 {:ok, user} = User.follow_all(user, [followed_one, followed_two])
258 assert length(User.following(user)) == 4
259 end
260
261 test "follow takes a user and another user" do
262 user = insert(:user)
263 followed = insert(:user)
264
265 {:ok, user} = User.follow(user, followed)
266
267 user = User.get_cached_by_id(user.id)
268 followed = User.get_cached_by_ap_id(followed.ap_id)
269
270 assert followed.follower_count == 1
271 assert user.following_count == 1
272
273 assert User.ap_followers(followed) in User.following(user)
274 end
275
276 test "can't follow a deactivated users" do
277 user = insert(:user)
278 followed = insert(:user, %{deactivated: true})
279
280 {:error, _} = User.follow(user, followed)
281 end
282
283 test "can't follow a user who blocked us" do
284 blocker = insert(:user)
285 blockee = insert(:user)
286
287 {:ok, _user_relationship} = User.block(blocker, blockee)
288
289 {:error, _} = User.follow(blockee, blocker)
290 end
291
292 test "can't subscribe to a user who blocked us" do
293 blocker = insert(:user)
294 blocked = insert(:user)
295
296 {:ok, _user_relationship} = User.block(blocker, blocked)
297
298 {:error, _} = User.subscribe(blocked, blocker)
299 end
300
301 test "local users do not automatically follow local locked accounts" do
302 follower = insert(:user, locked: true)
303 followed = insert(:user, locked: true)
304
305 {:ok, follower} = User.maybe_direct_follow(follower, followed)
306
307 refute User.following?(follower, followed)
308 end
309
310 describe "unfollow/2" do
311 setup do: clear_config([:instance, :external_user_synchronization])
312
313 test "unfollow with syncronizes external user" do
314 Pleroma.Config.put([:instance, :external_user_synchronization], true)
315
316 followed =
317 insert(:user,
318 nickname: "fuser1",
319 follower_address: "http://localhost:4001/users/fuser1/followers",
320 following_address: "http://localhost:4001/users/fuser1/following",
321 ap_id: "http://localhost:4001/users/fuser1"
322 )
323
324 user =
325 insert(:user, %{
326 local: false,
327 nickname: "fuser2",
328 ap_id: "http://localhost:4001/users/fuser2",
329 follower_address: "http://localhost:4001/users/fuser2/followers",
330 following_address: "http://localhost:4001/users/fuser2/following"
331 })
332
333 {:ok, user} = User.follow(user, followed, :follow_accept)
334
335 {:ok, user, _activity} = User.unfollow(user, followed)
336
337 user = User.get_cached_by_id(user.id)
338
339 assert User.following(user) == []
340 end
341
342 test "unfollow takes a user and another user" do
343 followed = insert(:user)
344 user = insert(:user)
345
346 {:ok, user} = User.follow(user, followed, :follow_accept)
347
348 assert User.following(user) == [user.follower_address, followed.follower_address]
349
350 {:ok, user, _activity} = User.unfollow(user, followed)
351
352 assert User.following(user) == [user.follower_address]
353 end
354
355 test "unfollow doesn't unfollow yourself" do
356 user = insert(:user)
357
358 {:error, _} = User.unfollow(user, user)
359
360 assert User.following(user) == [user.follower_address]
361 end
362 end
363
364 test "test if a user is following another user" do
365 followed = insert(:user)
366 user = insert(:user)
367 User.follow(user, followed, :follow_accept)
368
369 assert User.following?(user, followed)
370 refute User.following?(followed, user)
371 end
372
373 test "fetches correct profile for nickname beginning with number" do
374 # Use old-style integer ID to try to reproduce the problem
375 user = insert(:user, %{id: 1080})
376 user_with_numbers = insert(:user, %{nickname: "#{user.id}garbage"})
377 assert user_with_numbers == User.get_cached_by_nickname_or_id(user_with_numbers.nickname)
378 end
379
380 describe "user registration" do
381 @full_user_data %{
382 bio: "A guy",
383 name: "my name",
384 nickname: "nick",
385 password: "test",
386 password_confirmation: "test",
387 email: "email@example.com"
388 }
389
390 setup do: clear_config([:instance, :autofollowed_nicknames])
391 setup do: clear_config([:welcome])
392 setup do: clear_config([:instance, :account_activation_required])
393
394 test "it autofollows accounts that are set for it" do
395 user = insert(:user)
396 remote_user = insert(:user, %{local: false})
397
398 Pleroma.Config.put([:instance, :autofollowed_nicknames], [
399 user.nickname,
400 remote_user.nickname
401 ])
402
403 cng = User.register_changeset(%User{}, @full_user_data)
404
405 {:ok, registered_user} = User.register(cng)
406
407 assert User.following?(registered_user, user)
408 refute User.following?(registered_user, remote_user)
409 end
410
411 test "it sends a welcome message if it is set" do
412 welcome_user = insert(:user)
413 Pleroma.Config.put([:welcome, :direct_message, :enabled], true)
414 Pleroma.Config.put([:welcome, :direct_message, :sender_nickname], welcome_user.nickname)
415 Pleroma.Config.put([:welcome, :direct_message, :message], "Hello, this is a direct message")
416
417 cng = User.register_changeset(%User{}, @full_user_data)
418 {:ok, registered_user} = User.register(cng)
419 ObanHelpers.perform_all()
420
421 activity = Repo.one(Pleroma.Activity)
422 assert registered_user.ap_id in activity.recipients
423 assert Object.normalize(activity).data["content"] =~ "direct message"
424 assert activity.actor == welcome_user.ap_id
425 end
426
427 test "it sends a welcome chat message if it is set" do
428 welcome_user = insert(:user)
429 Pleroma.Config.put([:welcome, :chat_message, :enabled], true)
430 Pleroma.Config.put([:welcome, :chat_message, :sender_nickname], welcome_user.nickname)
431 Pleroma.Config.put([:welcome, :chat_message, :message], "Hello, this is a chat message")
432
433 cng = User.register_changeset(%User{}, @full_user_data)
434 {:ok, registered_user} = User.register(cng)
435 ObanHelpers.perform_all()
436
437 activity = Repo.one(Pleroma.Activity)
438 assert registered_user.ap_id in activity.recipients
439 assert Object.normalize(activity).data["content"] =~ "chat message"
440 assert activity.actor == welcome_user.ap_id
441 end
442
443 setup do:
444 clear_config(:mrf_simple,
445 media_removal: [],
446 media_nsfw: [],
447 federated_timeline_removal: [],
448 report_removal: [],
449 reject: [],
450 followers_only: [],
451 accept: [],
452 avatar_removal: [],
453 banner_removal: [],
454 reject_deletes: []
455 )
456
457 setup do:
458 clear_config(:mrf,
459 policies: [
460 Pleroma.Web.ActivityPub.MRF.SimplePolicy
461 ]
462 )
463
464 test "it sends a welcome chat message when Simple policy applied to local instance" do
465 Pleroma.Config.put([:mrf_simple, :media_nsfw], ["localhost"])
466
467 welcome_user = insert(:user)
468 Pleroma.Config.put([:welcome, :chat_message, :enabled], true)
469 Pleroma.Config.put([:welcome, :chat_message, :sender_nickname], welcome_user.nickname)
470 Pleroma.Config.put([:welcome, :chat_message, :message], "Hello, this is a chat message")
471
472 cng = User.register_changeset(%User{}, @full_user_data)
473 {:ok, registered_user} = User.register(cng)
474 ObanHelpers.perform_all()
475
476 activity = Repo.one(Pleroma.Activity)
477 assert registered_user.ap_id in activity.recipients
478 assert Object.normalize(activity).data["content"] =~ "chat message"
479 assert activity.actor == welcome_user.ap_id
480 end
481
482 test "it sends a welcome email message if it is set" do
483 welcome_user = insert(:user)
484 Pleroma.Config.put([:welcome, :email, :enabled], true)
485 Pleroma.Config.put([:welcome, :email, :sender], welcome_user.email)
486
487 Pleroma.Config.put(
488 [:welcome, :email, :subject],
489 "Hello, welcome to cool site: <%= instance_name %>"
490 )
491
492 instance_name = Pleroma.Config.get([:instance, :name])
493
494 cng = User.register_changeset(%User{}, @full_user_data)
495 {:ok, registered_user} = User.register(cng)
496 ObanHelpers.perform_all()
497
498 assert_email_sent(
499 from: {instance_name, welcome_user.email},
500 to: {registered_user.name, registered_user.email},
501 subject: "Hello, welcome to cool site: #{instance_name}",
502 html_body: "Welcome to #{instance_name}"
503 )
504 end
505
506 test "it sends a confirm email" do
507 Pleroma.Config.put([:instance, :account_activation_required], true)
508
509 cng = User.register_changeset(%User{}, @full_user_data)
510 {:ok, registered_user} = User.register(cng)
511 ObanHelpers.perform_all()
512
513 Pleroma.Emails.UserEmail.account_confirmation_email(registered_user)
514 # temporary hackney fix until hackney max_connections bug is fixed
515 # https://git.pleroma.social/pleroma/pleroma/-/issues/2101
516 |> Swoosh.Email.put_private(:hackney_options, ssl_options: [versions: [:"tlsv1.2"]])
517 |> assert_email_sent()
518 end
519
520 test "sends a pending approval email" do
521 clear_config([:instance, :account_approval_required], true)
522
523 {:ok, user} =
524 User.register_changeset(%User{}, @full_user_data)
525 |> User.register()
526
527 ObanHelpers.perform_all()
528
529 assert_email_sent(
530 from: Pleroma.Config.Helpers.sender(),
531 to: {user.name, user.email},
532 subject: "Your account is awaiting approval"
533 )
534 end
535
536 test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do
537 Pleroma.Config.put([:instance, :account_activation_required], true)
538
539 @full_user_data
540 |> Map.keys()
541 |> Enum.each(fn key ->
542 params = Map.delete(@full_user_data, key)
543 changeset = User.register_changeset(%User{}, params)
544
545 assert if key == :bio, do: changeset.valid?, else: not changeset.valid?
546 end)
547 end
548
549 test "it requires an name, nickname and password, bio and email are optional when account_activation_required is disabled" do
550 Pleroma.Config.put([:instance, :account_activation_required], false)
551
552 @full_user_data
553 |> Map.keys()
554 |> Enum.each(fn key ->
555 params = Map.delete(@full_user_data, key)
556 changeset = User.register_changeset(%User{}, params)
557
558 assert if key in [:bio, :email], do: changeset.valid?, else: not changeset.valid?
559 end)
560 end
561
562 test "it restricts certain nicknames" do
563 [restricted_name | _] = Pleroma.Config.get([User, :restricted_nicknames])
564
565 assert is_bitstring(restricted_name)
566
567 params =
568 @full_user_data
569 |> Map.put(:nickname, restricted_name)
570
571 changeset = User.register_changeset(%User{}, params)
572
573 refute changeset.valid?
574 end
575
576 test "it blocks blacklisted email domains" do
577 clear_config([User, :email_blacklist], ["trolling.world"])
578
579 # Block with match
580 params = Map.put(@full_user_data, :email, "troll@trolling.world")
581 changeset = User.register_changeset(%User{}, params)
582 refute changeset.valid?
583
584 # Block with subdomain match
585 params = Map.put(@full_user_data, :email, "troll@gnomes.trolling.world")
586 changeset = User.register_changeset(%User{}, params)
587 refute changeset.valid?
588
589 # Pass with different domains that are similar
590 params = Map.put(@full_user_data, :email, "troll@gnomestrolling.world")
591 changeset = User.register_changeset(%User{}, params)
592 assert changeset.valid?
593
594 params = Map.put(@full_user_data, :email, "troll@trolling.world.us")
595 changeset = User.register_changeset(%User{}, params)
596 assert changeset.valid?
597 end
598
599 test "it sets the password_hash and ap_id" do
600 changeset = User.register_changeset(%User{}, @full_user_data)
601
602 assert changeset.valid?
603
604 assert is_binary(changeset.changes[:password_hash])
605 assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname})
606
607 assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
608 end
609
610 test "it sets the 'accepts_chat_messages' set to true" do
611 changeset = User.register_changeset(%User{}, @full_user_data)
612 assert changeset.valid?
613
614 {:ok, user} = Repo.insert(changeset)
615
616 assert user.accepts_chat_messages
617 end
618
619 test "it creates a confirmed user" do
620 changeset = User.register_changeset(%User{}, @full_user_data)
621 assert changeset.valid?
622
623 {:ok, user} = Repo.insert(changeset)
624
625 refute user.confirmation_pending
626 end
627 end
628
629 describe "user registration, with :account_activation_required" do
630 @full_user_data %{
631 bio: "A guy",
632 name: "my name",
633 nickname: "nick",
634 password: "test",
635 password_confirmation: "test",
636 email: "email@example.com"
637 }
638 setup do: clear_config([:instance, :account_activation_required], true)
639
640 test "it creates unconfirmed user" do
641 changeset = User.register_changeset(%User{}, @full_user_data)
642 assert changeset.valid?
643
644 {:ok, user} = Repo.insert(changeset)
645
646 assert user.confirmation_pending
647 assert user.confirmation_token
648 end
649
650 test "it creates confirmed user if :confirmed option is given" do
651 changeset = User.register_changeset(%User{}, @full_user_data, need_confirmation: false)
652 assert changeset.valid?
653
654 {:ok, user} = Repo.insert(changeset)
655
656 refute user.confirmation_pending
657 refute user.confirmation_token
658 end
659 end
660
661 describe "user registration, with :account_approval_required" do
662 @full_user_data %{
663 bio: "A guy",
664 name: "my name",
665 nickname: "nick",
666 password: "test",
667 password_confirmation: "test",
668 email: "email@example.com",
669 registration_reason: "I'm a cool guy :)"
670 }
671 setup do: clear_config([:instance, :account_approval_required], true)
672
673 test "it creates unapproved user" do
674 changeset = User.register_changeset(%User{}, @full_user_data)
675 assert changeset.valid?
676
677 {:ok, user} = Repo.insert(changeset)
678
679 assert user.approval_pending
680 assert user.registration_reason == "I'm a cool guy :)"
681 end
682
683 test "it restricts length of registration reason" do
684 reason_limit = Pleroma.Config.get([:instance, :registration_reason_length])
685
686 assert is_integer(reason_limit)
687
688 params =
689 @full_user_data
690 |> Map.put(
691 :registration_reason,
692 "Quia et nesciunt dolores numquam ipsam nisi sapiente soluta. Ullam repudiandae nisi quam porro officiis officiis ad. Consequatur animi velit ex quia. Odit voluptatem perferendis quia ut nisi. Dignissimos sit soluta atque aliquid dolorem ut dolorum ut. Labore voluptates iste iusto amet voluptatum earum. Ad fugit illum nam eos ut nemo. Pariatur ea fuga non aspernatur. Dignissimos debitis officia corporis est nisi ab et. Atque itaque alias eius voluptas minus. Accusamus numquam tempore occaecati in."
693 )
694
695 changeset = User.register_changeset(%User{}, params)
696
697 refute changeset.valid?
698 end
699 end
700
701 describe "get_or_fetch/1" do
702 test "gets an existing user by nickname" do
703 user = insert(:user)
704 {:ok, fetched_user} = User.get_or_fetch(user.nickname)
705
706 assert user == fetched_user
707 end
708
709 test "gets an existing user by ap_id" do
710 ap_id = "http://mastodon.example.org/users/admin"
711
712 user =
713 insert(
714 :user,
715 local: false,
716 nickname: "admin@mastodon.example.org",
717 ap_id: ap_id
718 )
719
720 {:ok, fetched_user} = User.get_or_fetch(ap_id)
721 freshed_user = refresh_record(user)
722 assert freshed_user == fetched_user
723 end
724 end
725
726 describe "fetching a user from nickname or trying to build one" do
727 test "gets an existing user" do
728 user = insert(:user)
729 {:ok, fetched_user} = User.get_or_fetch_by_nickname(user.nickname)
730
731 assert user == fetched_user
732 end
733
734 test "gets an existing user, case insensitive" do
735 user = insert(:user, nickname: "nick")
736 {:ok, fetched_user} = User.get_or_fetch_by_nickname("NICK")
737
738 assert user == fetched_user
739 end
740
741 test "gets an existing user by fully qualified nickname" do
742 user = insert(:user)
743
744 {:ok, fetched_user} =
745 User.get_or_fetch_by_nickname(user.nickname <> "@" <> Pleroma.Web.Endpoint.host())
746
747 assert user == fetched_user
748 end
749
750 test "gets an existing user by fully qualified nickname, case insensitive" do
751 user = insert(:user, nickname: "nick")
752 casing_altered_fqn = String.upcase(user.nickname <> "@" <> Pleroma.Web.Endpoint.host())
753
754 {:ok, fetched_user} = User.get_or_fetch_by_nickname(casing_altered_fqn)
755
756 assert user == fetched_user
757 end
758
759 @tag capture_log: true
760 test "returns nil if no user could be fetched" do
761 {:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistant@social.heldscal.la")
762 assert fetched_user == "not found nonexistant@social.heldscal.la"
763 end
764
765 test "returns nil for nonexistant local user" do
766 {:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistant")
767 assert fetched_user == "not found nonexistant"
768 end
769
770 test "updates an existing user, if stale" do
771 a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)
772
773 orig_user =
774 insert(
775 :user,
776 local: false,
777 nickname: "admin@mastodon.example.org",
778 ap_id: "http://mastodon.example.org/users/admin",
779 last_refreshed_at: a_week_ago
780 )
781
782 assert orig_user.last_refreshed_at == a_week_ago
783
784 {:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
785
786 assert user.inbox
787
788 refute user.last_refreshed_at == orig_user.last_refreshed_at
789 end
790
791 test "if nicknames clash, the old user gets a prefix with the old id to the nickname" do
792 a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)
793
794 orig_user =
795 insert(
796 :user,
797 local: false,
798 nickname: "admin@mastodon.example.org",
799 ap_id: "http://mastodon.example.org/users/harinezumigari",
800 last_refreshed_at: a_week_ago
801 )
802
803 assert orig_user.last_refreshed_at == a_week_ago
804
805 {:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
806
807 assert user.inbox
808
809 refute user.id == orig_user.id
810
811 orig_user = User.get_by_id(orig_user.id)
812
813 assert orig_user.nickname == "#{orig_user.id}.admin@mastodon.example.org"
814 end
815
816 @tag capture_log: true
817 test "it returns the old user if stale, but unfetchable" do
818 a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)
819
820 orig_user =
821 insert(
822 :user,
823 local: false,
824 nickname: "admin@mastodon.example.org",
825 ap_id: "http://mastodon.example.org/users/raymoo",
826 last_refreshed_at: a_week_ago
827 )
828
829 assert orig_user.last_refreshed_at == a_week_ago
830
831 {:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/raymoo")
832
833 assert user.last_refreshed_at == orig_user.last_refreshed_at
834 end
835 end
836
837 test "returns an ap_id for a user" do
838 user = insert(:user)
839
840 assert User.ap_id(user) ==
841 Pleroma.Web.Router.Helpers.user_feed_url(
842 Pleroma.Web.Endpoint,
843 :feed_redirect,
844 user.nickname
845 )
846 end
847
848 test "returns an ap_followers link for a user" do
849 user = insert(:user)
850
851 assert User.ap_followers(user) ==
852 Pleroma.Web.Router.Helpers.user_feed_url(
853 Pleroma.Web.Endpoint,
854 :feed_redirect,
855 user.nickname
856 ) <> "/followers"
857 end
858
859 describe "remote user changeset" do
860 @valid_remote %{
861 bio: "hello",
862 name: "Someone",
863 nickname: "a@b.de",
864 ap_id: "http...",
865 avatar: %{some: "avatar"}
866 }
867 setup do: clear_config([:instance, :user_bio_length])
868 setup do: clear_config([:instance, :user_name_length])
869
870 test "it confirms validity" do
871 cs = User.remote_user_changeset(@valid_remote)
872 assert cs.valid?
873 end
874
875 test "it sets the follower_adress" do
876 cs = User.remote_user_changeset(@valid_remote)
877 # remote users get a fake local follower address
878 assert cs.changes.follower_address ==
879 User.ap_followers(%User{nickname: @valid_remote[:nickname]})
880 end
881
882 test "it enforces the fqn format for nicknames" do
883 cs = User.remote_user_changeset(%{@valid_remote | nickname: "bla"})
884 assert Ecto.Changeset.get_field(cs, :local) == false
885 assert cs.changes.avatar
886 refute cs.valid?
887 end
888
889 test "it has required fields" do
890 [:ap_id]
891 |> Enum.each(fn field ->
892 cs = User.remote_user_changeset(Map.delete(@valid_remote, field))
893 refute cs.valid?
894 end)
895 end
896 end
897
898 describe "followers and friends" do
899 test "gets all followers for a given user" do
900 user = insert(:user)
901 follower_one = insert(:user)
902 follower_two = insert(:user)
903 not_follower = insert(:user)
904
905 {:ok, follower_one} = User.follow(follower_one, user)
906 {:ok, follower_two} = User.follow(follower_two, user)
907
908 res = User.get_followers(user)
909
910 assert Enum.member?(res, follower_one)
911 assert Enum.member?(res, follower_two)
912 refute Enum.member?(res, not_follower)
913 end
914
915 test "gets all friends (followed users) for a given user" do
916 user = insert(:user)
917 followed_one = insert(:user)
918 followed_two = insert(:user)
919 not_followed = insert(:user)
920
921 {:ok, user} = User.follow(user, followed_one)
922 {:ok, user} = User.follow(user, followed_two)
923
924 res = User.get_friends(user)
925
926 followed_one = User.get_cached_by_ap_id(followed_one.ap_id)
927 followed_two = User.get_cached_by_ap_id(followed_two.ap_id)
928 assert Enum.member?(res, followed_one)
929 assert Enum.member?(res, followed_two)
930 refute Enum.member?(res, not_followed)
931 end
932 end
933
934 describe "updating note and follower count" do
935 test "it sets the note_count property" do
936 note = insert(:note)
937
938 user = User.get_cached_by_ap_id(note.data["actor"])
939
940 assert user.note_count == 0
941
942 {:ok, user} = User.update_note_count(user)
943
944 assert user.note_count == 1
945 end
946
947 test "it increases the note_count property" do
948 note = insert(:note)
949 user = User.get_cached_by_ap_id(note.data["actor"])
950
951 assert user.note_count == 0
952
953 {:ok, user} = User.increase_note_count(user)
954
955 assert user.note_count == 1
956
957 {:ok, user} = User.increase_note_count(user)
958
959 assert user.note_count == 2
960 end
961
962 test "it decreases the note_count property" do
963 note = insert(:note)
964 user = User.get_cached_by_ap_id(note.data["actor"])
965
966 assert user.note_count == 0
967
968 {:ok, user} = User.increase_note_count(user)
969
970 assert user.note_count == 1
971
972 {:ok, user} = User.decrease_note_count(user)
973
974 assert user.note_count == 0
975
976 {:ok, user} = User.decrease_note_count(user)
977
978 assert user.note_count == 0
979 end
980
981 test "it sets the follower_count property" do
982 user = insert(:user)
983 follower = insert(:user)
984
985 User.follow(follower, user)
986
987 assert user.follower_count == 0
988
989 {:ok, user} = User.update_follower_count(user)
990
991 assert user.follower_count == 1
992 end
993 end
994
995 describe "mutes" do
996 test "it mutes people" do
997 user = insert(:user)
998 muted_user = insert(:user)
999
1000 refute User.mutes?(user, muted_user)
1001 refute User.muted_notifications?(user, muted_user)
1002
1003 {:ok, _user_relationships} = User.mute(user, muted_user)
1004
1005 assert User.mutes?(user, muted_user)
1006 assert User.muted_notifications?(user, muted_user)
1007 end
1008
1009 test "it unmutes users" do
1010 user = insert(:user)
1011 muted_user = insert(:user)
1012
1013 {:ok, _user_relationships} = User.mute(user, muted_user)
1014 {:ok, _user_mute} = User.unmute(user, muted_user)
1015
1016 refute User.mutes?(user, muted_user)
1017 refute User.muted_notifications?(user, muted_user)
1018 end
1019
1020 test "it mutes user without notifications" do
1021 user = insert(:user)
1022 muted_user = insert(:user)
1023
1024 refute User.mutes?(user, muted_user)
1025 refute User.muted_notifications?(user, muted_user)
1026
1027 {:ok, _user_relationships} = User.mute(user, muted_user, false)
1028
1029 assert User.mutes?(user, muted_user)
1030 refute User.muted_notifications?(user, muted_user)
1031 end
1032 end
1033
1034 describe "blocks" do
1035 test "it blocks people" do
1036 user = insert(:user)
1037 blocked_user = insert(:user)
1038
1039 refute User.blocks?(user, blocked_user)
1040
1041 {:ok, _user_relationship} = User.block(user, blocked_user)
1042
1043 assert User.blocks?(user, blocked_user)
1044 end
1045
1046 test "it unblocks users" do
1047 user = insert(:user)
1048 blocked_user = insert(:user)
1049
1050 {:ok, _user_relationship} = User.block(user, blocked_user)
1051 {:ok, _user_block} = User.unblock(user, blocked_user)
1052
1053 refute User.blocks?(user, blocked_user)
1054 end
1055
1056 test "blocks tear down cyclical follow relationships" do
1057 blocker = insert(:user)
1058 blocked = insert(:user)
1059
1060 {:ok, blocker} = User.follow(blocker, blocked)
1061 {:ok, blocked} = User.follow(blocked, blocker)
1062
1063 assert User.following?(blocker, blocked)
1064 assert User.following?(blocked, blocker)
1065
1066 {:ok, _user_relationship} = User.block(blocker, blocked)
1067 blocked = User.get_cached_by_id(blocked.id)
1068
1069 assert User.blocks?(blocker, blocked)
1070
1071 refute User.following?(blocker, blocked)
1072 refute User.following?(blocked, blocker)
1073 end
1074
1075 test "blocks tear down blocker->blocked follow relationships" do
1076 blocker = insert(:user)
1077 blocked = insert(:user)
1078
1079 {:ok, blocker} = User.follow(blocker, blocked)
1080
1081 assert User.following?(blocker, blocked)
1082 refute User.following?(blocked, blocker)
1083
1084 {:ok, _user_relationship} = User.block(blocker, blocked)
1085 blocked = User.get_cached_by_id(blocked.id)
1086
1087 assert User.blocks?(blocker, blocked)
1088
1089 refute User.following?(blocker, blocked)
1090 refute User.following?(blocked, blocker)
1091 end
1092
1093 test "blocks tear down blocked->blocker follow relationships" do
1094 blocker = insert(:user)
1095 blocked = insert(:user)
1096
1097 {:ok, blocked} = User.follow(blocked, blocker)
1098
1099 refute User.following?(blocker, blocked)
1100 assert User.following?(blocked, blocker)
1101
1102 {:ok, _user_relationship} = User.block(blocker, blocked)
1103 blocked = User.get_cached_by_id(blocked.id)
1104
1105 assert User.blocks?(blocker, blocked)
1106
1107 refute User.following?(blocker, blocked)
1108 refute User.following?(blocked, blocker)
1109 end
1110
1111 test "blocks tear down blocked->blocker subscription relationships" do
1112 blocker = insert(:user)
1113 blocked = insert(:user)
1114
1115 {:ok, _subscription} = User.subscribe(blocked, blocker)
1116
1117 assert User.subscribed_to?(blocked, blocker)
1118 refute User.subscribed_to?(blocker, blocked)
1119
1120 {:ok, _user_relationship} = User.block(blocker, blocked)
1121
1122 assert User.blocks?(blocker, blocked)
1123 refute User.subscribed_to?(blocker, blocked)
1124 refute User.subscribed_to?(blocked, blocker)
1125 end
1126 end
1127
1128 describe "domain blocking" do
1129 test "blocks domains" do
1130 user = insert(:user)
1131 collateral_user = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"})
1132
1133 {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com")
1134
1135 assert User.blocks?(user, collateral_user)
1136 end
1137
1138 test "does not block domain with same end" do
1139 user = insert(:user)
1140
1141 collateral_user =
1142 insert(:user, %{ap_id: "https://another-awful-and-rude-instance.com/user/bully"})
1143
1144 {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com")
1145
1146 refute User.blocks?(user, collateral_user)
1147 end
1148
1149 test "does not block domain with same end if wildcard added" do
1150 user = insert(:user)
1151
1152 collateral_user =
1153 insert(:user, %{ap_id: "https://another-awful-and-rude-instance.com/user/bully"})
1154
1155 {:ok, user} = User.block_domain(user, "*.awful-and-rude-instance.com")
1156
1157 refute User.blocks?(user, collateral_user)
1158 end
1159
1160 test "blocks domain with wildcard for subdomain" do
1161 user = insert(:user)
1162
1163 user_from_subdomain =
1164 insert(:user, %{ap_id: "https://subdomain.awful-and-rude-instance.com/user/bully"})
1165
1166 user_with_two_subdomains =
1167 insert(:user, %{
1168 ap_id: "https://subdomain.second_subdomain.awful-and-rude-instance.com/user/bully"
1169 })
1170
1171 user_domain = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"})
1172
1173 {:ok, user} = User.block_domain(user, "*.awful-and-rude-instance.com")
1174
1175 assert User.blocks?(user, user_from_subdomain)
1176 assert User.blocks?(user, user_with_two_subdomains)
1177 assert User.blocks?(user, user_domain)
1178 end
1179
1180 test "unblocks domains" do
1181 user = insert(:user)
1182 collateral_user = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"})
1183
1184 {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com")
1185 {:ok, user} = User.unblock_domain(user, "awful-and-rude-instance.com")
1186
1187 refute User.blocks?(user, collateral_user)
1188 end
1189
1190 test "follows take precedence over domain blocks" do
1191 user = insert(:user)
1192 good_eggo = insert(:user, %{ap_id: "https://meanies.social/user/cuteposter"})
1193
1194 {:ok, user} = User.block_domain(user, "meanies.social")
1195 {:ok, user} = User.follow(user, good_eggo)
1196
1197 refute User.blocks?(user, good_eggo)
1198 end
1199 end
1200
1201 describe "get_recipients_from_activity" do
1202 test "works for announces" do
1203 actor = insert(:user)
1204 user = insert(:user, local: true)
1205
1206 {:ok, activity} = CommonAPI.post(actor, %{status: "hello"})
1207 {:ok, announce} = CommonAPI.repeat(activity.id, user)
1208
1209 recipients = User.get_recipients_from_activity(announce)
1210
1211 assert user in recipients
1212 end
1213
1214 test "get recipients" do
1215 actor = insert(:user)
1216 user = insert(:user, local: true)
1217 user_two = insert(:user, local: false)
1218 addressed = insert(:user, local: true)
1219 addressed_remote = insert(:user, local: false)
1220
1221 {:ok, activity} =
1222 CommonAPI.post(actor, %{
1223 status: "hey @#{addressed.nickname} @#{addressed_remote.nickname}"
1224 })
1225
1226 assert Enum.map([actor, addressed], & &1.ap_id) --
1227 Enum.map(User.get_recipients_from_activity(activity), & &1.ap_id) == []
1228
1229 {:ok, user} = User.follow(user, actor)
1230 {:ok, _user_two} = User.follow(user_two, actor)
1231 recipients = User.get_recipients_from_activity(activity)
1232 assert length(recipients) == 3
1233 assert user in recipients
1234 assert addressed in recipients
1235 end
1236
1237 test "has following" do
1238 actor = insert(:user)
1239 user = insert(:user)
1240 user_two = insert(:user)
1241 addressed = insert(:user, local: true)
1242
1243 {:ok, activity} =
1244 CommonAPI.post(actor, %{
1245 status: "hey @#{addressed.nickname}"
1246 })
1247
1248 assert Enum.map([actor, addressed], & &1.ap_id) --
1249 Enum.map(User.get_recipients_from_activity(activity), & &1.ap_id) == []
1250
1251 {:ok, _actor} = User.follow(actor, user)
1252 {:ok, _actor} = User.follow(actor, user_two)
1253 recipients = User.get_recipients_from_activity(activity)
1254 assert length(recipients) == 2
1255 assert addressed in recipients
1256 end
1257 end
1258
1259 describe ".deactivate" do
1260 test "can de-activate then re-activate a user" do
1261 user = insert(:user)
1262 assert false == user.deactivated
1263 {:ok, user} = User.deactivate(user)
1264 assert true == user.deactivated
1265 {:ok, user} = User.deactivate(user, false)
1266 assert false == user.deactivated
1267 end
1268
1269 test "hide a user from followers" do
1270 user = insert(:user)
1271 user2 = insert(:user)
1272
1273 {:ok, user} = User.follow(user, user2)
1274 {:ok, _user} = User.deactivate(user)
1275
1276 user2 = User.get_cached_by_id(user2.id)
1277
1278 assert user2.follower_count == 0
1279 assert [] = User.get_followers(user2)
1280 end
1281
1282 test "hide a user from friends" do
1283 user = insert(:user)
1284 user2 = insert(:user)
1285
1286 {:ok, user2} = User.follow(user2, user)
1287 assert user2.following_count == 1
1288 assert User.following_count(user2) == 1
1289
1290 {:ok, _user} = User.deactivate(user)
1291
1292 user2 = User.get_cached_by_id(user2.id)
1293
1294 assert refresh_record(user2).following_count == 0
1295 assert user2.following_count == 0
1296 assert User.following_count(user2) == 0
1297 assert [] = User.get_friends(user2)
1298 end
1299
1300 test "hide a user's statuses from timelines and notifications" do
1301 user = insert(:user)
1302 user2 = insert(:user)
1303
1304 {:ok, user2} = User.follow(user2, user)
1305
1306 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{user2.nickname}"})
1307
1308 activity = Repo.preload(activity, :bookmark)
1309
1310 [notification] = Pleroma.Notification.for_user(user2)
1311 assert notification.activity.id == activity.id
1312
1313 assert [activity] == ActivityPub.fetch_public_activities(%{}) |> Repo.preload(:bookmark)
1314
1315 assert [%{activity | thread_muted?: CommonAPI.thread_muted?(user2, activity)}] ==
1316 ActivityPub.fetch_activities([user2.ap_id | User.following(user2)], %{
1317 user: user2
1318 })
1319
1320 {:ok, _user} = User.deactivate(user)
1321
1322 assert [] == ActivityPub.fetch_public_activities(%{})
1323 assert [] == Pleroma.Notification.for_user(user2)
1324
1325 assert [] ==
1326 ActivityPub.fetch_activities([user2.ap_id | User.following(user2)], %{
1327 user: user2
1328 })
1329 end
1330 end
1331
1332 describe "approve" do
1333 test "approves a user" do
1334 user = insert(:user, approval_pending: true)
1335 assert true == user.approval_pending
1336 {:ok, user} = User.approve(user)
1337 assert false == user.approval_pending
1338 end
1339
1340 test "approves a list of users" do
1341 unapproved_users = [
1342 insert(:user, approval_pending: true),
1343 insert(:user, approval_pending: true),
1344 insert(:user, approval_pending: true)
1345 ]
1346
1347 {:ok, users} = User.approve(unapproved_users)
1348
1349 assert Enum.count(users) == 3
1350
1351 Enum.each(users, fn user ->
1352 assert false == user.approval_pending
1353 end)
1354 end
1355
1356 test "it sends welcome email if it is set" do
1357 clear_config([:welcome, :email, :enabled], true)
1358 clear_config([:welcome, :email, :sender], "tester@test.me")
1359
1360 user = insert(:user, approval_pending: true)
1361 welcome_user = insert(:user, email: "tester@test.me")
1362 instance_name = Pleroma.Config.get([:instance, :name])
1363
1364 User.approve(user)
1365
1366 ObanHelpers.perform_all()
1367
1368 assert_email_sent(
1369 from: {instance_name, welcome_user.email},
1370 to: {user.name, user.email},
1371 html_body: "Welcome to #{instance_name}"
1372 )
1373 end
1374
1375 test "approving an approved user does not trigger post-register actions" do
1376 clear_config([:welcome, :email, :enabled], true)
1377
1378 user = insert(:user, approval_pending: false)
1379 User.approve(user)
1380
1381 ObanHelpers.perform_all()
1382
1383 assert_no_email_sent()
1384 end
1385 end
1386
1387 describe "confirm" do
1388 test "confirms a user" do
1389 user = insert(:user, confirmation_pending: true)
1390 assert true == user.confirmation_pending
1391 {:ok, user} = User.confirm(user)
1392 assert false == user.confirmation_pending
1393 end
1394
1395 test "confirms a list of users" do
1396 unconfirmed_users = [
1397 insert(:user, confirmation_pending: true),
1398 insert(:user, confirmation_pending: true),
1399 insert(:user, confirmation_pending: true)
1400 ]
1401
1402 {:ok, users} = User.confirm(unconfirmed_users)
1403
1404 assert Enum.count(users) == 3
1405
1406 Enum.each(users, fn user ->
1407 assert false == user.confirmation_pending
1408 end)
1409 end
1410
1411 test "sends approval emails when `approval_pending: true`" do
1412 admin = insert(:user, is_admin: true)
1413 user = insert(:user, confirmation_pending: true, approval_pending: true)
1414 User.confirm(user)
1415
1416 ObanHelpers.perform_all()
1417
1418 user_email = Pleroma.Emails.UserEmail.approval_pending_email(user)
1419 admin_email = Pleroma.Emails.AdminEmail.new_unapproved_registration(admin, user)
1420
1421 notify_email = Pleroma.Config.get([:instance, :notify_email])
1422 instance_name = Pleroma.Config.get([:instance, :name])
1423
1424 # User approval email
1425 assert_email_sent(
1426 from: {instance_name, notify_email},
1427 to: {user.name, user.email},
1428 html_body: user_email.html_body
1429 )
1430
1431 # Admin email
1432 assert_email_sent(
1433 from: {instance_name, notify_email},
1434 to: {admin.name, admin.email},
1435 html_body: admin_email.html_body
1436 )
1437 end
1438
1439 test "confirming a confirmed user does not trigger post-register actions" do
1440 user = insert(:user, confirmation_pending: false, approval_pending: true)
1441 User.confirm(user)
1442
1443 ObanHelpers.perform_all()
1444
1445 assert_no_email_sent()
1446 end
1447 end
1448
1449 describe "delete" do
1450 setup do
1451 {:ok, user} = insert(:user) |> User.set_cache()
1452
1453 [user: user]
1454 end
1455
1456 setup do: clear_config([:instance, :federating])
1457
1458 test ".delete_user_activities deletes all create activities", %{user: user} do
1459 {:ok, activity} = CommonAPI.post(user, %{status: "2hu"})
1460
1461 User.delete_user_activities(user)
1462
1463 # TODO: Test removal favorites, repeats, delete activities.
1464 refute Activity.get_by_id(activity.id)
1465 end
1466
1467 test "it deactivates a user, all follow relationships and all activities", %{user: user} do
1468 follower = insert(:user)
1469 {:ok, follower} = User.follow(follower, user)
1470
1471 locked_user = insert(:user, name: "locked", locked: true)
1472 {:ok, _} = User.follow(user, locked_user, :follow_pending)
1473
1474 object = insert(:note, user: user)
1475 activity = insert(:note_activity, user: user, note: object)
1476
1477 object_two = insert(:note, user: follower)
1478 activity_two = insert(:note_activity, user: follower, note: object_two)
1479
1480 {:ok, like} = CommonAPI.favorite(user, activity_two.id)
1481 {:ok, like_two} = CommonAPI.favorite(follower, activity.id)
1482 {:ok, repeat} = CommonAPI.repeat(activity_two.id, user)
1483
1484 {:ok, job} = User.delete(user)
1485 {:ok, _user} = ObanHelpers.perform(job)
1486
1487 follower = User.get_cached_by_id(follower.id)
1488
1489 refute User.following?(follower, user)
1490 assert %{deactivated: true} = User.get_by_id(user.id)
1491
1492 assert [] == User.get_follow_requests(locked_user)
1493
1494 user_activities =
1495 user.ap_id
1496 |> Activity.Queries.by_actor()
1497 |> Repo.all()
1498 |> Enum.map(fn act -> act.data["type"] end)
1499
1500 assert Enum.all?(user_activities, fn act -> act in ~w(Delete Undo) end)
1501
1502 refute Activity.get_by_id(activity.id)
1503 refute Activity.get_by_id(like.id)
1504 refute Activity.get_by_id(like_two.id)
1505 refute Activity.get_by_id(repeat.id)
1506 end
1507 end
1508
1509 describe "delete/1 when confirmation is pending" do
1510 setup do
1511 user = insert(:user, confirmation_pending: true)
1512 {:ok, user: user}
1513 end
1514
1515 test "deletes user from database when activation required", %{user: user} do
1516 clear_config([:instance, :account_activation_required], true)
1517
1518 {:ok, job} = User.delete(user)
1519 {:ok, _} = ObanHelpers.perform(job)
1520
1521 refute User.get_cached_by_id(user.id)
1522 refute User.get_by_id(user.id)
1523 end
1524
1525 test "deactivates user when activation is not required", %{user: user} do
1526 clear_config([:instance, :account_activation_required], false)
1527
1528 {:ok, job} = User.delete(user)
1529 {:ok, _} = ObanHelpers.perform(job)
1530
1531 assert %{deactivated: true} = User.get_cached_by_id(user.id)
1532 assert %{deactivated: true} = User.get_by_id(user.id)
1533 end
1534 end
1535
1536 test "delete/1 when approval is pending deletes the user" do
1537 user = insert(:user, approval_pending: true)
1538
1539 {:ok, job} = User.delete(user)
1540 {:ok, _} = ObanHelpers.perform(job)
1541
1542 refute User.get_cached_by_id(user.id)
1543 refute User.get_by_id(user.id)
1544 end
1545
1546 test "delete/1 purges a user when they wouldn't be fully deleted" do
1547 user =
1548 insert(:user, %{
1549 bio: "eyy lmao",
1550 name: "qqqqqqq",
1551 password_hash: "pdfk2$1b3n159001",
1552 keys: "RSA begin buplic key",
1553 public_key: "--PRIVATE KEYE--",
1554 avatar: %{"a" => "b"},
1555 tags: ["qqqqq"],
1556 banner: %{"a" => "b"},
1557 background: %{"a" => "b"},
1558 note_count: 9,
1559 follower_count: 9,
1560 following_count: 9001,
1561 locked: true,
1562 confirmation_pending: true,
1563 password_reset_pending: true,
1564 approval_pending: true,
1565 registration_reason: "ahhhhh",
1566 confirmation_token: "qqqq",
1567 domain_blocks: ["lain.com"],
1568 deactivated: true,
1569 ap_enabled: true,
1570 is_moderator: true,
1571 is_admin: true,
1572 mastofe_settings: %{"a" => "b"},
1573 mascot: %{"a" => "b"},
1574 emoji: %{"a" => "b"},
1575 pleroma_settings_store: %{"q" => "x"},
1576 fields: [%{"gg" => "qq"}],
1577 raw_fields: [%{"gg" => "qq"}],
1578 discoverable: true,
1579 also_known_as: ["https://lol.olo/users/loll"]
1580 })
1581
1582 {:ok, job} = User.delete(user)
1583 {:ok, _} = ObanHelpers.perform(job)
1584 user = User.get_by_id(user.id)
1585
1586 assert %User{
1587 bio: "",
1588 raw_bio: nil,
1589 email: nil,
1590 name: nil,
1591 password_hash: nil,
1592 keys: nil,
1593 public_key: nil,
1594 avatar: %{},
1595 tags: [],
1596 last_refreshed_at: nil,
1597 last_digest_emailed_at: nil,
1598 banner: %{},
1599 background: %{},
1600 note_count: 0,
1601 follower_count: 0,
1602 following_count: 0,
1603 locked: false,
1604 confirmation_pending: false,
1605 password_reset_pending: false,
1606 approval_pending: false,
1607 registration_reason: nil,
1608 confirmation_token: nil,
1609 domain_blocks: [],
1610 deactivated: true,
1611 ap_enabled: false,
1612 is_moderator: false,
1613 is_admin: false,
1614 mastofe_settings: nil,
1615 mascot: nil,
1616 emoji: %{},
1617 pleroma_settings_store: %{},
1618 fields: [],
1619 raw_fields: [],
1620 discoverable: false,
1621 also_known_as: []
1622 } = user
1623 end
1624
1625 test "get_public_key_for_ap_id fetches a user that's not in the db" do
1626 assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
1627 end
1628
1629 describe "per-user rich-text filtering" do
1630 test "html_filter_policy returns default policies, when rich-text is enabled" do
1631 user = insert(:user)
1632
1633 assert Pleroma.Config.get([:markup, :scrub_policy]) == User.html_filter_policy(user)
1634 end
1635
1636 test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do
1637 user = insert(:user, no_rich_text: true)
1638
1639 assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)
1640 end
1641 end
1642
1643 describe "caching" do
1644 test "invalidate_cache works" do
1645 user = insert(:user)
1646
1647 User.set_cache(user)
1648 User.invalidate_cache(user)
1649
1650 {:ok, nil} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
1651 {:ok, nil} = Cachex.get(:user_cache, "nickname:#{user.nickname}")
1652 end
1653
1654 test "User.delete() plugs any possible zombie objects" do
1655 user = insert(:user)
1656
1657 {:ok, job} = User.delete(user)
1658 {:ok, _} = ObanHelpers.perform(job)
1659
1660 {:ok, cached_user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
1661
1662 assert cached_user != user
1663
1664 {:ok, cached_user} = Cachex.get(:user_cache, "nickname:#{user.ap_id}")
1665
1666 assert cached_user != user
1667 end
1668 end
1669
1670 describe "account_status/1" do
1671 setup do: clear_config([:instance, :account_activation_required])
1672
1673 test "return confirmation_pending for unconfirm user" do
1674 Pleroma.Config.put([:instance, :account_activation_required], true)
1675 user = insert(:user, confirmation_pending: true)
1676 assert User.account_status(user) == :confirmation_pending
1677 end
1678
1679 test "return active for confirmed user" do
1680 Pleroma.Config.put([:instance, :account_activation_required], true)
1681 user = insert(:user, confirmation_pending: false)
1682 assert User.account_status(user) == :active
1683 end
1684
1685 test "return active for remote user" do
1686 user = insert(:user, local: false)
1687 assert User.account_status(user) == :active
1688 end
1689
1690 test "returns :password_reset_pending for user with reset password" do
1691 user = insert(:user, password_reset_pending: true)
1692 assert User.account_status(user) == :password_reset_pending
1693 end
1694
1695 test "returns :deactivated for deactivated user" do
1696 user = insert(:user, local: true, confirmation_pending: false, deactivated: true)
1697 assert User.account_status(user) == :deactivated
1698 end
1699
1700 test "returns :approval_pending for unapproved user" do
1701 user = insert(:user, local: true, approval_pending: true)
1702 assert User.account_status(user) == :approval_pending
1703
1704 user = insert(:user, local: true, confirmation_pending: true, approval_pending: true)
1705 assert User.account_status(user) == :approval_pending
1706 end
1707 end
1708
1709 describe "superuser?/1" do
1710 test "returns false for unprivileged users" do
1711 user = insert(:user, local: true)
1712
1713 refute User.superuser?(user)
1714 end
1715
1716 test "returns false for remote users" do
1717 user = insert(:user, local: false)
1718 remote_admin_user = insert(:user, local: false, is_admin: true)
1719
1720 refute User.superuser?(user)
1721 refute User.superuser?(remote_admin_user)
1722 end
1723
1724 test "returns true for local moderators" do
1725 user = insert(:user, local: true, is_moderator: true)
1726
1727 assert User.superuser?(user)
1728 end
1729
1730 test "returns true for local admins" do
1731 user = insert(:user, local: true, is_admin: true)
1732
1733 assert User.superuser?(user)
1734 end
1735 end
1736
1737 describe "invisible?/1" do
1738 test "returns true for an invisible user" do
1739 user = insert(:user, local: true, invisible: true)
1740
1741 assert User.invisible?(user)
1742 end
1743
1744 test "returns false for a non-invisible user" do
1745 user = insert(:user, local: true)
1746
1747 refute User.invisible?(user)
1748 end
1749 end
1750
1751 describe "visible_for/2" do
1752 test "returns true when the account is itself" do
1753 user = insert(:user, local: true)
1754
1755 assert User.visible_for(user, user) == :visible
1756 end
1757
1758 test "returns false when the account is unconfirmed and confirmation is required" do
1759 Pleroma.Config.put([:instance, :account_activation_required], true)
1760
1761 user = insert(:user, local: true, confirmation_pending: true)
1762 other_user = insert(:user, local: true)
1763
1764 refute User.visible_for(user, other_user) == :visible
1765 end
1766
1767 test "returns true when the account is unconfirmed and confirmation is required but the account is remote" do
1768 Pleroma.Config.put([:instance, :account_activation_required], true)
1769
1770 user = insert(:user, local: false, confirmation_pending: true)
1771 other_user = insert(:user, local: true)
1772
1773 assert User.visible_for(user, other_user) == :visible
1774 end
1775
1776 test "returns true when the account is unconfirmed and confirmation is not required" do
1777 user = insert(:user, local: true, confirmation_pending: true)
1778 other_user = insert(:user, local: true)
1779
1780 assert User.visible_for(user, other_user) == :visible
1781 end
1782
1783 test "returns true when the account is unconfirmed and being viewed by a privileged account (confirmation required)" do
1784 Pleroma.Config.put([:instance, :account_activation_required], true)
1785
1786 user = insert(:user, local: true, confirmation_pending: true)
1787 other_user = insert(:user, local: true, is_admin: true)
1788
1789 assert User.visible_for(user, other_user) == :visible
1790 end
1791 end
1792
1793 describe "parse_bio/2" do
1794 test "preserves hosts in user links text" do
1795 remote_user = insert(:user, local: false, nickname: "nick@domain.com")
1796 user = insert(:user)
1797 bio = "A.k.a. @nick@domain.com"
1798
1799 expected_text =
1800 ~s(A.k.a. <span class="h-card"><a class="u-url mention" data-user="#{remote_user.id}" href="#{
1801 remote_user.ap_id
1802 }" rel="ugc">@<span>nick@domain.com</span></a></span>)
1803
1804 assert expected_text == User.parse_bio(bio, user)
1805 end
1806
1807 test "Adds rel=me on linkbacked urls" do
1808 user = insert(:user, ap_id: "https://social.example.org/users/lain")
1809
1810 bio = "http://example.com/rel_me/null"
1811 expected_text = "<a href=\"#{bio}\">#{bio}</a>"
1812 assert expected_text == User.parse_bio(bio, user)
1813
1814 bio = "http://example.com/rel_me/link"
1815 expected_text = "<a href=\"#{bio}\" rel=\"me\">#{bio}</a>"
1816 assert expected_text == User.parse_bio(bio, user)
1817
1818 bio = "http://example.com/rel_me/anchor"
1819 expected_text = "<a href=\"#{bio}\" rel=\"me\">#{bio}</a>"
1820 assert expected_text == User.parse_bio(bio, user)
1821 end
1822 end
1823
1824 test "follower count is updated when a follower is blocked" do
1825 user = insert(:user)
1826 follower = insert(:user)
1827 follower2 = insert(:user)
1828 follower3 = insert(:user)
1829
1830 {:ok, follower} = User.follow(follower, user)
1831 {:ok, _follower2} = User.follow(follower2, user)
1832 {:ok, _follower3} = User.follow(follower3, user)
1833
1834 {:ok, _user_relationship} = User.block(user, follower)
1835 user = refresh_record(user)
1836
1837 assert user.follower_count == 2
1838 end
1839
1840 describe "list_inactive_users_query/1" do
1841 defp days_ago(days) do
1842 NaiveDateTime.add(
1843 NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second),
1844 -days * 60 * 60 * 24,
1845 :second
1846 )
1847 end
1848
1849 test "Users are inactive by default" do
1850 total = 10
1851
1852 users =
1853 Enum.map(1..total, fn _ ->
1854 insert(:user, last_digest_emailed_at: days_ago(20), deactivated: false)
1855 end)
1856
1857 inactive_users_ids =
1858 Pleroma.User.list_inactive_users_query()
1859 |> Pleroma.Repo.all()
1860 |> Enum.map(& &1.id)
1861
1862 Enum.each(users, fn user ->
1863 assert user.id in inactive_users_ids
1864 end)
1865 end
1866
1867 test "Only includes users who has no recent activity" do
1868 total = 10
1869
1870 users =
1871 Enum.map(1..total, fn _ ->
1872 insert(:user, last_digest_emailed_at: days_ago(20), deactivated: false)
1873 end)
1874
1875 {inactive, active} = Enum.split(users, trunc(total / 2))
1876
1877 Enum.map(active, fn user ->
1878 to = Enum.random(users -- [user])
1879
1880 {:ok, _} =
1881 CommonAPI.post(user, %{
1882 status: "hey @#{to.nickname}"
1883 })
1884 end)
1885
1886 inactive_users_ids =
1887 Pleroma.User.list_inactive_users_query()
1888 |> Pleroma.Repo.all()
1889 |> Enum.map(& &1.id)
1890
1891 Enum.each(active, fn user ->
1892 refute user.id in inactive_users_ids
1893 end)
1894
1895 Enum.each(inactive, fn user ->
1896 assert user.id in inactive_users_ids
1897 end)
1898 end
1899
1900 test "Only includes users with no read notifications" do
1901 total = 10
1902
1903 users =
1904 Enum.map(1..total, fn _ ->
1905 insert(:user, last_digest_emailed_at: days_ago(20), deactivated: false)
1906 end)
1907
1908 [sender | recipients] = users
1909 {inactive, active} = Enum.split(recipients, trunc(total / 2))
1910
1911 Enum.each(recipients, fn to ->
1912 {:ok, _} =
1913 CommonAPI.post(sender, %{
1914 status: "hey @#{to.nickname}"
1915 })
1916
1917 {:ok, _} =
1918 CommonAPI.post(sender, %{
1919 status: "hey again @#{to.nickname}"
1920 })
1921 end)
1922
1923 Enum.each(active, fn user ->
1924 [n1, _n2] = Pleroma.Notification.for_user(user)
1925 {:ok, _} = Pleroma.Notification.read_one(user, n1.id)
1926 end)
1927
1928 inactive_users_ids =
1929 Pleroma.User.list_inactive_users_query()
1930 |> Pleroma.Repo.all()
1931 |> Enum.map(& &1.id)
1932
1933 Enum.each(active, fn user ->
1934 refute user.id in inactive_users_ids
1935 end)
1936
1937 Enum.each(inactive, fn user ->
1938 assert user.id in inactive_users_ids
1939 end)
1940 end
1941 end
1942
1943 describe "toggle_confirmation/1" do
1944 test "if user is confirmed" do
1945 user = insert(:user, confirmation_pending: false)
1946 {:ok, user} = User.toggle_confirmation(user)
1947
1948 assert user.confirmation_pending
1949 assert user.confirmation_token
1950 end
1951
1952 test "if user is unconfirmed" do
1953 user = insert(:user, confirmation_pending: true, confirmation_token: "some token")
1954 {:ok, user} = User.toggle_confirmation(user)
1955
1956 refute user.confirmation_pending
1957 refute user.confirmation_token
1958 end
1959 end
1960
1961 describe "ensure_keys_present" do
1962 test "it creates keys for a user and stores them in info" do
1963 user = insert(:user)
1964 refute is_binary(user.keys)
1965 {:ok, user} = User.ensure_keys_present(user)
1966 assert is_binary(user.keys)
1967 end
1968
1969 test "it doesn't create keys if there already are some" do
1970 user = insert(:user, keys: "xxx")
1971 {:ok, user} = User.ensure_keys_present(user)
1972 assert user.keys == "xxx"
1973 end
1974 end
1975
1976 describe "get_ap_ids_by_nicknames" do
1977 test "it returns a list of AP ids for a given set of nicknames" do
1978 user = insert(:user)
1979 user_two = insert(:user)
1980
1981 ap_ids = User.get_ap_ids_by_nicknames([user.nickname, user_two.nickname, "nonexistent"])
1982 assert length(ap_ids) == 2
1983 assert user.ap_id in ap_ids
1984 assert user_two.ap_id in ap_ids
1985 end
1986 end
1987
1988 describe "sync followers count" do
1989 setup do
1990 user1 = insert(:user, local: false, ap_id: "http://localhost:4001/users/masto_closed")
1991 user2 = insert(:user, local: false, ap_id: "http://localhost:4001/users/fuser2")
1992 insert(:user, local: true)
1993 insert(:user, local: false, deactivated: true)
1994 {:ok, user1: user1, user2: user2}
1995 end
1996
1997 test "external_users/1 external active users with limit", %{user1: user1, user2: user2} do
1998 [fdb_user1] = User.external_users(limit: 1)
1999
2000 assert fdb_user1.ap_id
2001 assert fdb_user1.ap_id == user1.ap_id
2002 assert fdb_user1.id == user1.id
2003
2004 [fdb_user2] = User.external_users(max_id: fdb_user1.id, limit: 1)
2005
2006 assert fdb_user2.ap_id
2007 assert fdb_user2.ap_id == user2.ap_id
2008 assert fdb_user2.id == user2.id
2009
2010 assert User.external_users(max_id: fdb_user2.id, limit: 1) == []
2011 end
2012 end
2013
2014 describe "is_internal_user?/1" do
2015 test "non-internal user returns false" do
2016 user = insert(:user)
2017 refute User.is_internal_user?(user)
2018 end
2019
2020 test "user with no nickname returns true" do
2021 user = insert(:user, %{nickname: nil})
2022 assert User.is_internal_user?(user)
2023 end
2024
2025 test "user with internal-prefixed nickname returns true" do
2026 user = insert(:user, %{nickname: "internal.test"})
2027 assert User.is_internal_user?(user)
2028 end
2029 end
2030
2031 describe "update_and_set_cache/1" do
2032 test "returns error when user is stale instead Ecto.StaleEntryError" do
2033 user = insert(:user)
2034
2035 changeset = Ecto.Changeset.change(user, bio: "test")
2036
2037 Repo.delete(user)
2038
2039 assert {:error, %Ecto.Changeset{errors: [id: {"is stale", [stale: true]}], valid?: false}} =
2040 User.update_and_set_cache(changeset)
2041 end
2042
2043 test "performs update cache if user updated" do
2044 user = insert(:user)
2045 assert {:ok, nil} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
2046
2047 changeset = Ecto.Changeset.change(user, bio: "test-bio")
2048
2049 assert {:ok, %User{bio: "test-bio"} = user} = User.update_and_set_cache(changeset)
2050 assert {:ok, user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
2051 assert %User{bio: "test-bio"} = User.get_cached_by_ap_id(user.ap_id)
2052 end
2053 end
2054
2055 describe "following/followers synchronization" do
2056 setup do: clear_config([:instance, :external_user_synchronization])
2057
2058 test "updates the counters normally on following/getting a follow when disabled" do
2059 Pleroma.Config.put([:instance, :external_user_synchronization], false)
2060 user = insert(:user)
2061
2062 other_user =
2063 insert(:user,
2064 local: false,
2065 follower_address: "http://localhost:4001/users/masto_closed/followers",
2066 following_address: "http://localhost:4001/users/masto_closed/following",
2067 ap_enabled: true
2068 )
2069
2070 assert other_user.following_count == 0
2071 assert other_user.follower_count == 0
2072
2073 {:ok, user} = Pleroma.User.follow(user, other_user)
2074 other_user = Pleroma.User.get_by_id(other_user.id)
2075
2076 assert user.following_count == 1
2077 assert other_user.follower_count == 1
2078 end
2079
2080 test "syncronizes the counters with the remote instance for the followed when enabled" do
2081 Pleroma.Config.put([:instance, :external_user_synchronization], false)
2082
2083 user = insert(:user)
2084
2085 other_user =
2086 insert(:user,
2087 local: false,
2088 follower_address: "http://localhost:4001/users/masto_closed/followers",
2089 following_address: "http://localhost:4001/users/masto_closed/following",
2090 ap_enabled: true
2091 )
2092
2093 assert other_user.following_count == 0
2094 assert other_user.follower_count == 0
2095
2096 Pleroma.Config.put([:instance, :external_user_synchronization], true)
2097 {:ok, _user} = User.follow(user, other_user)
2098 other_user = User.get_by_id(other_user.id)
2099
2100 assert other_user.follower_count == 437
2101 end
2102
2103 test "syncronizes the counters with the remote instance for the follower when enabled" do
2104 Pleroma.Config.put([:instance, :external_user_synchronization], false)
2105
2106 user = insert(:user)
2107
2108 other_user =
2109 insert(:user,
2110 local: false,
2111 follower_address: "http://localhost:4001/users/masto_closed/followers",
2112 following_address: "http://localhost:4001/users/masto_closed/following",
2113 ap_enabled: true
2114 )
2115
2116 assert other_user.following_count == 0
2117 assert other_user.follower_count == 0
2118
2119 Pleroma.Config.put([:instance, :external_user_synchronization], true)
2120 {:ok, other_user} = User.follow(other_user, user)
2121
2122 assert other_user.following_count == 152
2123 end
2124 end
2125
2126 describe "change_email/2" do
2127 setup do
2128 [user: insert(:user)]
2129 end
2130
2131 test "blank email returns error", %{user: user} do
2132 assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, "")
2133 assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, nil)
2134 end
2135
2136 test "non unique email returns error", %{user: user} do
2137 %{email: email} = insert(:user)
2138
2139 assert {:error, %{errors: [email: {"has already been taken", _}]}} =
2140 User.change_email(user, email)
2141 end
2142
2143 test "invalid email returns error", %{user: user} do
2144 assert {:error, %{errors: [email: {"has invalid format", _}]}} =
2145 User.change_email(user, "cofe")
2146 end
2147
2148 test "changes email", %{user: user} do
2149 assert {:ok, %User{email: "cofe@cofe.party"}} = User.change_email(user, "cofe@cofe.party")
2150 end
2151 end
2152
2153 describe "get_cached_by_nickname_or_id" do
2154 setup do
2155 local_user = insert(:user)
2156 remote_user = insert(:user, nickname: "nickname@example.com", local: false)
2157
2158 [local_user: local_user, remote_user: remote_user]
2159 end
2160
2161 setup do: clear_config([:instance, :limit_to_local_content])
2162
2163 test "allows getting remote users by id no matter what :limit_to_local_content is set to", %{
2164 remote_user: remote_user
2165 } do
2166 Pleroma.Config.put([:instance, :limit_to_local_content], false)
2167 assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
2168
2169 Pleroma.Config.put([:instance, :limit_to_local_content], true)
2170 assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
2171
2172 Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
2173 assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
2174 end
2175
2176 test "disallows getting remote users by nickname without authentication when :limit_to_local_content is set to :unauthenticated",
2177 %{remote_user: remote_user} do
2178 Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
2179 assert nil == User.get_cached_by_nickname_or_id(remote_user.nickname)
2180 end
2181
2182 test "allows getting remote users by nickname with authentication when :limit_to_local_content is set to :unauthenticated",
2183 %{remote_user: remote_user, local_user: local_user} do
2184 Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
2185 assert %User{} = User.get_cached_by_nickname_or_id(remote_user.nickname, for: local_user)
2186 end
2187
2188 test "disallows getting remote users by nickname when :limit_to_local_content is set to true",
2189 %{remote_user: remote_user} do
2190 Pleroma.Config.put([:instance, :limit_to_local_content], true)
2191 assert nil == User.get_cached_by_nickname_or_id(remote_user.nickname)
2192 end
2193
2194 test "allows getting local users by nickname no matter what :limit_to_local_content is set to",
2195 %{local_user: local_user} do
2196 Pleroma.Config.put([:instance, :limit_to_local_content], false)
2197 assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
2198
2199 Pleroma.Config.put([:instance, :limit_to_local_content], true)
2200 assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
2201
2202 Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
2203 assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
2204 end
2205 end
2206
2207 describe "update_email_notifications/2" do
2208 setup do
2209 user = insert(:user, email_notifications: %{"digest" => true})
2210
2211 {:ok, user: user}
2212 end
2213
2214 test "Notifications are updated", %{user: user} do
2215 true = user.email_notifications["digest"]
2216 assert {:ok, result} = User.update_email_notifications(user, %{"digest" => false})
2217 assert result.email_notifications["digest"] == false
2218 end
2219 end
2220
2221 test "avatar fallback" do
2222 user = insert(:user)
2223 assert User.avatar_url(user) =~ "/images/avi.png"
2224
2225 clear_config([:assets, :default_user_avatar], "avatar.png")
2226
2227 user = User.get_cached_by_nickname_or_id(user.nickname)
2228 assert User.avatar_url(user) =~ "avatar.png"
2229
2230 assert User.avatar_url(user, no_default: true) == nil
2231 end
2232 end