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.

1617 lines
48KB

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