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