logo

pleroma

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

force_mentions_in_content_test.exs (10572B)


  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.ActivityPub.MRF.ForceMentionsInContentTest do
  5. use Pleroma.DataCase
  6. require Pleroma.Constants
  7. alias Pleroma.Constants
  8. alias Pleroma.Object
  9. alias Pleroma.Web.ActivityPub.MRF
  10. alias Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent
  11. alias Pleroma.Web.CommonAPI
  12. import Pleroma.Factory
  13. test "adds mentions to post content" do
  14. [lain, coolboymew, dielan, hakui, fence] = [
  15. insert(:user, ap_id: "https://lain.com/users/lain", nickname: "lain@lain.com", local: false),
  16. insert(:user,
  17. ap_id: "https://shitposter.club/users/coolboymew",
  18. nickname: "coolboymew@shitposter.club",
  19. local: false
  20. ),
  21. insert(:user,
  22. ap_id: "https://shitposter.club/users/dielan",
  23. nickname: "dielan@shitposter.club",
  24. local: false
  25. ),
  26. insert(:user,
  27. ap_id: "https://tuusin.misono-ya.info/users/hakui",
  28. nickname: "hakui@tuusin.misono-ya.info",
  29. local: false
  30. ),
  31. insert(:user,
  32. ap_id: "https://xyzzy.link/users/fence",
  33. nickname: "fence@xyzzy.link",
  34. local: false
  35. )
  36. ]
  37. object = File.read!("test/fixtures/soapbox_no_mentions_in_content.json") |> Jason.decode!()
  38. activity = %{
  39. "type" => "Create",
  40. "actor" => "https://gleasonator.com/users/alex",
  41. "object" => object
  42. }
  43. {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
  44. assert filtered ==
  45. "<p><span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{dielan.id}\" href=\"https://shitposter.club/users/dielan\" rel=\"ugc\">@<span>dielan</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{coolboymew.id}\" href=\"https://shitposter.club/users/coolboymew\" rel=\"ugc\">@<span>coolboymew</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{fence.id}\" href=\"https://xyzzy.link/users/fence\" rel=\"ugc\">@<span>fence</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{hakui.id}\" href=\"https://tuusin.misono-ya.info/users/hakui\" rel=\"ugc\">@<span>hakui</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{lain.id}\" href=\"https://lain.com/users/lain\" rel=\"ugc\">@<span>lain</span></a></span> </span>Haha yeah, you can control who you reply to.</p>"
  46. end
  47. test "the replied-to user is sorted to the left" do
  48. [mario, luigi, wario] = [
  49. insert(:user, nickname: "mario"),
  50. insert(:user, nickname: "luigi"),
  51. insert(:user, nickname: "wario")
  52. ]
  53. {:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"})
  54. {:ok, post2} =
  55. CommonAPI.post(luigi, %{status: "Oh yaah", in_reply_to_id: post1.id, to: [mario.ap_id]})
  56. activity = %{
  57. "type" => "Create",
  58. "actor" => wario.ap_id,
  59. "object" => %{
  60. "type" => "Note",
  61. "actor" => wario.ap_id,
  62. "content" => "WHA-HA!",
  63. "to" => [
  64. mario.ap_id,
  65. luigi.ap_id,
  66. Constants.as_public()
  67. ],
  68. "inReplyTo" => Object.normalize(post2).data["id"]
  69. }
  70. }
  71. {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
  72. assert filtered ==
  73. "<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{luigi.id}\" href=\"#{luigi.ap_id}\" rel=\"ugc\">@<span>luigi</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{mario.id}\" href=\"#{mario.ap_id}\" rel=\"ugc\">@<span>mario</span></a></span> </span>WHA-HA!"
  74. end
  75. test "don't mention self" do
  76. mario = insert(:user, nickname: "mario")
  77. {:ok, post} = CommonAPI.post(mario, %{status: "Mama mia"})
  78. activity = %{
  79. "type" => "Create",
  80. "actor" => mario.ap_id,
  81. "object" => %{
  82. "type" => "Note",
  83. "actor" => mario.ap_id,
  84. "content" => "I'ma tired...",
  85. "to" => [
  86. mario.ap_id,
  87. Constants.as_public()
  88. ],
  89. "inReplyTo" => Object.normalize(post).data["id"]
  90. }
  91. }
  92. {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
  93. assert filtered == "I'ma tired..."
  94. end
  95. test "don't mention in top-level posts" do
  96. mario = insert(:user, nickname: "mario")
  97. luigi = insert(:user, nickname: "luigi")
  98. {:ok, post} = CommonAPI.post(mario, %{status: "Letsa go"})
  99. activity = %{
  100. "type" => "Create",
  101. "actor" => mario.ap_id,
  102. "object" => %{
  103. "type" => "Note",
  104. "actor" => mario.ap_id,
  105. "content" => "Mama mia!",
  106. "to" => [
  107. luigi.ap_id,
  108. Constants.as_public()
  109. ],
  110. "quoteUrl" => Object.normalize(post).data["id"]
  111. }
  112. }
  113. {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
  114. assert filtered == "Mama mia!"
  115. end
  116. test "with markdown formatting" do
  117. mario = insert(:user, nickname: "mario")
  118. luigi = insert(:user, nickname: "luigi")
  119. {:ok, post} = CommonAPI.post(luigi, %{status: "Mama mia"})
  120. activity = %{
  121. "type" => "Create",
  122. "actor" => mario.ap_id,
  123. "object" => %{
  124. "type" => "Note",
  125. "actor" => mario.ap_id,
  126. "content" => "<p>I'ma tired...</p>",
  127. "to" => [
  128. luigi.ap_id,
  129. Constants.as_public()
  130. ],
  131. "inReplyTo" => Object.normalize(post).data["id"]
  132. }
  133. }
  134. {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
  135. assert filtered ==
  136. "<p><span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{luigi.id}\" href=\"#{luigi.ap_id}\" rel=\"ugc\">@<span>luigi</span></a></span> </span>I'ma tired...</p>"
  137. end
  138. test "aware of history" do
  139. mario = insert(:user, nickname: "mario")
  140. wario = insert(:user, nickname: "wario")
  141. {:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"})
  142. activity = %{
  143. "type" => "Create",
  144. "actor" => wario.ap_id,
  145. "object" => %{
  146. "type" => "Note",
  147. "actor" => wario.ap_id,
  148. "content" => "WHA-HA!",
  149. "to" => [
  150. mario.ap_id,
  151. Constants.as_public()
  152. ],
  153. "inReplyTo" => post1.object.data["id"],
  154. "formerRepresentations" => %{
  155. "orderedItems" => [
  156. %{
  157. "type" => "Note",
  158. "actor" => wario.ap_id,
  159. "content" => "WHA-HA!",
  160. "to" => [
  161. mario.ap_id,
  162. Constants.as_public()
  163. ],
  164. "inReplyTo" => post1.object.data["id"]
  165. }
  166. ]
  167. }
  168. }
  169. }
  170. expected =
  171. "<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{mario.id}\" href=\"#{mario.ap_id}\" rel=\"ugc\">@<span>mario</span></a></span> </span>WHA-HA!"
  172. assert {:ok,
  173. %{
  174. "object" => %{
  175. "content" => ^expected,
  176. "formerRepresentations" => %{"orderedItems" => [%{"content" => ^expected}]}
  177. }
  178. }} = MRF.filter_one(ForceMentionsInContent, activity)
  179. end
  180. test "works with Updates" do
  181. mario = insert(:user, nickname: "mario")
  182. wario = insert(:user, nickname: "wario")
  183. {:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"})
  184. activity = %{
  185. "type" => "Update",
  186. "actor" => wario.ap_id,
  187. "object" => %{
  188. "type" => "Note",
  189. "actor" => wario.ap_id,
  190. "content" => "WHA-HA!",
  191. "to" => [
  192. mario.ap_id,
  193. Constants.as_public()
  194. ],
  195. "inReplyTo" => post1.object.data["id"],
  196. "formerRepresentations" => %{
  197. "orderedItems" => [
  198. %{
  199. "type" => "Note",
  200. "actor" => wario.ap_id,
  201. "content" => "WHA-HA!",
  202. "to" => [
  203. mario.ap_id,
  204. Constants.as_public()
  205. ],
  206. "inReplyTo" => post1.object.data["id"]
  207. }
  208. ]
  209. }
  210. }
  211. }
  212. expected =
  213. "<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{mario.id}\" href=\"#{mario.ap_id}\" rel=\"ugc\">@<span>mario</span></a></span> </span>WHA-HA!"
  214. assert {:ok,
  215. %{
  216. "object" => %{
  217. "content" => ^expected,
  218. "formerRepresentations" => %{"orderedItems" => [%{"content" => ^expected}]}
  219. }
  220. }} = MRF.filter_one(ForceMentionsInContent, activity)
  221. end
  222. test "don't add duplicate mentions for mastodon or misskey posts" do
  223. [zero, rogerick, greg] = [
  224. insert(:user,
  225. ap_id: "https://pleroma.example.com/users/zero",
  226. uri: "https://pleroma.example.com/users/zero",
  227. nickname: "zero@pleroma.example.com",
  228. local: false
  229. ),
  230. insert(:user,
  231. ap_id: "https://misskey.example.com/users/104ab42f11",
  232. uri: "https://misskey.example.com/@rogerick",
  233. nickname: "rogerick@misskey.example.com",
  234. local: false
  235. ),
  236. insert(:user,
  237. ap_id: "https://mastodon.example.com/users/greg",
  238. uri: "https://mastodon.example.com/@greg",
  239. nickname: "greg@mastodon.example.com",
  240. local: false
  241. )
  242. ]
  243. {:ok, post} = CommonAPI.post(rogerick, %{status: "eugh"})
  244. inline_mentions = [
  245. "<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{rogerick.id}\" href=\"#{rogerick.ap_id}\" rel=\"ugc\">@<span>rogerick</span></a></span>",
  246. "<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{greg.id}\" href=\"#{greg.uri}\" rel=\"ugc\">@<span>greg</span></a></span>"
  247. ]
  248. activity = %{
  249. "type" => "Create",
  250. "actor" => zero.ap_id,
  251. "object" => %{
  252. "type" => "Note",
  253. "actor" => zero.ap_id,
  254. "content" => "#{Enum.at(inline_mentions, 0)} #{Enum.at(inline_mentions, 1)} erm",
  255. "to" => [
  256. rogerick.ap_id,
  257. greg.ap_id,
  258. Constants.as_public()
  259. ],
  260. "inReplyTo" => Object.normalize(post).data["id"]
  261. }
  262. }
  263. {:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
  264. assert filtered ==
  265. "#{Enum.at(inline_mentions, 0)} #{Enum.at(inline_mentions, 1)} erm"
  266. end
  267. end