Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1750 lines
52KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2019 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
  14. use Oban.Testing, repo: Pleroma.Repo
  15. import Mock
  16. import Pleroma.Factory
  17. setup_all do
  18. Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
  19. :ok
  20. end
  21. clear_config([:instance, :account_activation_required])
  22. describe "when tags are nil" do
  23. test "tagging a user" do
  24. user = insert(:user, %{tags: nil})
  25. user = User.tag(user, ["cool", "dude"])
  26. assert "cool" in user.tags
  27. assert "dude" in user.tags
  28. end
  29. test "untagging a user" do
  30. user = insert(:user, %{tags: nil})
  31. user = User.untag(user, ["cool", "dude"])
  32. assert user.tags == []
  33. end
  34. end
  35. test "ap_id returns the activity pub id for the user" do
  36. user = UserBuilder.build()
  37. expected_ap_id = "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
  38. assert expected_ap_id == User.ap_id(user)
  39. end
  40. test "ap_followers returns the followers collection for the user" do
  41. user = UserBuilder.build()
  42. expected_followers_collection = "#{User.ap_id(user)}/followers"
  43. assert expected_followers_collection == User.ap_followers(user)
  44. end
  45. test "ap_following returns the following collection for the user" do
  46. user = UserBuilder.build()
  47. expected_followers_collection = "#{User.ap_id(user)}/following"
  48. assert expected_followers_collection == User.ap_following(user)
  49. end
  50. test "returns all pending follow requests" do
  51. unlocked = insert(:user)
  52. locked = insert(:user, locked: true)
  53. follower = insert(:user)
  54. CommonAPI.follow(follower, unlocked)
  55. CommonAPI.follow(follower, locked)
  56. assert [] = User.get_follow_requests(unlocked)
  57. assert [activity] = User.get_follow_requests(locked)
  58. assert activity
  59. end
  60. test "doesn't return already accepted or duplicate follow requests" do
  61. locked = insert(:user, locked: true)
  62. pending_follower = insert(:user)
  63. accepted_follower = insert(:user)
  64. CommonAPI.follow(pending_follower, locked)
  65. CommonAPI.follow(pending_follower, locked)
  66. CommonAPI.follow(accepted_follower, locked)
  67. Pleroma.FollowingRelationship.update(accepted_follower, locked, "accept")
  68. assert [^pending_follower] = User.get_follow_requests(locked)
  69. end
  70. test "clears follow requests when requester is blocked" do
  71. followed = insert(:user, locked: true)
  72. follower = insert(:user)
  73. CommonAPI.follow(follower, followed)
  74. assert [_activity] = User.get_follow_requests(followed)
  75. {:ok, _follower} = User.block(followed, follower)
  76. assert [] = User.get_follow_requests(followed)
  77. end
  78. test "follow_all follows mutliple users" do
  79. user = insert(:user)
  80. followed_zero = insert(:user)
  81. followed_one = insert(:user)
  82. followed_two = insert(:user)
  83. blocked = insert(:user)
  84. not_followed = insert(:user)
  85. reverse_blocked = insert(:user)
  86. {:ok, user} = User.block(user, blocked)
  87. {:ok, reverse_blocked} = User.block(reverse_blocked, user)
  88. {:ok, user} = User.follow(user, followed_zero)
  89. {:ok, user} = User.follow_all(user, [followed_one, followed_two, blocked, reverse_blocked])
  90. assert User.following?(user, followed_one)
  91. assert User.following?(user, followed_two)
  92. assert User.following?(user, followed_zero)
  93. refute User.following?(user, not_followed)
  94. refute User.following?(user, blocked)
  95. refute User.following?(user, reverse_blocked)
  96. end
  97. test "follow_all follows mutliple users without duplicating" do
  98. user = insert(:user)
  99. followed_zero = insert(:user)
  100. followed_one = insert(:user)
  101. followed_two = insert(:user)
  102. {:ok, user} = User.follow_all(user, [followed_zero, followed_one])
  103. assert length(User.following(user)) == 3
  104. {:ok, user} = User.follow_all(user, [followed_one, followed_two])
  105. assert length(User.following(user)) == 4
  106. end
  107. test "follow takes a user and another user" do
  108. user = insert(:user)
  109. followed = insert(:user)
  110. {:ok, user} = User.follow(user, followed)
  111. user = User.get_cached_by_id(user.id)
  112. followed = User.get_cached_by_ap_id(followed.ap_id)
  113. assert followed.follower_count == 1
  114. assert User.ap_followers(followed) in User.following(user)
  115. end
  116. test "can't follow a deactivated users" do
  117. user = insert(:user)
  118. followed = insert(:user, %{deactivated: true})
  119. {:error, _} = User.follow(user, followed)
  120. end
  121. test "can't follow a user who blocked us" do
  122. blocker = insert(:user)
  123. blockee = insert(:user)
  124. {:ok, blocker} = User.block(blocker, blockee)
  125. {:error, _} = User.follow(blockee, blocker)
  126. end
  127. test "can't subscribe to a user who blocked us" do
  128. blocker = insert(:user)
  129. blocked = insert(:user)
  130. {:ok, blocker} = User.block(blocker, blocked)
  131. {:error, _} = User.subscribe(blocked, blocker)
  132. end
  133. test "local users do not automatically follow local locked accounts" do
  134. follower = insert(:user, locked: true)
  135. followed = insert(:user, locked: true)
  136. {:ok, follower} = User.maybe_direct_follow(follower, followed)
  137. refute User.following?(follower, followed)
  138. end
  139. describe "unfollow/2" do
  140. setup do
  141. setting = Pleroma.Config.get([:instance, :external_user_synchronization])
  142. on_exit(fn ->
  143. Pleroma.Config.put([:instance, :external_user_synchronization], setting)
  144. end)
  145. :ok
  146. end
  147. test "unfollow with syncronizes external user" do
  148. Pleroma.Config.put([:instance, :external_user_synchronization], true)
  149. followed =
  150. insert(:user,
  151. nickname: "fuser1",
  152. follower_address: "http://localhost:4001/users/fuser1/followers",
  153. following_address: "http://localhost:4001/users/fuser1/following",
  154. ap_id: "http://localhost:4001/users/fuser1"
  155. )
  156. user =
  157. insert(:user, %{
  158. local: false,
  159. nickname: "fuser2",
  160. ap_id: "http://localhost:4001/users/fuser2",
  161. follower_address: "http://localhost:4001/users/fuser2/followers",
  162. following_address: "http://localhost:4001/users/fuser2/following"
  163. })
  164. {:ok, user} = User.follow(user, followed, "accept")
  165. {:ok, user, _activity} = User.unfollow(user, followed)
  166. user = User.get_cached_by_id(user.id)
  167. assert User.following(user) == []
  168. end
  169. test "unfollow takes a user and another user" do
  170. followed = insert(:user)
  171. user = insert(:user)
  172. {:ok, user} = User.follow(user, followed, "accept")
  173. assert User.following(user) == [user.follower_address, followed.follower_address]
  174. {:ok, user, _activity} = User.unfollow(user, followed)
  175. assert User.following(user) == [user.follower_address]
  176. end
  177. test "unfollow doesn't unfollow yourself" do
  178. user = insert(:user)
  179. {:error, _} = User.unfollow(user, user)
  180. assert User.following(user) == [user.follower_address]
  181. end
  182. end
  183. test "test if a user is following another user" do
  184. followed = insert(:user)
  185. user = insert(:user)
  186. User.follow(user, followed, "accept")
  187. assert User.following?(user, followed)
  188. refute User.following?(followed, user)
  189. end
  190. test "fetches correct profile for nickname beginning with number" do
  191. # Use old-style integer ID to try to reproduce the problem
  192. user = insert(:user, %{id: 1080})
  193. user_with_numbers = insert(:user, %{nickname: "#{user.id}garbage"})
  194. assert user_with_numbers == User.get_cached_by_nickname_or_id(user_with_numbers.nickname)
  195. end
  196. describe "user registration" do
  197. @full_user_data %{
  198. bio: "A guy",
  199. name: "my name",
  200. nickname: "nick",
  201. password: "test",
  202. password_confirmation: "test",
  203. email: "email@example.com"
  204. }
  205. clear_config([:instance, :autofollowed_nicknames])
  206. clear_config([:instance, :welcome_message])
  207. clear_config([:instance, :welcome_user_nickname])
  208. test "it autofollows accounts that are set for it" do
  209. user = insert(:user)
  210. remote_user = insert(:user, %{local: false})
  211. Pleroma.Config.put([:instance, :autofollowed_nicknames], [
  212. user.nickname,
  213. remote_user.nickname
  214. ])
  215. cng = User.register_changeset(%User{}, @full_user_data)
  216. {:ok, registered_user} = User.register(cng)
  217. assert User.following?(registered_user, user)
  218. refute User.following?(registered_user, remote_user)
  219. end
  220. test "it sends a welcome message if it is set" do
  221. welcome_user = insert(:user)
  222. Pleroma.Config.put([:instance, :welcome_user_nickname], welcome_user.nickname)
  223. Pleroma.Config.put([:instance, :welcome_message], "Hello, this is a cool site")
  224. cng = User.register_changeset(%User{}, @full_user_data)
  225. {:ok, registered_user} = User.register(cng)
  226. activity = Repo.one(Pleroma.Activity)
  227. assert registered_user.ap_id in activity.recipients
  228. assert Object.normalize(activity).data["content"] =~ "cool site"
  229. assert activity.actor == welcome_user.ap_id
  230. end
  231. test "it requires an email, name, nickname and password, bio is optional" do
  232. @full_user_data
  233. |> Map.keys()
  234. |> Enum.each(fn key ->
  235. params = Map.delete(@full_user_data, key)
  236. changeset = User.register_changeset(%User{}, params)
  237. assert if key == :bio, do: changeset.valid?, else: not changeset.valid?
  238. end)
  239. end
  240. test "it restricts certain nicknames" do
  241. [restricted_name | _] = Pleroma.Config.get([User, :restricted_nicknames])
  242. assert is_bitstring(restricted_name)
  243. params =
  244. @full_user_data
  245. |> Map.put(:nickname, restricted_name)
  246. changeset = User.register_changeset(%User{}, params)
  247. refute changeset.valid?
  248. end
  249. test "it sets the password_hash and ap_id" do
  250. changeset = User.register_changeset(%User{}, @full_user_data)
  251. assert changeset.valid?
  252. assert is_binary(changeset.changes[:password_hash])
  253. assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname})
  254. assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
  255. end
  256. test "it ensures info is not nil" do
  257. changeset = User.register_changeset(%User{}, @full_user_data)
  258. assert changeset.valid?
  259. {:ok, user} =
  260. changeset
  261. |> Repo.insert()
  262. refute is_nil(user.info)
  263. end
  264. end
  265. describe "user registration, with :account_activation_required" do
  266. @full_user_data %{
  267. bio: "A guy",
  268. name: "my name",
  269. nickname: "nick",
  270. password: "test",
  271. password_confirmation: "test",
  272. email: "email@example.com"
  273. }
  274. clear_config([:instance, :account_activation_required]) do
  275. Pleroma.Config.put([:instance, :account_activation_required], true)
  276. end
  277. test "it creates unconfirmed user" do
  278. changeset = User.register_changeset(%User{}, @full_user_data)
  279. assert changeset.valid?
  280. {:ok, user} = Repo.insert(changeset)
  281. assert user.confirmation_pending
  282. assert user.confirmation_token
  283. end
  284. test "it creates confirmed user if :confirmed option is given" do
  285. changeset = User.register_changeset(%User{}, @full_user_data, need_confirmation: false)
  286. assert changeset.valid?
  287. {:ok, user} = Repo.insert(changeset)
  288. refute user.confirmation_pending
  289. refute user.confirmation_token
  290. end
  291. end
  292. describe "get_or_fetch/1" do
  293. test "gets an existing user by nickname" do
  294. user = insert(:user)
  295. {:ok, fetched_user} = User.get_or_fetch(user.nickname)
  296. assert user == fetched_user
  297. end
  298. test "gets an existing user by ap_id" do
  299. ap_id = "http://mastodon.example.org/users/admin"
  300. user =
  301. insert(
  302. :user,
  303. local: false,
  304. nickname: "admin@mastodon.example.org",
  305. ap_id: ap_id,
  306. info: %{}
  307. )
  308. {:ok, fetched_user} = User.get_or_fetch(ap_id)
  309. freshed_user = refresh_record(user)
  310. assert freshed_user == fetched_user
  311. end
  312. end
  313. describe "fetching a user from nickname or trying to build one" do
  314. test "gets an existing user" do
  315. user = insert(:user)
  316. {:ok, fetched_user} = User.get_or_fetch_by_nickname(user.nickname)
  317. assert user == fetched_user
  318. end
  319. test "gets an existing user, case insensitive" do
  320. user = insert(:user, nickname: "nick")
  321. {:ok, fetched_user} = User.get_or_fetch_by_nickname("NICK")
  322. assert user == fetched_user
  323. end
  324. test "gets an existing user by fully qualified nickname" do
  325. user = insert(:user)
  326. {:ok, fetched_user} =
  327. User.get_or_fetch_by_nickname(user.nickname <> "@" <> Pleroma.Web.Endpoint.host())
  328. assert user == fetched_user
  329. end
  330. test "gets an existing user by fully qualified nickname, case insensitive" do
  331. user = insert(:user, nickname: "nick")
  332. casing_altered_fqn = String.upcase(user.nickname <> "@" <> Pleroma.Web.Endpoint.host())
  333. {:ok, fetched_user} = User.get_or_fetch_by_nickname(casing_altered_fqn)
  334. assert user == fetched_user
  335. end
  336. test "returns nil if no user could be fetched" do
  337. {:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistant@social.heldscal.la")
  338. assert fetched_user == "not found nonexistant@social.heldscal.la"
  339. end
  340. test "returns nil for nonexistant local user" do
  341. {:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistant")
  342. assert fetched_user == "not found nonexistant"
  343. end
  344. test "updates an existing user, if stale" do
  345. a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)
  346. orig_user =
  347. insert(
  348. :user,
  349. local: false,
  350. nickname: "admin@mastodon.example.org",
  351. ap_id: "http://mastodon.example.org/users/admin",
  352. last_refreshed_at: a_week_ago,
  353. info: %{}
  354. )
  355. assert orig_user.last_refreshed_at == a_week_ago
  356. {:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
  357. assert user.source_data["endpoints"]
  358. refute user.last_refreshed_at == orig_user.last_refreshed_at
  359. end
  360. end
  361. test "returns an ap_id for a user" do
  362. user = insert(:user)
  363. assert User.ap_id(user) ==
  364. Pleroma.Web.Router.Helpers.feed_url(
  365. Pleroma.Web.Endpoint,
  366. :feed_redirect,
  367. user.nickname
  368. )
  369. end
  370. test "returns an ap_followers link for a user" do
  371. user = insert(:user)
  372. assert User.ap_followers(user) ==
  373. Pleroma.Web.Router.Helpers.feed_url(
  374. Pleroma.Web.Endpoint,
  375. :feed_redirect,
  376. user.nickname
  377. ) <> "/followers"
  378. end
  379. describe "remote user creation changeset" do
  380. @valid_remote %{
  381. bio: "hello",
  382. name: "Someone",
  383. nickname: "a@b.de",
  384. ap_id: "http...",
  385. info: %{some: "info"},
  386. avatar: %{some: "avatar"}
  387. }
  388. clear_config([:instance, :user_bio_length])
  389. clear_config([:instance, :user_name_length])
  390. test "it confirms validity" do
  391. cs = User.remote_user_creation(@valid_remote)
  392. assert cs.valid?
  393. end
  394. test "it sets the follower_adress" do
  395. cs = User.remote_user_creation(@valid_remote)
  396. # remote users get a fake local follower address
  397. assert cs.changes.follower_address ==
  398. User.ap_followers(%User{nickname: @valid_remote[:nickname]})
  399. end
  400. test "it enforces the fqn format for nicknames" do
  401. cs = User.remote_user_creation(%{@valid_remote | nickname: "bla"})
  402. assert Ecto.Changeset.get_field(cs, :local) == false
  403. assert cs.changes.avatar
  404. refute cs.valid?
  405. end
  406. test "it has required fields" do
  407. [:name, :ap_id]
  408. |> Enum.each(fn field ->
  409. cs = User.remote_user_creation(Map.delete(@valid_remote, field))
  410. refute cs.valid?
  411. end)
  412. end
  413. end
  414. describe "followers and friends" do
  415. test "gets all followers for a given user" do
  416. user = insert(:user)
  417. follower_one = insert(:user)
  418. follower_two = insert(:user)
  419. not_follower = insert(:user)
  420. {:ok, follower_one} = User.follow(follower_one, user)
  421. {:ok, follower_two} = User.follow(follower_two, user)
  422. res = User.get_followers(user)
  423. assert Enum.member?(res, follower_one)
  424. assert Enum.member?(res, follower_two)
  425. refute Enum.member?(res, not_follower)
  426. end
  427. test "gets all friends (followed users) for a given user" do
  428. user = insert(:user)
  429. followed_one = insert(:user)
  430. followed_two = insert(:user)
  431. not_followed = insert(:user)
  432. {:ok, user} = User.follow(user, followed_one)
  433. {:ok, user} = User.follow(user, followed_two)
  434. res = User.get_friends(user)
  435. followed_one = User.get_cached_by_ap_id(followed_one.ap_id)
  436. followed_two = User.get_cached_by_ap_id(followed_two.ap_id)
  437. assert Enum.member?(res, followed_one)
  438. assert Enum.member?(res, followed_two)
  439. refute Enum.member?(res, not_followed)
  440. end
  441. end
  442. describe "updating note and follower count" do
  443. test "it sets the note_count property" do
  444. note = insert(:note)
  445. user = User.get_cached_by_ap_id(note.data["actor"])
  446. assert user.note_count == 0
  447. {:ok, user} = User.update_note_count(user)
  448. assert user.note_count == 1
  449. end
  450. test "it increases the note_count property" do
  451. note = insert(:note)
  452. user = User.get_cached_by_ap_id(note.data["actor"])
  453. assert user.note_count == 0
  454. {:ok, user} = User.increase_note_count(user)
  455. assert user.note_count == 1
  456. {:ok, user} = User.increase_note_count(user)
  457. assert user.note_count == 2
  458. end
  459. test "it decreases the note_count property" do
  460. note = insert(:note)
  461. user = User.get_cached_by_ap_id(note.data["actor"])
  462. assert user.note_count == 0
  463. {:ok, user} = User.increase_note_count(user)
  464. assert user.note_count == 1
  465. {:ok, user} = User.decrease_note_count(user)
  466. assert user.note_count == 0
  467. {:ok, user} = User.decrease_note_count(user)
  468. assert user.note_count == 0
  469. end
  470. test "it sets the follower_count property" do
  471. user = insert(:user)
  472. follower = insert(:user)
  473. User.follow(follower, user)
  474. assert user.follower_count == 0
  475. {:ok, user} = User.update_follower_count(user)
  476. assert user.follower_count == 1
  477. end
  478. end
  479. describe "follow_import" do
  480. test "it imports user followings from list" do
  481. [user1, user2, user3] = insert_list(3, :user)
  482. identifiers = [
  483. user2.ap_id,
  484. user3.nickname
  485. ]
  486. {:ok, job} = User.follow_import(user1, identifiers)
  487. result = ObanHelpers.perform(job)
  488. assert is_list(result)
  489. assert result == [user2, user3]
  490. end
  491. end
  492. describe "mutes" do
  493. test "it mutes people" do
  494. user = insert(:user)
  495. muted_user = insert(:user)
  496. refute User.mutes?(user, muted_user)
  497. refute User.muted_notifications?(user, muted_user)
  498. {:ok, user} = User.mute(user, muted_user)
  499. assert User.mutes?(user, muted_user)
  500. assert User.muted_notifications?(user, muted_user)
  501. end
  502. test "it unmutes users" do
  503. user = insert(:user)
  504. muted_user = insert(:user)
  505. {:ok, user} = User.mute(user, muted_user)
  506. {:ok, user} = User.unmute(user, muted_user)
  507. refute User.mutes?(user, muted_user)
  508. refute User.muted_notifications?(user, muted_user)
  509. end
  510. test "it mutes user without notifications" do
  511. user = insert(:user)
  512. muted_user = insert(:user)
  513. refute User.mutes?(user, muted_user)
  514. refute User.muted_notifications?(user, muted_user)
  515. {:ok, user} = User.mute(user, muted_user, false)
  516. assert User.mutes?(user, muted_user)
  517. refute User.muted_notifications?(user, muted_user)
  518. end
  519. end
  520. describe "blocks" do
  521. test "it blocks people" do
  522. user = insert(:user)
  523. blocked_user = insert(:user)
  524. refute User.blocks?(user, blocked_user)
  525. {:ok, user} = User.block(user, blocked_user)
  526. assert User.blocks?(user, blocked_user)
  527. end
  528. test "it unblocks users" do
  529. user = insert(:user)
  530. blocked_user = insert(:user)
  531. {:ok, user} = User.block(user, blocked_user)
  532. {:ok, user} = User.unblock(user, blocked_user)
  533. refute User.blocks?(user, blocked_user)
  534. end
  535. test "blocks tear down cyclical follow relationships" do
  536. blocker = insert(:user)
  537. blocked = insert(:user)
  538. {:ok, blocker} = User.follow(blocker, blocked)
  539. {:ok, blocked} = User.follow(blocked, blocker)
  540. assert User.following?(blocker, blocked)
  541. assert User.following?(blocked, blocker)
  542. {:ok, blocker} = User.block(blocker, blocked)
  543. blocked = User.get_cached_by_id(blocked.id)
  544. assert User.blocks?(blocker, blocked)
  545. refute User.following?(blocker, blocked)
  546. refute User.following?(blocked, blocker)
  547. end
  548. test "blocks tear down blocker->blocked follow relationships" do
  549. blocker = insert(:user)
  550. blocked = insert(:user)
  551. {:ok, blocker} = User.follow(blocker, blocked)
  552. assert User.following?(blocker, blocked)
  553. refute User.following?(blocked, blocker)
  554. {:ok, blocker} = User.block(blocker, blocked)
  555. blocked = User.get_cached_by_id(blocked.id)
  556. assert User.blocks?(blocker, blocked)
  557. refute User.following?(blocker, blocked)
  558. refute User.following?(blocked, blocker)
  559. end
  560. test "blocks tear down blocked->blocker follow relationships" do
  561. blocker = insert(:user)
  562. blocked = insert(:user)
  563. {:ok, blocked} = User.follow(blocked, blocker)
  564. refute User.following?(blocker, blocked)
  565. assert User.following?(blocked, blocker)
  566. {:ok, blocker} = User.block(blocker, blocked)
  567. blocked = User.get_cached_by_id(blocked.id)
  568. assert User.blocks?(blocker, blocked)
  569. refute User.following?(blocker, blocked)
  570. refute User.following?(blocked, blocker)
  571. end
  572. test "blocks tear down blocked->blocker subscription relationships" do
  573. blocker = insert(:user)
  574. blocked = insert(:user)
  575. {:ok, blocker} = User.subscribe(blocked, blocker)
  576. assert User.subscribed_to?(blocked, blocker)
  577. refute User.subscribed_to?(blocker, blocked)
  578. {:ok, blocker} = User.block(blocker, blocked)
  579. assert User.blocks?(blocker, blocked)
  580. refute User.subscribed_to?(blocker, blocked)
  581. refute User.subscribed_to?(blocked, blocker)
  582. end
  583. end
  584. describe "domain blocking" do
  585. test "blocks domains" do
  586. user = insert(:user)
  587. collateral_user = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"})
  588. {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com")
  589. assert User.blocks?(user, collateral_user)
  590. end
  591. test "does not block domain with same end" do
  592. user = insert(:user)
  593. collateral_user =
  594. insert(:user, %{ap_id: "https://another-awful-and-rude-instance.com/user/bully"})
  595. {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com")
  596. refute User.blocks?(user, collateral_user)
  597. end
  598. test "does not block domain with same end if wildcard added" do
  599. user = insert(:user)
  600. collateral_user =
  601. insert(:user, %{ap_id: "https://another-awful-and-rude-instance.com/user/bully"})
  602. {:ok, user} = User.block_domain(user, "*.awful-and-rude-instance.com")
  603. refute User.blocks?(user, collateral_user)
  604. end
  605. test "blocks domain with wildcard for subdomain" do
  606. user = insert(:user)
  607. user_from_subdomain =
  608. insert(:user, %{ap_id: "https://subdomain.awful-and-rude-instance.com/user/bully"})
  609. user_with_two_subdomains =
  610. insert(:user, %{
  611. ap_id: "https://subdomain.second_subdomain.awful-and-rude-instance.com/user/bully"
  612. })
  613. user_domain = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"})
  614. {:ok, user} = User.block_domain(user, "*.awful-and-rude-instance.com")
  615. assert User.blocks?(user, user_from_subdomain)
  616. assert User.blocks?(user, user_with_two_subdomains)
  617. assert User.blocks?(user, user_domain)
  618. end
  619. test "unblocks domains" do
  620. user = insert(:user)
  621. collateral_user = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"})
  622. {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com")
  623. {:ok, user} = User.unblock_domain(user, "awful-and-rude-instance.com")
  624. refute User.blocks?(user, collateral_user)
  625. end
  626. end
  627. describe "blocks_import" do
  628. test "it imports user blocks from list" do
  629. [user1, user2, user3] = insert_list(3, :user)
  630. identifiers = [
  631. user2.ap_id,
  632. user3.nickname
  633. ]
  634. {:ok, job} = User.blocks_import(user1, identifiers)
  635. result = ObanHelpers.perform(job)
  636. assert is_list(result)
  637. assert result == [user2, user3]
  638. end
  639. end
  640. describe "get_recipients_from_activity" do
  641. test "get recipients" do
  642. actor = insert(:user)
  643. user = insert(:user, local: true)
  644. user_two = insert(:user, local: false)
  645. addressed = insert(:user, local: true)
  646. addressed_remote = insert(:user, local: false)
  647. {:ok, activity} =
  648. CommonAPI.post(actor, %{
  649. "status" => "hey @#{addressed.nickname} @#{addressed_remote.nickname}"
  650. })
  651. assert Enum.map([actor, addressed], & &1.ap_id) --
  652. Enum.map(User.get_recipients_from_activity(activity), & &1.ap_id) == []
  653. {:ok, user} = User.follow(user, actor)
  654. {:ok, _user_two} = User.follow(user_two, actor)
  655. recipients = User.get_recipients_from_activity(activity)
  656. assert length(recipients) == 3
  657. assert user in recipients
  658. assert addressed in recipients
  659. end
  660. test "has following" do
  661. actor = insert(:user)
  662. user = insert(:user)
  663. user_two = insert(:user)
  664. addressed = insert(:user, local: true)
  665. {:ok, activity} =
  666. CommonAPI.post(actor, %{
  667. "status" => "hey @#{addressed.nickname}"
  668. })
  669. assert Enum.map([actor, addressed], & &1.ap_id) --
  670. Enum.map(User.get_recipients_from_activity(activity), & &1.ap_id) == []
  671. {:ok, _actor} = User.follow(actor, user)
  672. {:ok, _actor} = User.follow(actor, user_two)
  673. recipients = User.get_recipients_from_activity(activity)
  674. assert length(recipients) == 2
  675. assert addressed in recipients
  676. end
  677. end
  678. describe ".deactivate" do
  679. test "can de-activate then re-activate a user" do
  680. user = insert(:user)
  681. assert false == user.deactivated
  682. {:ok, user} = User.deactivate(user)
  683. assert true == user.deactivated
  684. {:ok, user} = User.deactivate(user, false)
  685. assert false == user.deactivated
  686. end
  687. test "hide a user from followers" do
  688. user = insert(:user)
  689. user2 = insert(:user)
  690. {:ok, user} = User.follow(user, user2)
  691. {:ok, _user} = User.deactivate(user)
  692. info = User.get_cached_user_info(user2)
  693. assert info.follower_count == 0
  694. assert [] = User.get_followers(user2)
  695. end
  696. test "hide a user from friends" do
  697. user = insert(:user)
  698. user2 = insert(:user)
  699. {:ok, user2} = User.follow(user2, user)
  700. assert User.following_count(user2) == 1
  701. {:ok, _user} = User.deactivate(user)
  702. info = User.get_cached_user_info(user2)
  703. assert info.following_count == 0
  704. assert User.following_count(user2) == 0
  705. assert [] = User.get_friends(user2)
  706. end
  707. test "hide a user's statuses from timelines and notifications" do
  708. user = insert(:user)
  709. user2 = insert(:user)
  710. {:ok, user2} = User.follow(user2, user)
  711. {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{user2.nickname}"})
  712. activity = Repo.preload(activity, :bookmark)
  713. [notification] = Pleroma.Notification.for_user(user2)
  714. assert notification.activity.id == activity.id
  715. assert [activity] == ActivityPub.fetch_public_activities(%{}) |> Repo.preload(:bookmark)
  716. assert [%{activity | thread_muted?: CommonAPI.thread_muted?(user2, activity)}] ==
  717. ActivityPub.fetch_activities([user2.ap_id | User.following(user2)], %{
  718. "user" => user2
  719. })
  720. {:ok, _user} = User.deactivate(user)
  721. assert [] == ActivityPub.fetch_public_activities(%{})
  722. assert [] == Pleroma.Notification.for_user(user2)
  723. assert [] ==
  724. ActivityPub.fetch_activities([user2.ap_id | User.following(user2)], %{
  725. "user" => user2
  726. })
  727. end
  728. end
  729. describe "delete" do
  730. setup do
  731. {:ok, user} = insert(:user) |> User.set_cache()
  732. [user: user]
  733. end
  734. clear_config([:instance, :federating])
  735. test ".delete_user_activities deletes all create activities", %{user: user} do
  736. {:ok, activity} = CommonAPI.post(user, %{"status" => "2hu"})
  737. User.delete_user_activities(user)
  738. # TODO: Remove favorites, repeats, delete activities.
  739. refute Activity.get_by_id(activity.id)
  740. end
  741. test "it deletes deactivated user" do
  742. {:ok, user} = insert(:user, deactivated: true) |> User.set_cache()
  743. {:ok, job} = User.delete(user)
  744. {:ok, _user} = ObanHelpers.perform(job)
  745. refute User.get_by_id(user.id)
  746. end
  747. test "it deletes a user, all follow relationships and all activities", %{user: user} do
  748. follower = insert(:user)
  749. {:ok, follower} = User.follow(follower, user)
  750. object = insert(:note, user: user)
  751. activity = insert(:note_activity, user: user, note: object)
  752. object_two = insert(:note, user: follower)
  753. activity_two = insert(:note_activity, user: follower, note: object_two)
  754. {:ok, like, _} = CommonAPI.favorite(activity_two.id, user)
  755. {:ok, like_two, _} = CommonAPI.favorite(activity.id, follower)
  756. {:ok, repeat, _} = CommonAPI.repeat(activity_two.id, user)
  757. {:ok, job} = User.delete(user)
  758. {:ok, _user} = ObanHelpers.perform(job)
  759. follower = User.get_cached_by_id(follower.id)
  760. refute User.following?(follower, user)
  761. refute User.get_by_id(user.id)
  762. assert {:ok, nil} == Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
  763. user_activities =
  764. user.ap_id
  765. |> Activity.Queries.by_actor()
  766. |> Repo.all()
  767. |> Enum.map(fn act -> act.data["type"] end)
  768. assert Enum.all?(user_activities, fn act -> act in ~w(Delete Undo) end)
  769. refute Activity.get_by_id(activity.id)
  770. refute Activity.get_by_id(like.id)
  771. refute Activity.get_by_id(like_two.id)
  772. refute Activity.get_by_id(repeat.id)
  773. end
  774. test_with_mock "it sends out User Delete activity",
  775. %{user: user},
  776. Pleroma.Web.ActivityPub.Publisher,
  777. [:passthrough],
  778. [] do
  779. Pleroma.Config.put([:instance, :federating], true)
  780. {:ok, follower} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
  781. {:ok, _} = User.follow(follower, user)
  782. {:ok, job} = User.delete(user)
  783. {:ok, _user} = ObanHelpers.perform(job)
  784. assert ObanHelpers.member?(
  785. %{
  786. "op" => "publish_one",
  787. "params" => %{
  788. "inbox" => "http://mastodon.example.org/inbox",
  789. "id" => "pleroma:fakeid"
  790. }
  791. },
  792. all_enqueued(worker: Pleroma.Workers.PublisherWorker)
  793. )
  794. end
  795. end
  796. test "get_public_key_for_ap_id fetches a user that's not in the db" do
  797. assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
  798. end
  799. describe "insert or update a user from given data" do
  800. test "with normal data" do
  801. user = insert(:user, %{nickname: "nick@name.de"})
  802. data = %{ap_id: user.ap_id <> "xxx", name: user.name, nickname: user.nickname}
  803. assert {:ok, %User{}} = User.insert_or_update_user(data)
  804. end
  805. test "with overly long fields" do
  806. current_max_length = Pleroma.Config.get([:instance, :account_field_value_length], 255)
  807. user = insert(:user, nickname: "nickname@supergood.domain")
  808. data = %{
  809. ap_id: user.ap_id,
  810. name: user.name,
  811. nickname: user.nickname,
  812. fields: [
  813. %{"name" => "myfield", "value" => String.duplicate("h", current_max_length + 1)}
  814. ]
  815. }
  816. assert {:ok, %User{}} = User.insert_or_update_user(data)
  817. end
  818. test "with an overly long bio" do
  819. current_max_length = Pleroma.Config.get([:instance, :user_bio_length], 5000)
  820. user = insert(:user, nickname: "nickname@supergood.domain")
  821. data = %{
  822. ap_id: user.ap_id,
  823. name: user.name,
  824. nickname: user.nickname,
  825. bio: String.duplicate("h", current_max_length + 1),
  826. info: %{}
  827. }
  828. assert {:ok, %User{}} = User.insert_or_update_user(data)
  829. end
  830. test "with an overly long display name" do
  831. current_max_length = Pleroma.Config.get([:instance, :user_name_length], 100)
  832. user = insert(:user, nickname: "nickname@supergood.domain")
  833. data = %{
  834. ap_id: user.ap_id,
  835. name: String.duplicate("h", current_max_length + 1),
  836. nickname: user.nickname,
  837. info: %{}
  838. }
  839. assert {:ok, %User{}} = User.insert_or_update_user(data)
  840. end
  841. end
  842. describe "per-user rich-text filtering" do
  843. test "html_filter_policy returns default policies, when rich-text is enabled" do
  844. user = insert(:user)
  845. assert Pleroma.Config.get([:markup, :scrub_policy]) == User.html_filter_policy(user)
  846. end
  847. test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do
  848. user = insert(:user, no_rich_text: true)
  849. assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)
  850. end
  851. end
  852. describe "caching" do
  853. test "invalidate_cache works" do
  854. user = insert(:user)
  855. _user_info = User.get_cached_user_info(user)
  856. User.invalidate_cache(user)
  857. {:ok, nil} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
  858. {:ok, nil} = Cachex.get(:user_cache, "nickname:#{user.nickname}")
  859. {:ok, nil} = Cachex.get(:user_cache, "user_info:#{user.id}")
  860. end
  861. test "User.delete() plugs any possible zombie objects" do
  862. user = insert(:user)
  863. {:ok, job} = User.delete(user)
  864. {:ok, _} = ObanHelpers.perform(job)
  865. {:ok, cached_user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
  866. assert cached_user != user
  867. {:ok, cached_user} = Cachex.get(:user_cache, "nickname:#{user.ap_id}")
  868. assert cached_user != user
  869. end
  870. end
  871. test "auth_active?/1 works correctly" do
  872. Pleroma.Config.put([:instance, :account_activation_required], true)
  873. local_user = insert(:user, local: true, confirmation_pending: true)
  874. confirmed_user = insert(:user, local: true, confirmation_pending: false)
  875. remote_user = insert(:user, local: false)
  876. refute User.auth_active?(local_user)
  877. assert User.auth_active?(confirmed_user)
  878. assert User.auth_active?(remote_user)
  879. end
  880. describe "superuser?/1" do
  881. test "returns false for unprivileged users" do
  882. user = insert(:user, local: true)
  883. refute User.superuser?(user)
  884. end
  885. test "returns false for remote users" do
  886. user = insert(:user, local: false)
  887. remote_admin_user = insert(:user, local: false, is_admin: true)
  888. refute User.superuser?(user)
  889. refute User.superuser?(remote_admin_user)
  890. end
  891. test "returns true for local moderators" do
  892. user = insert(:user, local: true, is_moderator: true)
  893. assert User.superuser?(user)
  894. end
  895. test "returns true for local admins" do
  896. user = insert(:user, local: true, is_admin: true)
  897. assert User.superuser?(user)
  898. end
  899. end
  900. describe "invisible?/1" do
  901. test "returns true for an invisible user" do
  902. user = insert(:user, local: true, invisible: true)
  903. assert User.invisible?(user)
  904. end
  905. test "returns false for a non-invisible user" do
  906. user = insert(:user, local: true)
  907. refute User.invisible?(user)
  908. end
  909. end
  910. describe "visible_for?/2" do
  911. test "returns true when the account is itself" do
  912. user = insert(:user, local: true)
  913. assert User.visible_for?(user, user)
  914. end
  915. test "returns false when the account is unauthenticated and auth is required" do
  916. Pleroma.Config.put([:instance, :account_activation_required], true)
  917. user = insert(:user, local: true, confirmation_pending: true)
  918. other_user = insert(:user, local: true)
  919. refute User.visible_for?(user, other_user)
  920. end
  921. test "returns true when the account is unauthenticated and auth is not required" do
  922. user = insert(:user, local: true, confirmation_pending: true)
  923. other_user = insert(:user, local: true)
  924. assert User.visible_for?(user, other_user)
  925. end
  926. test "returns true when the account is unauthenticated and being viewed by a privileged account (auth required)" do
  927. Pleroma.Config.put([:instance, :account_activation_required], true)
  928. user = insert(:user, local: true, confirmation_pending: true)
  929. other_user = insert(:user, local: true, is_admin: true)
  930. assert User.visible_for?(user, other_user)
  931. end
  932. end
  933. describe "parse_bio/2" do
  934. test "preserves hosts in user links text" do
  935. remote_user = insert(:user, local: false, nickname: "nick@domain.com")
  936. user = insert(:user)
  937. bio = "A.k.a. @nick@domain.com"
  938. expected_text =
  939. ~s(A.k.a. <span class="h-card"><a data-user="#{remote_user.id}" class="u-url mention" href="#{
  940. remote_user.ap_id
  941. }" rel="ugc">@<span>nick@domain.com</span></a></span>)
  942. assert expected_text == User.parse_bio(bio, user)
  943. end
  944. test "Adds rel=me on linkbacked urls" do
  945. user = insert(:user, ap_id: "https://social.example.org/users/lain")
  946. bio = "http://example.com/rel_me/null"
  947. expected_text = "<a href=\"#{bio}\">#{bio}</a>"
  948. assert expected_text == User.parse_bio(bio, user)
  949. bio = "http://example.com/rel_me/link"
  950. expected_text = "<a href=\"#{bio}\" rel=\"me\">#{bio}</a>"
  951. assert expected_text == User.parse_bio(bio, user)
  952. bio = "http://example.com/rel_me/anchor"
  953. expected_text = "<a href=\"#{bio}\" rel=\"me\">#{bio}</a>"
  954. assert expected_text == User.parse_bio(bio, user)
  955. end
  956. end
  957. test "follower count is updated when a follower is blocked" do
  958. user = insert(:user)
  959. follower = insert(:user)
  960. follower2 = insert(:user)
  961. follower3 = insert(:user)
  962. {:ok, follower} = User.follow(follower, user)
  963. {:ok, _follower2} = User.follow(follower2, user)
  964. {:ok, _follower3} = User.follow(follower3, user)
  965. {:ok, user} = User.block(user, follower)
  966. assert User.user_info(user).follower_count == 2
  967. end
  968. describe "list_inactive_users_query/1" do
  969. defp days_ago(days) do
  970. NaiveDateTime.add(
  971. NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second),
  972. -days * 60 * 60 * 24,
  973. :second
  974. )
  975. end
  976. test "Users are inactive by default" do
  977. total = 10
  978. users =
  979. Enum.map(1..total, fn _ ->
  980. insert(:user, last_digest_emailed_at: days_ago(20), deactivated: false)
  981. end)
  982. inactive_users_ids =
  983. Pleroma.User.list_inactive_users_query()
  984. |> Pleroma.Repo.all()
  985. |> Enum.map(& &1.id)
  986. Enum.each(users, fn user ->
  987. assert user.id in inactive_users_ids
  988. end)
  989. end
  990. test "Only includes users who has no recent activity" do
  991. total = 10
  992. users =
  993. Enum.map(1..total, fn _ ->
  994. insert(:user, last_digest_emailed_at: days_ago(20), deactivated: false)
  995. end)
  996. {inactive, active} = Enum.split(users, trunc(total / 2))
  997. Enum.map(active, fn user ->
  998. to = Enum.random(users -- [user])
  999. {:ok, _} =
  1000. CommonAPI.post(user, %{
  1001. "status" => "hey @#{to.nickname}"
  1002. })
  1003. end)
  1004. inactive_users_ids =
  1005. Pleroma.User.list_inactive_users_query()
  1006. |> Pleroma.Repo.all()
  1007. |> Enum.map(& &1.id)
  1008. Enum.each(active, fn user ->
  1009. refute user.id in inactive_users_ids
  1010. end)
  1011. Enum.each(inactive, fn user ->
  1012. assert user.id in inactive_users_ids
  1013. end)
  1014. end
  1015. test "Only includes users with no read notifications" do
  1016. total = 10
  1017. users =
  1018. Enum.map(1..total, fn _ ->
  1019. insert(:user, last_digest_emailed_at: days_ago(20), deactivated: false)
  1020. end)
  1021. [sender | recipients] = users
  1022. {inactive, active} = Enum.split(recipients, trunc(total / 2))
  1023. Enum.each(recipients, fn to ->
  1024. {:ok, _} =
  1025. CommonAPI.post(sender, %{
  1026. "status" => "hey @#{to.nickname}"
  1027. })
  1028. {:ok, _} =
  1029. CommonAPI.post(sender, %{
  1030. "status" => "hey again @#{to.nickname}"
  1031. })
  1032. end)
  1033. Enum.each(active, fn user ->
  1034. [n1, _n2] = Pleroma.Notification.for_user(user)
  1035. {:ok, _} = Pleroma.Notification.read_one(user, n1.id)
  1036. end)
  1037. inactive_users_ids =
  1038. Pleroma.User.list_inactive_users_query()
  1039. |> Pleroma.Repo.all()
  1040. |> Enum.map(& &1.id)
  1041. Enum.each(active, fn user ->
  1042. refute user.id in inactive_users_ids
  1043. end)
  1044. Enum.each(inactive, fn user ->
  1045. assert user.id in inactive_users_ids
  1046. end)
  1047. end
  1048. end
  1049. describe "toggle_confirmation/1" do
  1050. test "if user is confirmed" do
  1051. user = insert(:user, confirmation_pending: false)
  1052. {:ok, user} = User.toggle_confirmation(user)
  1053. assert user.confirmation_pending
  1054. assert user.confirmation_token
  1055. end
  1056. test "if user is unconfirmed" do
  1057. user = insert(:user, confirmation_pending: true, confirmation_token: "some token")
  1058. {:ok, user} = User.toggle_confirmation(user)
  1059. refute user.confirmation_pending
  1060. refute user.confirmation_token
  1061. end
  1062. end
  1063. describe "ensure_keys_present" do
  1064. test "it creates keys for a user and stores them in info" do
  1065. user = insert(:user)
  1066. refute is_binary(user.keys)
  1067. {:ok, user} = User.ensure_keys_present(user)
  1068. assert is_binary(user.keys)
  1069. end
  1070. test "it doesn't create keys if there already are some" do
  1071. user = insert(:user, keys: "xxx")
  1072. {:ok, user} = User.ensure_keys_present(user)
  1073. assert user.keys == "xxx"
  1074. end
  1075. end
  1076. describe "get_ap_ids_by_nicknames" do
  1077. test "it returns a list of AP ids for a given set of nicknames" do
  1078. user = insert(:user)
  1079. user_two = insert(:user)
  1080. ap_ids = User.get_ap_ids_by_nicknames([user.nickname, user_two.nickname, "nonexistent"])
  1081. assert length(ap_ids) == 2
  1082. assert user.ap_id in ap_ids
  1083. assert user_two.ap_id in ap_ids
  1084. end
  1085. end
  1086. describe "sync followers count" do
  1087. setup do
  1088. user1 = insert(:user, local: false, ap_id: "http://localhost:4001/users/masto_closed")
  1089. user2 = insert(:user, local: false, ap_id: "http://localhost:4001/users/fuser2")
  1090. insert(:user, local: true)
  1091. insert(:user, local: false, deactivated: true)
  1092. {:ok, user1: user1, user2: user2}
  1093. end
  1094. test "external_users/1 external active users with limit", %{user1: user1, user2: user2} do
  1095. [fdb_user1] = User.external_users(limit: 1)
  1096. assert fdb_user1.ap_id
  1097. assert fdb_user1.ap_id == user1.ap_id
  1098. assert fdb_user1.id == user1.id
  1099. [fdb_user2] = User.external_users(max_id: fdb_user1.id, limit: 1)
  1100. assert fdb_user2.ap_id
  1101. assert fdb_user2.ap_id == user2.ap_id
  1102. assert fdb_user2.id == user2.id
  1103. assert User.external_users(max_id: fdb_user2.id, limit: 1) == []
  1104. end
  1105. end
  1106. describe "set_info_cache/2" do
  1107. setup do
  1108. user = insert(:user)
  1109. {:ok, user: user}
  1110. end
  1111. test "update from args", %{user: user} do
  1112. User.set_info_cache(user, %{following_count: 15, follower_count: 18})
  1113. %{follower_count: followers, following_count: following} = User.get_cached_user_info(user)
  1114. assert followers == 18
  1115. assert following == 15
  1116. end
  1117. test "without args", %{user: user} do
  1118. User.set_info_cache(user, %{})
  1119. %{follower_count: followers, following_count: following} = User.get_cached_user_info(user)
  1120. assert followers == 0
  1121. assert following == 0
  1122. end
  1123. end
  1124. describe "user_info/2" do
  1125. setup do
  1126. user = insert(:user)
  1127. {:ok, user: user}
  1128. end
  1129. test "update from args", %{user: user} do
  1130. %{follower_count: followers, following_count: following} =
  1131. User.user_info(user, %{following_count: 15, follower_count: 18})
  1132. assert followers == 18
  1133. assert following == 15
  1134. end
  1135. test "without args", %{user: user} do
  1136. %{follower_count: followers, following_count: following} = User.user_info(user)
  1137. assert followers == 0
  1138. assert following == 0
  1139. end
  1140. end
  1141. describe "is_internal_user?/1" do
  1142. test "non-internal user returns false" do
  1143. user = insert(:user)
  1144. refute User.is_internal_user?(user)
  1145. end
  1146. test "user with no nickname returns true" do
  1147. user = insert(:user, %{nickname: nil})
  1148. assert User.is_internal_user?(user)
  1149. end
  1150. test "user with internal-prefixed nickname returns true" do
  1151. user = insert(:user, %{nickname: "internal.test"})
  1152. assert User.is_internal_user?(user)
  1153. end
  1154. end
  1155. describe "update_and_set_cache/1" do
  1156. test "returns error when user is stale instead Ecto.StaleEntryError" do
  1157. user = insert(:user)
  1158. changeset = Ecto.Changeset.change(user, bio: "test")
  1159. Repo.delete(user)
  1160. assert {:error, %Ecto.Changeset{errors: [id: {"is stale", [stale: true]}], valid?: false}} =
  1161. User.update_and_set_cache(changeset)
  1162. end
  1163. test "performs update cache if user updated" do
  1164. user = insert(:user)
  1165. assert {:ok, nil} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
  1166. changeset = Ecto.Changeset.change(user, bio: "test-bio")
  1167. assert {:ok, %User{bio: "test-bio"} = user} = User.update_and_set_cache(changeset)
  1168. assert {:ok, user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
  1169. assert %User{bio: "test-bio"} = User.get_cached_by_ap_id(user.ap_id)
  1170. end
  1171. end
  1172. describe "following/followers synchronization" do
  1173. clear_config([:instance, :external_user_synchronization])
  1174. test "updates the counters normally on following/getting a follow when disabled" do
  1175. Pleroma.Config.put([:instance, :external_user_synchronization], false)
  1176. user = insert(:user)
  1177. other_user =
  1178. insert(:user,
  1179. local: false,
  1180. follower_address: "http://localhost:4001/users/masto_closed/followers",
  1181. following_address: "http://localhost:4001/users/masto_closed/following",
  1182. ap_enabled: true
  1183. )
  1184. assert User.user_info(other_user).following_count == 0
  1185. assert User.user_info(other_user).follower_count == 0
  1186. {:ok, user} = Pleroma.User.follow(user, other_user)
  1187. other_user = Pleroma.User.get_by_id(other_user.id)
  1188. assert User.user_info(user).following_count == 1
  1189. assert User.user_info(other_user).follower_count == 1
  1190. end
  1191. test "syncronizes the counters with the remote instance for the followed when enabled" do
  1192. Pleroma.Config.put([:instance, :external_user_synchronization], false)
  1193. user = insert(:user)
  1194. other_user =
  1195. insert(:user,
  1196. local: false,
  1197. follower_address: "http://localhost:4001/users/masto_closed/followers",
  1198. following_address: "http://localhost:4001/users/masto_closed/following",
  1199. ap_enabled: true
  1200. )
  1201. assert User.user_info(other_user).following_count == 0
  1202. assert User.user_info(other_user).follower_count == 0
  1203. Pleroma.Config.put([:instance, :external_user_synchronization], true)
  1204. {:ok, _user} = User.follow(user, other_user)
  1205. other_user = User.get_by_id(other_user.id)
  1206. assert User.user_info(other_user).follower_count == 437
  1207. end
  1208. test "syncronizes the counters with the remote instance for the follower when enabled" do
  1209. Pleroma.Config.put([:instance, :external_user_synchronization], false)
  1210. user = insert(:user)
  1211. other_user =
  1212. insert(:user,
  1213. local: false,
  1214. follower_address: "http://localhost:4001/users/masto_closed/followers",
  1215. following_address: "http://localhost:4001/users/masto_closed/following",
  1216. ap_enabled: true
  1217. )
  1218. assert User.user_info(other_user).following_count == 0
  1219. assert User.user_info(other_user).follower_count == 0
  1220. Pleroma.Config.put([:instance, :external_user_synchronization], true)
  1221. {:ok, other_user} = User.follow(other_user, user)
  1222. assert User.user_info(other_user).following_count == 152
  1223. end
  1224. end
  1225. describe "change_email/2" do
  1226. setup do
  1227. [user: insert(:user)]
  1228. end
  1229. test "blank email returns error", %{user: user} do
  1230. assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, "")
  1231. assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, nil)
  1232. end
  1233. test "non unique email returns error", %{user: user} do
  1234. %{email: email} = insert(:user)
  1235. assert {:error, %{errors: [email: {"has already been taken", _}]}} =
  1236. User.change_email(user, email)
  1237. end
  1238. test "invalid email returns error", %{user: user} do
  1239. assert {:error, %{errors: [email: {"has invalid format", _}]}} =
  1240. User.change_email(user, "cofe")
  1241. end
  1242. test "changes email", %{user: user} do
  1243. assert {:ok, %User{email: "cofe@cofe.party"}} = User.change_email(user, "cofe@cofe.party")
  1244. end
  1245. end
  1246. describe "get_cached_by_nickname_or_id" do
  1247. setup do
  1248. limit_to_local_content = Pleroma.Config.get([:instance, :limit_to_local_content])
  1249. local_user = insert(:user)
  1250. remote_user = insert(:user, nickname: "nickname@example.com", local: false)
  1251. on_exit(fn ->
  1252. Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local_content)
  1253. end)
  1254. [local_user: local_user, remote_user: remote_user]
  1255. end
  1256. test "allows getting remote users by id no matter what :limit_to_local_content is set to", %{
  1257. remote_user: remote_user
  1258. } do
  1259. Pleroma.Config.put([:instance, :limit_to_local_content], false)
  1260. assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
  1261. Pleroma.Config.put([:instance, :limit_to_local_content], true)
  1262. assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
  1263. Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
  1264. assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
  1265. end
  1266. test "disallows getting remote users by nickname without authentication when :limit_to_local_content is set to :unauthenticated",
  1267. %{remote_user: remote_user} do
  1268. Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
  1269. assert nil == User.get_cached_by_nickname_or_id(remote_user.nickname)
  1270. end
  1271. test "allows getting remote users by nickname with authentication when :limit_to_local_content is set to :unauthenticated",
  1272. %{remote_user: remote_user, local_user: local_user} do
  1273. Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
  1274. assert %User{} = User.get_cached_by_nickname_or_id(remote_user.nickname, for: local_user)
  1275. end
  1276. test "disallows getting remote users by nickname when :limit_to_local_content is set to true",
  1277. %{remote_user: remote_user} do
  1278. Pleroma.Config.put([:instance, :limit_to_local_content], true)
  1279. assert nil == User.get_cached_by_nickname_or_id(remote_user.nickname)
  1280. end
  1281. test "allows getting local users by nickname no matter what :limit_to_local_content is set to",
  1282. %{local_user: local_user} do
  1283. Pleroma.Config.put([:instance, :limit_to_local_content], false)
  1284. assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
  1285. Pleroma.Config.put([:instance, :limit_to_local_content], true)
  1286. assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
  1287. Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
  1288. assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
  1289. end
  1290. end
  1291. describe "update_email_notifications/2" do
  1292. setup do
  1293. user = insert(:user, email_notifications: %{"digest" => true})
  1294. {:ok, user: user}
  1295. end
  1296. test "Notifications are updated", %{user: user} do
  1297. true = user.email_notifications["digest"]
  1298. assert {:ok, result} = User.update_email_notifications(user, %{"digest" => false})
  1299. assert result.email_notifications["digest"] == false
  1300. end
  1301. end
  1302. end