logo

pleroma

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

emoji_policy_test.exs (13132B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicyTest do
  5. use Pleroma.DataCase
  6. require Pleroma.Constants
  7. alias Pleroma.Web.ActivityPub.MRF
  8. alias Pleroma.Web.ActivityPub.MRF.EmojiPolicy
  9. setup do: clear_config(:mrf_emoji)
  10. setup do
  11. clear_config([:mrf_emoji], %{
  12. remove_url: [],
  13. remove_shortcode: [],
  14. federated_timeline_removal_url: [],
  15. federated_timeline_removal_shortcode: []
  16. })
  17. end
  18. @emoji_tags [
  19. %{
  20. "icon" => %{
  21. "type" => "Image",
  22. "url" => "https://example.org/emoji/biribiri/mikoto_smile2.png"
  23. },
  24. "id" => "https://example.org/emoji/biribiri/mikoto_smile2.png",
  25. "name" => ":mikoto_smile2:",
  26. "type" => "Emoji",
  27. "updated" => "1970-01-01T00:00:00Z"
  28. },
  29. %{
  30. "icon" => %{
  31. "type" => "Image",
  32. "url" => "https://example.org/emoji/biribiri/mikoto_smile3.png"
  33. },
  34. "id" => "https://example.org/emoji/biribiri/mikoto_smile3.png",
  35. "name" => ":mikoto_smile3:",
  36. "type" => "Emoji",
  37. "updated" => "1970-01-01T00:00:00Z"
  38. },
  39. %{
  40. "icon" => %{
  41. "type" => "Image",
  42. "url" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
  43. },
  44. "id" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png",
  45. "name" => ":nekomimi_girl_emoji_007:",
  46. "type" => "Emoji",
  47. "updated" => "1970-01-01T00:00:00Z"
  48. },
  49. %{
  50. "icon" => %{
  51. "type" => "Image",
  52. "url" => "https://example.org/test.png"
  53. },
  54. "id" => "https://example.org/test.png",
  55. "name" => ":test:",
  56. "type" => "Emoji",
  57. "updated" => "1970-01-01T00:00:00Z"
  58. }
  59. ]
  60. @misc_tags [%{"type" => "Placeholder"}]
  61. @user_data %{
  62. "type" => "Person",
  63. "id" => "https://example.org/placeholder",
  64. "name" => "lol",
  65. "tag" => @emoji_tags ++ @misc_tags
  66. }
  67. @status_data %{
  68. "type" => "Create",
  69. "object" => %{
  70. "type" => "Note",
  71. "id" => "https://example.org/placeholder",
  72. "content" => "lol",
  73. "tag" => @emoji_tags ++ @misc_tags,
  74. "emoji" => %{
  75. "mikoto_smile2" => "https://example.org/emoji/biribiri/mikoto_smile2.png",
  76. "mikoto_smile3" => "https://example.org/emoji/biribiri/mikoto_smile3.png",
  77. "nekomimi_girl_emoji_007" =>
  78. "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png",
  79. "test" => "https://example.org/test.png"
  80. },
  81. "to" => ["https://example.org/self", Pleroma.Constants.as_public()],
  82. "cc" => ["https://example.org/someone"]
  83. },
  84. "to" => ["https://example.org/self", Pleroma.Constants.as_public()],
  85. "cc" => ["https://example.org/someone"]
  86. }
  87. @status_data_with_history %{
  88. "type" => "Create",
  89. "object" =>
  90. @status_data["object"]
  91. |> Map.merge(%{
  92. "formerRepresentations" => %{
  93. "type" => "OrderedCollection",
  94. "orderedItems" => [@status_data["object"] |> Map.put("content", "older")],
  95. "totalItems" => 1
  96. }
  97. }),
  98. "to" => ["https://example.org/self", Pleroma.Constants.as_public()],
  99. "cc" => ["https://example.org/someone"]
  100. }
  101. @emoji_react_data %{
  102. "type" => "EmojiReact",
  103. "tag" => [@emoji_tags |> Enum.at(3)],
  104. "object" => "https://example.org/someobject",
  105. "to" => ["https://example.org/self"],
  106. "cc" => ["https://example.org/someone"]
  107. }
  108. @emoji_react_data_matching_regex %{
  109. "type" => "EmojiReact",
  110. "tag" => [@emoji_tags |> Enum.at(1)],
  111. "object" => "https://example.org/someobject",
  112. "to" => ["https://example.org/self"],
  113. "cc" => ["https://example.org/someone"]
  114. }
  115. @emoji_react_data_matching_nothing %{
  116. "type" => "EmojiReact",
  117. "tag" => [@emoji_tags |> Enum.at(2)],
  118. "object" => "https://example.org/someobject",
  119. "to" => ["https://example.org/self"],
  120. "cc" => ["https://example.org/someone"]
  121. }
  122. @emoji_react_data_unicode %{
  123. "type" => "EmojiReact",
  124. "content" => "😍",
  125. "object" => "https://example.org/someobject",
  126. "to" => ["https://example.org/self"],
  127. "cc" => ["https://example.org/someone"]
  128. }
  129. describe "remove_url" do
  130. setup do
  131. clear_config([:mrf_emoji, :remove_url], [
  132. "https://example.org/test.png",
  133. ~r{/biribiri/mikoto_smile[23]\.png},
  134. "nekomimi_girl_emoji"
  135. ])
  136. :ok
  137. end
  138. test "processes user" do
  139. {:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data)
  140. expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
  141. assert %{"tag" => ^expected_tags} = filtered
  142. end
  143. test "processes status" do
  144. {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
  145. expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
  146. expected_emoji = %{
  147. "nekomimi_girl_emoji_007" =>
  148. "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
  149. }
  150. assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered
  151. end
  152. test "processes status with history" do
  153. {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history)
  154. expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
  155. expected_emoji = %{
  156. "nekomimi_girl_emoji_007" =>
  157. "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
  158. }
  159. assert %{
  160. "object" => %{
  161. "tag" => ^expected_tags,
  162. "emoji" => ^expected_emoji,
  163. "formerRepresentations" => %{"orderedItems" => [item]}
  164. }
  165. } = filtered
  166. assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
  167. end
  168. test "processes updates" do
  169. {:ok, filtered} =
  170. MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update"))
  171. expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
  172. expected_emoji = %{
  173. "nekomimi_girl_emoji_007" =>
  174. "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
  175. }
  176. assert %{
  177. "object" => %{
  178. "tag" => ^expected_tags,
  179. "emoji" => ^expected_emoji,
  180. "formerRepresentations" => %{"orderedItems" => [item]}
  181. }
  182. } = filtered
  183. assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
  184. end
  185. test "processes EmojiReact" do
  186. assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
  187. MRF.filter_one(EmojiPolicy, @emoji_react_data)
  188. assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
  189. MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex)
  190. assert {:ok, @emoji_react_data_matching_nothing} ==
  191. MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing)
  192. assert {:ok, @emoji_react_data_unicode} ==
  193. MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
  194. end
  195. end
  196. describe "remove_shortcode" do
  197. setup do
  198. clear_config([:mrf_emoji, :remove_shortcode], [
  199. "test",
  200. ~r{mikoto_s},
  201. "nekomimi_girl_emoji"
  202. ])
  203. :ok
  204. end
  205. test "processes user" do
  206. {:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data)
  207. expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
  208. assert %{"tag" => ^expected_tags} = filtered
  209. end
  210. test "processes status" do
  211. {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
  212. expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
  213. expected_emoji = %{
  214. "nekomimi_girl_emoji_007" =>
  215. "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
  216. }
  217. assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered
  218. end
  219. test "processes status with history" do
  220. {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history)
  221. expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
  222. expected_emoji = %{
  223. "nekomimi_girl_emoji_007" =>
  224. "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
  225. }
  226. assert %{
  227. "object" => %{
  228. "tag" => ^expected_tags,
  229. "emoji" => ^expected_emoji,
  230. "formerRepresentations" => %{"orderedItems" => [item]}
  231. }
  232. } = filtered
  233. assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
  234. end
  235. test "processes updates" do
  236. {:ok, filtered} =
  237. MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update"))
  238. expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
  239. expected_emoji = %{
  240. "nekomimi_girl_emoji_007" =>
  241. "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
  242. }
  243. assert %{
  244. "object" => %{
  245. "tag" => ^expected_tags,
  246. "emoji" => ^expected_emoji,
  247. "formerRepresentations" => %{"orderedItems" => [item]}
  248. }
  249. } = filtered
  250. assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
  251. end
  252. test "processes EmojiReact" do
  253. assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
  254. MRF.filter_one(EmojiPolicy, @emoji_react_data)
  255. assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
  256. MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex)
  257. assert {:ok, @emoji_react_data_matching_nothing} ==
  258. MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing)
  259. assert {:ok, @emoji_react_data_unicode} ==
  260. MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
  261. end
  262. end
  263. describe "federated_timeline_removal_url" do
  264. setup do
  265. clear_config([:mrf_emoji, :federated_timeline_removal_url], [
  266. "https://example.org/test.png",
  267. ~r{/biribiri/mikoto_smile[23]\.png},
  268. "nekomimi_girl_emoji"
  269. ])
  270. :ok
  271. end
  272. test "processes status" do
  273. {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
  274. expected_tags = @status_data["object"]["tag"]
  275. expected_emoji = @status_data["object"]["emoji"]
  276. expected_to = ["https://example.org/self"]
  277. expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"]
  278. assert %{
  279. "to" => ^expected_to,
  280. "cc" => ^expected_cc,
  281. "object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}
  282. } = filtered
  283. end
  284. test "ignore updates" do
  285. {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data |> Map.put("type", "Update"))
  286. expected_tags = @status_data["object"]["tag"]
  287. expected_emoji = @status_data["object"]["emoji"]
  288. expected_to = ["https://example.org/self", Pleroma.Constants.as_public()]
  289. expected_cc = ["https://example.org/someone"]
  290. assert %{
  291. "to" => ^expected_to,
  292. "cc" => ^expected_cc,
  293. "object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}
  294. } = filtered
  295. end
  296. test "processes status with history" do
  297. status =
  298. @status_data_with_history
  299. |> put_in(["object", "tag"], @misc_tags)
  300. |> put_in(["object", "emoji"], %{})
  301. {:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
  302. expected_tags = @status_data["object"]["tag"]
  303. expected_emoji = @status_data["object"]["emoji"]
  304. expected_to = ["https://example.org/self"]
  305. expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"]
  306. assert %{
  307. "to" => ^expected_to,
  308. "cc" => ^expected_cc,
  309. "object" => %{
  310. "formerRepresentations" => %{
  311. "orderedItems" => [%{"tag" => ^expected_tags, "emoji" => ^expected_emoji}]
  312. }
  313. }
  314. } = filtered
  315. end
  316. end
  317. describe "edge cases" do
  318. setup do
  319. clear_config([:mrf_emoji, :remove_url], [
  320. "https://example.org/test.png",
  321. ~r{/biribiri/mikoto_smile[23]\.png},
  322. "nekomimi_girl_emoji"
  323. ])
  324. :ok
  325. end
  326. test "non-statuses" do
  327. answer = @status_data |> put_in(["object", "type"], "Answer")
  328. {:ok, filtered} = MRF.filter_one(EmojiPolicy, answer)
  329. assert filtered == answer
  330. end
  331. test "without tag" do
  332. status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["tag"]))
  333. {:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
  334. refute Map.has_key?(filtered["object"], "tag")
  335. end
  336. test "without emoji" do
  337. status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["emoji"]))
  338. {:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
  339. refute Map.has_key?(filtered["object"], "emoji")
  340. end
  341. end
  342. end