logo

pleroma

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

account_view_test.exs (28281B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
  5. use Pleroma.DataCase, async: false
  6. alias Pleroma.UnstubbedConfigMock, as: ConfigMock
  7. alias Pleroma.User
  8. alias Pleroma.UserRelationship
  9. alias Pleroma.Web.CommonAPI
  10. alias Pleroma.Web.MastodonAPI.AccountView
  11. import Mox
  12. import Pleroma.Factory
  13. import Tesla.Mock
  14. setup do
  15. mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
  16. :ok
  17. end
  18. test "Represent a user account" do
  19. background_image = %{
  20. "url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}]
  21. }
  22. user =
  23. insert(:user, %{
  24. follower_count: 3,
  25. note_count: 5,
  26. background: background_image,
  27. nickname: "shp@shitposter.club",
  28. name: ":karjalanpiirakka: shp",
  29. bio:
  30. "<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f '&<>\"",
  31. inserted_at: ~N[2017-08-15 15:47:06.597036],
  32. emoji: %{"karjalanpiirakka" => "/file.png"},
  33. raw_bio: "valid html. a\nb\nc\nd\nf '&<>\"",
  34. also_known_as: ["https://shitposter.zone/users/shp"],
  35. last_status_at: NaiveDateTime.utc_now()
  36. })
  37. expected = %{
  38. id: to_string(user.id),
  39. username: "shp",
  40. acct: user.nickname,
  41. display_name: user.name,
  42. locked: false,
  43. created_at: "2017-08-15T15:47:06.000Z",
  44. followers_count: 3,
  45. following_count: 0,
  46. statuses_count: 5,
  47. note: "<span>valid html</span>. a<br/>b<br/>c<br/>d<br/>f &#39;&amp;&lt;&gt;&quot;",
  48. url: user.ap_id,
  49. avatar: "http://localhost:4001/images/avi.png",
  50. avatar_static: "http://localhost:4001/images/avi.png",
  51. header: "http://localhost:4001/images/banner.png",
  52. header_static: "http://localhost:4001/images/banner.png",
  53. emojis: [
  54. %{
  55. static_url: "/file.png",
  56. url: "/file.png",
  57. shortcode: "karjalanpiirakka",
  58. visible_in_picker: false
  59. }
  60. ],
  61. fields: [],
  62. bot: false,
  63. source: %{
  64. note: "valid html. a\nb\nc\nd\nf '&<>\"",
  65. sensitive: false,
  66. pleroma: %{
  67. actor_type: "Person",
  68. discoverable: true
  69. },
  70. fields: []
  71. },
  72. fqn: "shp@shitposter.club",
  73. last_status_at: user.last_status_at |> NaiveDateTime.to_date() |> Date.to_iso8601(),
  74. pleroma: %{
  75. ap_id: user.ap_id,
  76. also_known_as: ["https://shitposter.zone/users/shp"],
  77. background_image: "https://example.com/images/asuka_hospital.png",
  78. favicon: nil,
  79. is_confirmed: true,
  80. tags: [],
  81. is_admin: false,
  82. is_moderator: false,
  83. privileges: [],
  84. is_suggested: false,
  85. hide_favorites: true,
  86. hide_followers: false,
  87. hide_follows: false,
  88. hide_followers_count: false,
  89. hide_follows_count: false,
  90. relationship: %{},
  91. skip_thread_containment: false,
  92. accepts_chat_messages: nil,
  93. avatar_description: "",
  94. header_description: ""
  95. }
  96. }
  97. assert expected == AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  98. end
  99. describe "roles and privileges" do
  100. setup do
  101. clear_config([:instance, :moderator_privileges], [:cofe, :only_moderator])
  102. clear_config([:instance, :admin_privileges], [:cofe, :only_admin])
  103. %{
  104. user: insert(:user),
  105. moderator: insert(:user, is_moderator: true),
  106. admin: insert(:user, is_admin: true),
  107. moderator_admin: insert(:user, is_moderator: true, is_admin: true),
  108. user_no_show_roles: insert(:user, show_role: false),
  109. moderator_admin_no_show_roles:
  110. insert(:user, is_moderator: true, is_admin: true, show_role: false)
  111. }
  112. end
  113. test "shows roles and privileges when show_role: true", %{
  114. user: user,
  115. moderator: moderator,
  116. admin: admin,
  117. moderator_admin: moderator_admin,
  118. user_no_show_roles: user_no_show_roles,
  119. moderator_admin_no_show_roles: moderator_admin_no_show_roles
  120. } do
  121. assert %{pleroma: %{is_moderator: false, is_admin: false}} =
  122. AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  123. assert [] ==
  124. AccountView.render("show.json", %{user: user, skip_visibility_check: true})[
  125. :pleroma
  126. ][:privileges]
  127. |> Enum.sort()
  128. assert %{pleroma: %{is_moderator: true, is_admin: false}} =
  129. AccountView.render("show.json", %{user: moderator, skip_visibility_check: true})
  130. assert [:cofe, :only_moderator] ==
  131. AccountView.render("show.json", %{user: moderator, skip_visibility_check: true})[
  132. :pleroma
  133. ][:privileges]
  134. |> Enum.sort()
  135. assert %{pleroma: %{is_moderator: false, is_admin: true}} =
  136. AccountView.render("show.json", %{user: admin, skip_visibility_check: true})
  137. assert [:cofe, :only_admin] ==
  138. AccountView.render("show.json", %{user: admin, skip_visibility_check: true})[
  139. :pleroma
  140. ][:privileges]
  141. |> Enum.sort()
  142. assert %{pleroma: %{is_moderator: true, is_admin: true}} =
  143. AccountView.render("show.json", %{
  144. user: moderator_admin,
  145. skip_visibility_check: true
  146. })
  147. assert [:cofe, :only_admin, :only_moderator] ==
  148. AccountView.render("show.json", %{
  149. user: moderator_admin,
  150. skip_visibility_check: true
  151. })[:pleroma][:privileges]
  152. |> Enum.sort()
  153. refute match?(
  154. %{pleroma: %{is_moderator: _}},
  155. AccountView.render("show.json", %{
  156. user: user_no_show_roles,
  157. skip_visibility_check: true
  158. })
  159. )
  160. refute match?(
  161. %{pleroma: %{is_admin: _}},
  162. AccountView.render("show.json", %{
  163. user: user_no_show_roles,
  164. skip_visibility_check: true
  165. })
  166. )
  167. refute match?(
  168. %{pleroma: %{privileges: _}},
  169. AccountView.render("show.json", %{
  170. user: user_no_show_roles,
  171. skip_visibility_check: true
  172. })
  173. )
  174. refute match?(
  175. %{pleroma: %{is_moderator: _}},
  176. AccountView.render("show.json", %{
  177. user: moderator_admin_no_show_roles,
  178. skip_visibility_check: true
  179. })
  180. )
  181. refute match?(
  182. %{pleroma: %{is_admin: _}},
  183. AccountView.render("show.json", %{
  184. user: moderator_admin_no_show_roles,
  185. skip_visibility_check: true
  186. })
  187. )
  188. refute match?(
  189. %{pleroma: %{privileges: _}},
  190. AccountView.render("show.json", %{
  191. user: moderator_admin_no_show_roles,
  192. skip_visibility_check: true
  193. })
  194. )
  195. end
  196. test "shows roles and privileges when viewing own account, even when show_role: false", %{
  197. user_no_show_roles: user_no_show_roles,
  198. moderator_admin_no_show_roles: moderator_admin_no_show_roles
  199. } do
  200. assert %{pleroma: %{is_moderator: false, is_admin: false, privileges: []}} =
  201. AccountView.render("show.json", %{
  202. user: user_no_show_roles,
  203. skip_visibility_check: true,
  204. for: user_no_show_roles
  205. })
  206. assert %{
  207. pleroma: %{
  208. is_moderator: true,
  209. is_admin: true,
  210. privileges: privileges
  211. }
  212. } =
  213. AccountView.render("show.json", %{
  214. user: moderator_admin_no_show_roles,
  215. skip_visibility_check: true,
  216. for: moderator_admin_no_show_roles
  217. })
  218. assert [:cofe, :only_admin, :only_moderator] == privileges |> Enum.sort()
  219. end
  220. end
  221. describe "favicon" do
  222. setup do
  223. [user: insert(:user)]
  224. end
  225. test "is parsed when :instance_favicons is enabled", %{user: user} do
  226. clear_config([:instances_favicons, :enabled], true)
  227. assert %{
  228. pleroma: %{
  229. favicon:
  230. "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png"
  231. }
  232. } = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  233. end
  234. test "is nil when :instances_favicons is disabled", %{user: user} do
  235. assert %{pleroma: %{favicon: nil}} =
  236. AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  237. end
  238. end
  239. test "Represent the user account for the account owner" do
  240. user = insert(:user)
  241. notification_settings = %{
  242. block_from_strangers: false,
  243. hide_notification_contents: false
  244. }
  245. privacy = user.default_scope
  246. assert %{
  247. pleroma: %{notification_settings: ^notification_settings, allow_following_move: true},
  248. source: %{privacy: ^privacy}
  249. } = AccountView.render("show.json", %{user: user, for: user})
  250. end
  251. test "Represent a Service(bot) account" do
  252. user =
  253. insert(:user, %{
  254. follower_count: 3,
  255. note_count: 5,
  256. actor_type: "Service",
  257. nickname: "shp@shitposter.club",
  258. inserted_at: ~N[2017-08-15 15:47:06.597036]
  259. })
  260. expected = %{
  261. id: to_string(user.id),
  262. username: "shp",
  263. acct: user.nickname,
  264. display_name: user.name,
  265. locked: false,
  266. created_at: "2017-08-15T15:47:06.000Z",
  267. followers_count: 3,
  268. following_count: 0,
  269. statuses_count: 5,
  270. note: user.bio,
  271. url: user.ap_id,
  272. avatar: "http://localhost:4001/images/avi.png",
  273. avatar_static: "http://localhost:4001/images/avi.png",
  274. header: "http://localhost:4001/images/banner.png",
  275. header_static: "http://localhost:4001/images/banner.png",
  276. emojis: [],
  277. fields: [],
  278. bot: true,
  279. source: %{
  280. note: user.bio,
  281. sensitive: false,
  282. pleroma: %{
  283. actor_type: "Service",
  284. discoverable: true
  285. },
  286. fields: []
  287. },
  288. fqn: "shp@shitposter.club",
  289. last_status_at: nil,
  290. pleroma: %{
  291. ap_id: user.ap_id,
  292. also_known_as: [],
  293. background_image: nil,
  294. favicon: nil,
  295. is_confirmed: true,
  296. tags: [],
  297. is_admin: false,
  298. is_moderator: false,
  299. privileges: [],
  300. is_suggested: false,
  301. hide_favorites: true,
  302. hide_followers: false,
  303. hide_follows: false,
  304. hide_followers_count: false,
  305. hide_follows_count: false,
  306. relationship: %{},
  307. skip_thread_containment: false,
  308. accepts_chat_messages: nil,
  309. avatar_description: "",
  310. header_description: ""
  311. }
  312. }
  313. assert expected == AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  314. end
  315. test "Represent a Funkwhale channel" do
  316. {:ok, user} =
  317. User.get_or_fetch_by_ap_id(
  318. "https://channels.tests.funkwhale.audio/federation/actors/compositions"
  319. )
  320. assert represented =
  321. AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  322. assert represented.acct == "compositions@channels.tests.funkwhale.audio"
  323. assert represented.url == "https://channels.tests.funkwhale.audio/channels/compositions"
  324. end
  325. test "Represent a deactivated user for a privileged user" do
  326. clear_config([:instance, :moderator_privileges], [:users_manage_activation_state])
  327. admin = insert(:user, is_moderator: true)
  328. deactivated_user = insert(:user, is_active: false)
  329. represented = AccountView.render("show.json", %{user: deactivated_user, for: admin})
  330. assert represented[:pleroma][:deactivated] == true
  331. end
  332. test "Represent a smaller mention" do
  333. user = insert(:user)
  334. expected = %{
  335. id: to_string(user.id),
  336. acct: user.nickname,
  337. username: user.nickname,
  338. url: user.ap_id
  339. }
  340. assert expected == AccountView.render("mention.json", %{user: user})
  341. end
  342. test "demands :for or :skip_visibility_check option for account rendering" do
  343. clear_config([:restrict_unauthenticated, :profiles, :local], false)
  344. user = insert(:user)
  345. user_id = user.id
  346. assert %{id: ^user_id} = AccountView.render("show.json", %{user: user, for: nil})
  347. assert %{id: ^user_id} = AccountView.render("show.json", %{user: user, for: user})
  348. assert %{id: ^user_id} =
  349. AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  350. assert_raise RuntimeError, ~r/:skip_visibility_check or :for option is required/, fn ->
  351. AccountView.render("show.json", %{user: user})
  352. end
  353. end
  354. describe "relationship" do
  355. defp test_relationship_rendering(user, other_user, expected_result) do
  356. opts = %{user: user, target: other_user, relationships: nil}
  357. assert expected_result == AccountView.render("relationship.json", opts)
  358. relationships_opt = UserRelationship.view_relationships_option(user, [other_user])
  359. opts = Map.put(opts, :relationships, relationships_opt)
  360. assert expected_result == AccountView.render("relationship.json", opts)
  361. assert [expected_result] ==
  362. AccountView.render("relationships.json", %{user: user, targets: [other_user]})
  363. end
  364. @blank_response %{
  365. following: false,
  366. followed_by: false,
  367. blocking: false,
  368. blocked_by: false,
  369. muting: false,
  370. muting_notifications: false,
  371. subscribing: false,
  372. notifying: false,
  373. requested: false,
  374. domain_blocking: false,
  375. showing_reblogs: true,
  376. endorsed: false,
  377. note: ""
  378. }
  379. test "represent a relationship for the following and followed user" do
  380. user = insert(:user)
  381. other_user = insert(:user)
  382. {:ok, user, other_user} = User.follow(user, other_user)
  383. {:ok, other_user, user} = User.follow(other_user, user)
  384. {:ok, _subscription} = User.subscribe(user, other_user)
  385. {:ok, _user_relationships} = User.mute(user, other_user, %{notifications: true})
  386. {:ok, _reblog_mute} = CommonAPI.hide_reblogs(other_user, user)
  387. expected =
  388. Map.merge(
  389. @blank_response,
  390. %{
  391. following: true,
  392. followed_by: true,
  393. muting: true,
  394. muting_notifications: true,
  395. subscribing: true,
  396. notifying: true,
  397. showing_reblogs: false,
  398. id: to_string(other_user.id)
  399. }
  400. )
  401. test_relationship_rendering(user, other_user, expected)
  402. end
  403. test "relationship does not indicate following if a FollowingRelationship is missing" do
  404. user = insert(:user)
  405. other_user = insert(:user, local: false)
  406. # Create a follow relationship with the real Follow Activity and Accept it
  407. assert {:ok, _, _, _} = CommonAPI.follow(other_user, user)
  408. assert {:ok, _} = CommonAPI.accept_follow_request(user, other_user)
  409. assert %{data: %{"state" => "accept"}} =
  410. Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(user, other_user)
  411. # Fetch the relationship and forcibly delete it to simulate
  412. # a Follow Accept that did not complete processing
  413. %{following_relationships: [relationship]} =
  414. Pleroma.UserRelationship.view_relationships_option(user, [other_user])
  415. assert {:ok, _} = Pleroma.Repo.delete(relationship)
  416. assert %{following_relationships: [], user_relationships: []} ==
  417. Pleroma.UserRelationship.view_relationships_option(user, [other_user])
  418. expected =
  419. Map.merge(
  420. @blank_response,
  421. %{
  422. following: false,
  423. followed_by: false,
  424. muting: false,
  425. muting_notifications: false,
  426. subscribing: false,
  427. notifying: false,
  428. showing_reblogs: true,
  429. id: to_string(other_user.id)
  430. }
  431. )
  432. test_relationship_rendering(user, other_user, expected)
  433. end
  434. test "represent a relationship for the blocking and blocked user" do
  435. user = insert(:user)
  436. other_user = insert(:user)
  437. {:ok, user, other_user} = User.follow(user, other_user)
  438. {:ok, _subscription} = User.subscribe(user, other_user)
  439. {:ok, _user_relationship} = User.block(user, other_user)
  440. {:ok, _user_relationship} = User.block(other_user, user)
  441. expected =
  442. Map.merge(
  443. @blank_response,
  444. %{following: false, blocking: true, blocked_by: true, id: to_string(other_user.id)}
  445. )
  446. test_relationship_rendering(user, other_user, expected)
  447. end
  448. test "represent a relationship for the user blocking a domain" do
  449. user = insert(:user)
  450. other_user = insert(:user, ap_id: "https://bad.site/users/other_user")
  451. {:ok, user} = User.block_domain(user, "bad.site")
  452. expected =
  453. Map.merge(
  454. @blank_response,
  455. %{domain_blocking: true, blocking: false, id: to_string(other_user.id)}
  456. )
  457. test_relationship_rendering(user, other_user, expected)
  458. end
  459. test "represent a relationship for the user with a pending follow request" do
  460. user = insert(:user)
  461. other_user = insert(:user, is_locked: true)
  462. {:ok, other_user, user, _} = CommonAPI.follow(other_user, user)
  463. user = User.get_cached_by_id(user.id)
  464. other_user = User.get_cached_by_id(other_user.id)
  465. expected =
  466. Map.merge(
  467. @blank_response,
  468. %{requested: true, following: false, id: to_string(other_user.id)}
  469. )
  470. test_relationship_rendering(user, other_user, expected)
  471. end
  472. end
  473. test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
  474. user = insert(:user, pleroma_settings_store: %{fe: "test"})
  475. result =
  476. AccountView.render("show.json", %{user: user, for: user, with_pleroma_settings: true})
  477. assert result.pleroma.settings_store == %{:fe => "test"}
  478. result = AccountView.render("show.json", %{user: user, for: nil, with_pleroma_settings: true})
  479. assert result.pleroma[:settings_store] == nil
  480. result = AccountView.render("show.json", %{user: user, for: user})
  481. assert result.pleroma[:settings_store] == nil
  482. end
  483. test "doesn't sanitize display names" do
  484. user = insert(:user, name: "<marquee> username </marquee>")
  485. result = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  486. assert result.display_name == "<marquee> username </marquee>"
  487. end
  488. test "never display nil user follow counts" do
  489. user = insert(:user, following_count: 0, follower_count: 0)
  490. result = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  491. assert result.following_count == 0
  492. assert result.followers_count == 0
  493. end
  494. describe "hiding follows/following" do
  495. test "shows when follows/followers stats are hidden and sets follow/follower count to 0" do
  496. user =
  497. insert(:user, %{
  498. hide_followers: true,
  499. hide_followers_count: true,
  500. hide_follows: true,
  501. hide_follows_count: true
  502. })
  503. other_user = insert(:user)
  504. {:ok, user, other_user, _activity} = CommonAPI.follow(other_user, user)
  505. {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
  506. assert %{
  507. followers_count: 0,
  508. following_count: 0,
  509. pleroma: %{hide_follows_count: true, hide_followers_count: true}
  510. } = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  511. end
  512. test "shows when follows/followers are hidden" do
  513. user = insert(:user, hide_followers: true, hide_follows: true)
  514. other_user = insert(:user)
  515. {:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)
  516. {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
  517. assert %{
  518. followers_count: 1,
  519. following_count: 1,
  520. pleroma: %{hide_follows: true, hide_followers: true}
  521. } = AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  522. end
  523. test "shows actual follower/following count to the account owner" do
  524. user = insert(:user, hide_followers: true, hide_follows: true)
  525. other_user = insert(:user)
  526. {:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)
  527. assert User.following?(user, other_user)
  528. assert Pleroma.FollowingRelationship.follower_count(other_user) == 1
  529. {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
  530. assert %{
  531. followers_count: 1,
  532. following_count: 1
  533. } = AccountView.render("show.json", %{user: user, for: user})
  534. end
  535. test "shows unread_conversation_count only to the account owner" do
  536. user = insert(:user)
  537. other_user = insert(:user)
  538. {:ok, _activity} =
  539. CommonAPI.post(other_user, %{
  540. status: "Hey @#{user.nickname}.",
  541. visibility: "direct"
  542. })
  543. user = User.get_cached_by_ap_id(user.ap_id)
  544. assert AccountView.render("show.json", %{user: user, for: other_user})[:pleroma][
  545. :unread_conversation_count
  546. ] == nil
  547. assert AccountView.render("show.json", %{user: user, for: user})[:pleroma][
  548. :unread_conversation_count
  549. ] == 1
  550. end
  551. test "shows unread_count only to the account owner" do
  552. user = insert(:user)
  553. insert_list(7, :notification, user: user, activity: insert(:note_activity))
  554. other_user = insert(:user)
  555. user = User.get_cached_by_ap_id(user.ap_id)
  556. assert AccountView.render(
  557. "show.json",
  558. %{user: user, for: other_user}
  559. )[:pleroma][:unread_notifications_count] == nil
  560. assert AccountView.render(
  561. "show.json",
  562. %{user: user, for: user}
  563. )[:pleroma][:unread_notifications_count] == 7
  564. end
  565. test "shows email only to the account owner" do
  566. user = insert(:user)
  567. other_user = insert(:user)
  568. user = User.get_cached_by_ap_id(user.ap_id)
  569. assert AccountView.render(
  570. "show.json",
  571. %{user: user, for: other_user}
  572. )[:pleroma][:email] == nil
  573. assert AccountView.render(
  574. "show.json",
  575. %{user: user, for: user}
  576. )[:pleroma][:email] == user.email
  577. end
  578. end
  579. describe "hiding birthday" do
  580. test "doesn't show birthday if hidden" do
  581. user =
  582. insert(:user, %{
  583. birthday: "2001-02-12",
  584. show_birthday: false
  585. })
  586. other_user = insert(:user)
  587. user = User.get_cached_by_ap_id(user.ap_id)
  588. assert AccountView.render(
  589. "show.json",
  590. %{user: user, for: other_user}
  591. )[:birthday] == nil
  592. end
  593. test "shows hidden birthday to the account owner" do
  594. user =
  595. insert(:user, %{
  596. birthday: "2001-02-12",
  597. show_birthday: false
  598. })
  599. user = User.get_cached_by_ap_id(user.ap_id)
  600. assert AccountView.render(
  601. "show.json",
  602. %{user: user, for: user}
  603. )[:birthday] == nil
  604. end
  605. end
  606. describe "follow requests counter" do
  607. test "shows zero when no follow requests are pending" do
  608. user = insert(:user)
  609. assert %{follow_requests_count: 0} =
  610. AccountView.render("show.json", %{user: user, for: user})
  611. other_user = insert(:user)
  612. {:ok, _other_user, user, _activity} = CommonAPI.follow(user, other_user)
  613. assert %{follow_requests_count: 0} =
  614. AccountView.render("show.json", %{user: user, for: user})
  615. end
  616. test "shows non-zero when follow requests are pending" do
  617. user = insert(:user, is_locked: true)
  618. assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
  619. other_user = insert(:user)
  620. {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
  621. assert %{locked: true, follow_requests_count: 1} =
  622. AccountView.render("show.json", %{user: user, for: user})
  623. end
  624. test "decreases when accepting a follow request" do
  625. user = insert(:user, is_locked: true)
  626. assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
  627. other_user = insert(:user)
  628. {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
  629. assert %{locked: true, follow_requests_count: 1} =
  630. AccountView.render("show.json", %{user: user, for: user})
  631. {:ok, _other_user} = CommonAPI.accept_follow_request(other_user, user)
  632. assert %{locked: true, follow_requests_count: 0} =
  633. AccountView.render("show.json", %{user: user, for: user})
  634. end
  635. test "decreases when rejecting a follow request" do
  636. user = insert(:user, is_locked: true)
  637. assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
  638. other_user = insert(:user)
  639. {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
  640. assert %{locked: true, follow_requests_count: 1} =
  641. AccountView.render("show.json", %{user: user, for: user})
  642. {:ok, _other_user} = CommonAPI.reject_follow_request(other_user, user)
  643. assert %{locked: true, follow_requests_count: 0} =
  644. AccountView.render("show.json", %{user: user, for: user})
  645. end
  646. test "shows non-zero when historical unapproved requests are present" do
  647. user = insert(:user, is_locked: true)
  648. assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
  649. other_user = insert(:user)
  650. {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
  651. {:ok, user} = User.update_and_set_cache(user, %{is_locked: false})
  652. assert %{locked: false, follow_requests_count: 1} =
  653. AccountView.render("show.json", %{user: user, for: user})
  654. end
  655. end
  656. test "uses mediaproxy urls when it's enabled (regardless of media preview proxy state)" do
  657. clear_config([:media_proxy, :enabled], true)
  658. clear_config([:media_preview_proxy, :enabled])
  659. ConfigMock
  660. |> stub_with(Pleroma.Test.StaticConfig)
  661. user =
  662. insert(:user,
  663. avatar: %{"url" => [%{"href" => "https://evil.website/avatar.png"}]},
  664. banner: %{"url" => [%{"href" => "https://evil.website/banner.png"}]},
  665. emoji: %{"joker_smile" => "https://evil.website/society.png"}
  666. )
  667. Enum.each([true, false], fn media_preview_enabled ->
  668. clear_config([:media_preview_proxy, :enabled], media_preview_enabled)
  669. AccountView.render("show.json", %{user: user, skip_visibility_check: true})
  670. |> Enum.all?(fn
  671. {key, url} when key in [:avatar, :avatar_static, :header, :header_static] ->
  672. String.starts_with?(url, Pleroma.Web.Endpoint.url())
  673. {:emojis, emojis} ->
  674. Enum.all?(emojis, fn %{url: url, static_url: static_url} ->
  675. String.starts_with?(url, Pleroma.Web.Endpoint.url()) &&
  676. String.starts_with?(static_url, Pleroma.Web.Endpoint.url())
  677. end)
  678. _ ->
  679. true
  680. end)
  681. |> assert()
  682. end)
  683. end
  684. test "renders mute expiration date" do
  685. user = insert(:user)
  686. other_user = insert(:user)
  687. {:ok, _user_relationships} =
  688. User.mute(user, other_user, %{notifications: true, duration: 24 * 60 * 60})
  689. %{
  690. mute_expires_at: mute_expires_at
  691. } = AccountView.render("show.json", %{user: other_user, for: user, mutes: true})
  692. assert DateTime.diff(
  693. mute_expires_at,
  694. DateTime.utc_now() |> DateTime.add(24 * 60 * 60)
  695. ) in -3..3
  696. end
  697. end