logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

user_test.exs (93793B)


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