logo

pleroma

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

emoji_reaction_controller_test.exs (15320B)


  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.PleromaAPI.EmojiReactionControllerTest do
  5. use Oban.Testing, repo: Pleroma.Repo
  6. use Pleroma.Web.ConnCase
  7. alias Pleroma.Object
  8. alias Pleroma.Tests.ObanHelpers
  9. alias Pleroma.User
  10. alias Pleroma.Web.ActivityPub.Visibility
  11. alias Pleroma.Web.CommonAPI
  12. import Pleroma.Factory
  13. defp prepare_reacted_post(visibility \\ "private") do
  14. unrelated_user = insert(:user, local: true)
  15. poster = insert(:user, local: true)
  16. follower = insert(:user, local: true)
  17. {:ok, _, _, %{data: %{"state" => "accept"}}} = CommonAPI.follow(poster, follower)
  18. {:ok, post_activity} = CommonAPI.post(poster, %{status: "miaow!", visibility: visibility})
  19. if visibility != "direct" do
  20. assert Visibility.visible_for_user?(post_activity, follower)
  21. end
  22. if visibility in ["direct", "private"] do
  23. refute Visibility.visible_for_user?(post_activity, unrelated_user)
  24. end
  25. {:ok, _react_activity} = CommonAPI.react_with_emoji(post_activity.id, follower, "🐾")
  26. {post_activity, poster, follower, unrelated_user}
  27. end
  28. defp prepare_conn_of_user(conn, user) do
  29. conn
  30. |> assign(:user, user)
  31. |> assign(:token, insert(:oauth_token, user: user, scopes: ["write", "read"]))
  32. end
  33. setup do
  34. Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Test.StaticConfig)
  35. :ok
  36. end
  37. test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
  38. user = insert(:user)
  39. other_user = insert(:user)
  40. note = insert(:note, user: user, data: %{"reactions" => [["👍", [other_user.ap_id], nil]]})
  41. activity = insert(:note_activity, note: note, user: user)
  42. result =
  43. conn
  44. |> assign(:user, other_user)
  45. |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
  46. |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/\u26A0")
  47. |> json_response_and_validate_schema(200)
  48. assert %{"id" => id} = result
  49. assert to_string(activity.id) == id
  50. assert result["pleroma"]["emoji_reactions"] == [
  51. %{
  52. "name" => "👍",
  53. "count" => 1,
  54. "me" => true,
  55. "url" => nil,
  56. "account_ids" => [other_user.id]
  57. },
  58. %{
  59. "name" => "\u26A0\uFE0F",
  60. "count" => 1,
  61. "me" => true,
  62. "url" => nil,
  63. "account_ids" => [other_user.id]
  64. }
  65. ]
  66. {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
  67. ObanHelpers.perform_all()
  68. # Reacting with a custom emoji
  69. result =
  70. conn
  71. |> assign(:user, other_user)
  72. |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
  73. |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/:dinosaur:")
  74. |> json_response_and_validate_schema(200)
  75. assert %{"id" => id} = result
  76. assert to_string(activity.id) == id
  77. assert result["pleroma"]["emoji_reactions"] == [
  78. %{
  79. "name" => "dinosaur",
  80. "count" => 1,
  81. "me" => true,
  82. "url" => "http://localhost:4001/emoji/dino%20walking.gif",
  83. "account_ids" => [other_user.id]
  84. }
  85. ]
  86. # Reacting with a remote emoji
  87. note =
  88. insert(:note,
  89. user: user,
  90. data: %{
  91. "reactions" => [
  92. ["👍", [other_user.ap_id], nil],
  93. ["wow", [other_user.ap_id], "https://remote/emoji/wow"]
  94. ]
  95. }
  96. )
  97. activity = insert(:note_activity, note: note, user: user)
  98. result =
  99. conn
  100. |> assign(:user, user)
  101. |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"]))
  102. |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/:wow@remote:")
  103. |> json_response(200)
  104. assert result["pleroma"]["emoji_reactions"] == [
  105. %{
  106. "account_ids" => [other_user.id],
  107. "count" => 1,
  108. "me" => false,
  109. "name" => "👍",
  110. "url" => nil
  111. },
  112. %{
  113. "name" => "wow@remote",
  114. "count" => 2,
  115. "me" => true,
  116. "url" => "https://remote/emoji/wow",
  117. "account_ids" => [user.id, other_user.id]
  118. }
  119. ]
  120. # Reacting with a remote custom emoji that hasn't been reacted with yet
  121. note =
  122. insert(:note,
  123. user: user
  124. )
  125. activity = insert(:note_activity, note: note, user: user)
  126. assert conn
  127. |> assign(:user, user)
  128. |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"]))
  129. |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/:wow@remote:")
  130. |> json_response(400)
  131. # Reacting with a non-emoji
  132. assert conn
  133. |> assign(:user, other_user)
  134. |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
  135. |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/x")
  136. |> json_response_and_validate_schema(400)
  137. end
  138. test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji not allowed for non-visible posts", %{
  139. conn: conn
  140. } do
  141. {%{id: activity_id} = _activity, _author, follower, stranger} = prepare_reacted_post()
  142. # Works for follower
  143. resp =
  144. prepare_conn_of_user(conn, follower)
  145. |> put("/api/v1/pleroma/statuses/#{activity_id}/reactions/🐈")
  146. |> json_response_and_validate_schema(200)
  147. assert match?(%{"id" => ^activity_id}, resp)
  148. # Fails for stranger
  149. resp =
  150. prepare_conn_of_user(conn, stranger)
  151. |> put("/api/v1/pleroma/statuses/#{activity_id}/reactions/🐈")
  152. |> json_response_and_validate_schema(404)
  153. assert match?(%{"error" => "Record not found"}, resp)
  154. end
  155. test "DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
  156. user = insert(:user)
  157. other_user = insert(:user)
  158. note =
  159. insert(:note,
  160. user: user,
  161. data: %{"reactions" => [["wow", [user.ap_id], "https://remote/emoji/wow"]]}
  162. )
  163. activity = insert(:note_activity, note: note, user: user)
  164. ObanHelpers.perform_all()
  165. {:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
  166. {:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, ":dinosaur:")
  167. {:ok, _reaction_activity} =
  168. CommonAPI.react_with_emoji(activity.id, other_user, ":wow@remote:")
  169. ObanHelpers.perform_all()
  170. result =
  171. conn
  172. |> assign(:user, other_user)
  173. |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
  174. |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕")
  175. assert %{"id" => id} = json_response_and_validate_schema(result, 200)
  176. assert to_string(activity.id) == id
  177. # Remove custom emoji
  178. result =
  179. conn
  180. |> assign(:user, other_user)
  181. |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
  182. |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/:dinosaur:")
  183. assert %{"id" => id} = json_response_and_validate_schema(result, 200)
  184. assert to_string(activity.id) == id
  185. ObanHelpers.perform_all()
  186. object = Object.get_by_ap_id(activity.data["object"])
  187. assert object.data["reaction_count"] == 2
  188. # Remove custom remote emoji
  189. result =
  190. conn
  191. |> assign(:user, other_user)
  192. |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
  193. |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/:wow@remote:")
  194. |> json_response(200)
  195. assert result["pleroma"]["emoji_reactions"] == [
  196. %{
  197. "name" => "wow@remote",
  198. "count" => 1,
  199. "me" => false,
  200. "url" => "https://remote/emoji/wow",
  201. "account_ids" => [user.id]
  202. }
  203. ]
  204. # Remove custom remote emoji that hasn't been reacted with yet
  205. assert conn
  206. |> assign(:user, other_user)
  207. |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
  208. |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/:zoop@remote:")
  209. |> json_response(400)
  210. end
  211. test "DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji only allows original reacter to revoke",
  212. %{conn: conn} do
  213. {%{id: activity_id} = _activity, author, follower, unrelated} = prepare_reacted_post("public")
  214. # Works for original reacter
  215. prepare_conn_of_user(conn, follower)
  216. |> delete("/api/v1/pleroma/statuses/#{activity_id}/reactions/🐾")
  217. |> json_response_and_validate_schema(200)
  218. # Fails for anyone else
  219. for u <- [author, unrelated] do
  220. resp =
  221. prepare_conn_of_user(conn, u)
  222. |> delete("/api/v1/pleroma/statuses/#{activity_id}/reactions/🐾")
  223. |> json_response(400)
  224. assert match?(%{"error" => _}, resp)
  225. end
  226. end
  227. test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do
  228. user = insert(:user)
  229. other_user = insert(:user)
  230. doomed_user = insert(:user)
  231. {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
  232. result =
  233. conn
  234. |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
  235. |> json_response_and_validate_schema(200)
  236. assert result == []
  237. {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
  238. {:ok, _} = CommonAPI.react_with_emoji(activity.id, doomed_user, "🎅")
  239. User.perform(:delete, doomed_user)
  240. result =
  241. conn
  242. |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
  243. |> json_response_and_validate_schema(200)
  244. [%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = result
  245. assert represented_user["id"] == other_user.id
  246. result =
  247. conn
  248. |> assign(:user, other_user)
  249. |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:statuses"]))
  250. |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
  251. |> json_response_and_validate_schema(200)
  252. assert [%{"name" => "🎅", "count" => 1, "accounts" => [_represented_user], "me" => true}] =
  253. result
  254. end
  255. test "GET /api/v1/pleroma/statuses/:id/reactions with legacy format", %{conn: conn} do
  256. user = insert(:user)
  257. other_user = insert(:user)
  258. note =
  259. insert(:note,
  260. user: user,
  261. data: %{
  262. "reactions" => [["😿", [other_user.ap_id]]]
  263. }
  264. )
  265. activity = insert(:note_activity, user: user, note: note)
  266. result =
  267. conn
  268. |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
  269. |> json_response_and_validate_schema(200)
  270. other_user_id = other_user.id
  271. assert [
  272. %{
  273. "name" => "😿",
  274. "count" => 1,
  275. "me" => false,
  276. "url" => nil,
  277. "accounts" => [%{"id" => ^other_user_id}]
  278. }
  279. ] = result
  280. end
  281. test "GET /api/v1/pleroma/statuses/:id/reactions?with_muted=true", %{conn: conn} do
  282. user = insert(:user)
  283. user2 = insert(:user)
  284. user3 = insert(:user)
  285. token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
  286. {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
  287. {:ok, _} = CommonAPI.react_with_emoji(activity.id, user2, "🎅")
  288. {:ok, _} = CommonAPI.react_with_emoji(activity.id, user3, "🎅")
  289. result =
  290. conn
  291. |> assign(:user, user)
  292. |> assign(:token, token)
  293. |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
  294. |> json_response_and_validate_schema(200)
  295. assert [%{"name" => "🎅", "count" => 2}] = result
  296. User.mute(user, user3)
  297. result =
  298. conn
  299. |> assign(:user, user)
  300. |> assign(:token, token)
  301. |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
  302. |> json_response_and_validate_schema(200)
  303. assert [%{"name" => "🎅", "count" => 1}] = result
  304. result =
  305. conn
  306. |> assign(:user, user)
  307. |> assign(:token, token)
  308. |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions?with_muted=true")
  309. |> json_response_and_validate_schema(200)
  310. assert [%{"name" => "🎅", "count" => 2}] = result
  311. end
  312. test "GET /api/v1/pleroma/statuses/:id/reactions not allowed for non-visible posts", %{
  313. conn: conn
  314. } do
  315. {%{id: activity_id} = _activity, _author, follower, stranger} = prepare_reacted_post()
  316. # Works for follower
  317. resp =
  318. prepare_conn_of_user(conn, follower)
  319. |> get("/api/v1/pleroma/statuses/#{activity_id}/reactions")
  320. |> json_response_and_validate_schema(200)
  321. assert match?([%{"name" => _, "count" => _} | _], resp)
  322. # Fails for stranger
  323. assert prepare_conn_of_user(conn, stranger)
  324. |> get("/api/v1/pleroma/statuses/#{activity_id}/reactions")
  325. |> json_response_and_validate_schema(404) == %{"error" => "Record not found"}
  326. end
  327. test "GET /api/v1/pleroma/statuses/:id/reactions with :show_reactions disabled", %{conn: conn} do
  328. clear_config([:instance, :show_reactions], false)
  329. user = insert(:user)
  330. other_user = insert(:user)
  331. {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
  332. {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
  333. result =
  334. conn
  335. |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
  336. |> json_response_and_validate_schema(200)
  337. assert result == []
  338. end
  339. test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
  340. user = insert(:user)
  341. other_user = insert(:user)
  342. {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
  343. result =
  344. conn
  345. |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅")
  346. |> json_response_and_validate_schema(200)
  347. assert result == []
  348. {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
  349. {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
  350. assert [
  351. %{
  352. "name" => "🎅",
  353. "count" => 1,
  354. "accounts" => [represented_user],
  355. "me" => false,
  356. "url" => nil
  357. }
  358. ] =
  359. conn
  360. |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅")
  361. |> json_response_and_validate_schema(200)
  362. assert represented_user["id"] == other_user.id
  363. end
  364. test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji not allowed for non-visible posts", %{
  365. conn: conn
  366. } do
  367. {%{id: activity_id} = _activity, _author, follower, stranger} = prepare_reacted_post()
  368. # Works for follower
  369. assert prepare_conn_of_user(conn, follower)
  370. |> get("/api/v1/pleroma/statuses/#{activity_id}/reactions/🐈")
  371. |> json_response_and_validate_schema(200)
  372. # Fails for stranger
  373. assert prepare_conn_of_user(conn, stranger)
  374. |> get("/api/v1/pleroma/statuses/#{activity_id}/reactions/🐈")
  375. |> json_response_and_validate_schema(404) == %{"error" => "Record not found"}
  376. end
  377. end