Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

416 wiersze
13KB

  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.NotificationTest do
  5. use Pleroma.DataCase
  6. alias Pleroma.Web.TwitterAPI.TwitterAPI
  7. alias Pleroma.Web.CommonAPI
  8. alias Pleroma.User
  9. alias Pleroma.Notification
  10. alias Pleroma.Web.ActivityPub.Transmogrifier
  11. import Pleroma.Factory
  12. describe "create_notifications" do
  13. test "notifies someone when they are directly addressed" do
  14. user = insert(:user)
  15. other_user = insert(:user)
  16. third_user = insert(:user)
  17. {:ok, activity} =
  18. TwitterAPI.create_status(user, %{
  19. "status" => "hey @#{other_user.nickname} and @#{third_user.nickname}"
  20. })
  21. {:ok, [notification, other_notification]} = Notification.create_notifications(activity)
  22. notified_ids = Enum.sort([notification.user_id, other_notification.user_id])
  23. assert notified_ids == [other_user.id, third_user.id]
  24. assert notification.activity_id == activity.id
  25. assert other_notification.activity_id == activity.id
  26. end
  27. end
  28. describe "create_notification" do
  29. test "it doesn't create a notification for user if the user blocks the activity author" do
  30. activity = insert(:note_activity)
  31. author = User.get_by_ap_id(activity.data["actor"])
  32. user = insert(:user)
  33. {:ok, user} = User.block(user, author)
  34. assert nil == Notification.create_notification(activity, user)
  35. end
  36. test "it doesn't create a notification for user if he is the activity author" do
  37. activity = insert(:note_activity)
  38. author = User.get_by_ap_id(activity.data["actor"])
  39. assert nil == Notification.create_notification(activity, author)
  40. end
  41. test "it doesn't create a notification for follow-unfollow-follow chains" do
  42. user = insert(:user)
  43. followed_user = insert(:user)
  44. {:ok, _, _, activity} = TwitterAPI.follow(user, %{"user_id" => followed_user.id})
  45. Notification.create_notification(activity, followed_user)
  46. TwitterAPI.unfollow(user, %{"user_id" => followed_user.id})
  47. {:ok, _, _, activity_dupe} = TwitterAPI.follow(user, %{"user_id" => followed_user.id})
  48. assert nil == Notification.create_notification(activity_dupe, followed_user)
  49. end
  50. test "it doesn't create a notification for like-unlike-like chains" do
  51. user = insert(:user)
  52. liked_user = insert(:user)
  53. {:ok, status} = TwitterAPI.create_status(liked_user, %{"status" => "Yui is best yuru"})
  54. {:ok, fav_status} = TwitterAPI.fav(user, status.id)
  55. Notification.create_notification(fav_status, liked_user)
  56. TwitterAPI.unfav(user, status.id)
  57. {:ok, dupe} = TwitterAPI.fav(user, status.id)
  58. assert nil == Notification.create_notification(dupe, liked_user)
  59. end
  60. test "it doesn't create a notification for repeat-unrepeat-repeat chains" do
  61. user = insert(:user)
  62. retweeted_user = insert(:user)
  63. {:ok, status} =
  64. TwitterAPI.create_status(retweeted_user, %{
  65. "status" => "Send dupe notifications to the shadow realm"
  66. })
  67. {:ok, retweeted_activity} = TwitterAPI.repeat(user, status.id)
  68. Notification.create_notification(retweeted_activity, retweeted_user)
  69. TwitterAPI.unrepeat(user, status.id)
  70. {:ok, dupe} = TwitterAPI.repeat(user, status.id)
  71. assert nil == Notification.create_notification(dupe, retweeted_user)
  72. end
  73. end
  74. describe "get notification" do
  75. test "it gets a notification that belongs to the user" do
  76. user = insert(:user)
  77. other_user = insert(:user)
  78. {:ok, activity} =
  79. TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
  80. {:ok, [notification]} = Notification.create_notifications(activity)
  81. {:ok, notification} = Notification.get(other_user, notification.id)
  82. assert notification.user_id == other_user.id
  83. end
  84. test "it returns error if the notification doesn't belong to the user" do
  85. user = insert(:user)
  86. other_user = insert(:user)
  87. {:ok, activity} =
  88. TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
  89. {:ok, [notification]} = Notification.create_notifications(activity)
  90. {:error, _notification} = Notification.get(user, notification.id)
  91. end
  92. end
  93. describe "dismiss notification" do
  94. test "it dismisses a notification that belongs to the user" do
  95. user = insert(:user)
  96. other_user = insert(:user)
  97. {:ok, activity} =
  98. TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
  99. {:ok, [notification]} = Notification.create_notifications(activity)
  100. {:ok, notification} = Notification.dismiss(other_user, notification.id)
  101. assert notification.user_id == other_user.id
  102. end
  103. test "it returns error if the notification doesn't belong to the user" do
  104. user = insert(:user)
  105. other_user = insert(:user)
  106. {:ok, activity} =
  107. TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
  108. {:ok, [notification]} = Notification.create_notifications(activity)
  109. {:error, _notification} = Notification.dismiss(user, notification.id)
  110. end
  111. end
  112. describe "clear notification" do
  113. test "it clears all notifications belonging to the user" do
  114. user = insert(:user)
  115. other_user = insert(:user)
  116. third_user = insert(:user)
  117. {:ok, activity} =
  118. TwitterAPI.create_status(user, %{
  119. "status" => "hey @#{other_user.nickname} and @#{third_user.nickname} !"
  120. })
  121. {:ok, _notifs} = Notification.create_notifications(activity)
  122. {:ok, activity} =
  123. TwitterAPI.create_status(user, %{
  124. "status" => "hey again @#{other_user.nickname} and @#{third_user.nickname} !"
  125. })
  126. {:ok, _notifs} = Notification.create_notifications(activity)
  127. Notification.clear(other_user)
  128. assert Notification.for_user(other_user) == []
  129. assert Notification.for_user(third_user) != []
  130. end
  131. end
  132. describe "set_read_up_to()" do
  133. test "it sets all notifications as read up to a specified notification ID" do
  134. user = insert(:user)
  135. other_user = insert(:user)
  136. {:ok, _activity} =
  137. TwitterAPI.create_status(user, %{
  138. "status" => "hey @#{other_user.nickname}!"
  139. })
  140. {:ok, _activity} =
  141. TwitterAPI.create_status(user, %{
  142. "status" => "hey again @#{other_user.nickname}!"
  143. })
  144. [n2, n1] = notifs = Notification.for_user(other_user)
  145. assert length(notifs) == 2
  146. assert n2.id > n1.id
  147. {:ok, _activity} =
  148. TwitterAPI.create_status(user, %{
  149. "status" => "hey yet again @#{other_user.nickname}!"
  150. })
  151. Notification.set_read_up_to(other_user, n2.id)
  152. [n3, n2, n1] = Notification.for_user(other_user)
  153. assert n1.seen == true
  154. assert n2.seen == true
  155. assert n3.seen == false
  156. end
  157. end
  158. describe "notification target determination" do
  159. test "it sends notifications to addressed users in new messages" do
  160. user = insert(:user)
  161. other_user = insert(:user)
  162. {:ok, activity} =
  163. CommonAPI.post(user, %{
  164. "status" => "hey @#{other_user.nickname}!"
  165. })
  166. assert other_user in Notification.get_notified_from_activity(activity)
  167. end
  168. test "it sends notifications to mentioned users in new messages" do
  169. user = insert(:user)
  170. other_user = insert(:user)
  171. create_activity = %{
  172. "@context" => "https://www.w3.org/ns/activitystreams",
  173. "type" => "Create",
  174. "to" => ["https://www.w3.org/ns/activitystreams#Public"],
  175. "actor" => user.ap_id,
  176. "object" => %{
  177. "type" => "Note",
  178. "content" => "message with a Mention tag, but no explicit tagging",
  179. "tag" => [
  180. %{
  181. "type" => "Mention",
  182. "href" => other_user.ap_id,
  183. "name" => other_user.nickname
  184. }
  185. ],
  186. "attributedTo" => user.ap_id
  187. }
  188. }
  189. {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
  190. assert other_user in Notification.get_notified_from_activity(activity)
  191. end
  192. test "it does not send notifications to users who are only cc in new messages" do
  193. user = insert(:user)
  194. other_user = insert(:user)
  195. create_activity = %{
  196. "@context" => "https://www.w3.org/ns/activitystreams",
  197. "type" => "Create",
  198. "to" => ["https://www.w3.org/ns/activitystreams#Public"],
  199. "cc" => [other_user.ap_id],
  200. "actor" => user.ap_id,
  201. "object" => %{
  202. "type" => "Note",
  203. "content" => "hi everyone",
  204. "attributedTo" => user.ap_id
  205. }
  206. }
  207. {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
  208. assert other_user not in Notification.get_notified_from_activity(activity)
  209. end
  210. test "it does not send notification to mentioned users in likes" do
  211. user = insert(:user)
  212. other_user = insert(:user)
  213. third_user = insert(:user)
  214. {:ok, activity_one} =
  215. CommonAPI.post(user, %{
  216. "status" => "hey @#{other_user.nickname}!"
  217. })
  218. {:ok, activity_two, _} = CommonAPI.favorite(activity_one.id, third_user)
  219. assert other_user not in Notification.get_notified_from_activity(activity_two)
  220. end
  221. test "it does not send notification to mentioned users in announces" do
  222. user = insert(:user)
  223. other_user = insert(:user)
  224. third_user = insert(:user)
  225. {:ok, activity_one} =
  226. CommonAPI.post(user, %{
  227. "status" => "hey @#{other_user.nickname}!"
  228. })
  229. {:ok, activity_two, _} = CommonAPI.repeat(activity_one.id, third_user)
  230. assert other_user not in Notification.get_notified_from_activity(activity_two)
  231. end
  232. end
  233. describe "notification lifecycle" do
  234. test "liking an activity results in 1 notification, then 0 if the activity is deleted" do
  235. user = insert(:user)
  236. other_user = insert(:user)
  237. {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
  238. assert Enum.empty?(Notification.for_user(user))
  239. {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
  240. assert length(Notification.for_user(user)) == 1
  241. {:ok, _} = CommonAPI.delete(activity.id, user)
  242. assert Enum.empty?(Notification.for_user(user))
  243. end
  244. test "liking an activity results in 1 notification, then 0 if the activity is unliked" do
  245. user = insert(:user)
  246. other_user = insert(:user)
  247. {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
  248. assert Enum.empty?(Notification.for_user(user))
  249. {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
  250. assert length(Notification.for_user(user)) == 1
  251. {:ok, _, _, _} = CommonAPI.unfavorite(activity.id, other_user)
  252. assert Enum.empty?(Notification.for_user(user))
  253. end
  254. test "repeating an activity results in 1 notification, then 0 if the activity is deleted" do
  255. user = insert(:user)
  256. other_user = insert(:user)
  257. {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
  258. assert Enum.empty?(Notification.for_user(user))
  259. {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
  260. assert length(Notification.for_user(user)) == 1
  261. {:ok, _} = CommonAPI.delete(activity.id, user)
  262. assert Enum.empty?(Notification.for_user(user))
  263. end
  264. test "repeating an activity results in 1 notification, then 0 if the activity is unrepeated" do
  265. user = insert(:user)
  266. other_user = insert(:user)
  267. {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
  268. assert Enum.empty?(Notification.for_user(user))
  269. {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
  270. assert length(Notification.for_user(user)) == 1
  271. {:ok, _, _} = CommonAPI.unrepeat(activity.id, other_user)
  272. assert Enum.empty?(Notification.for_user(user))
  273. end
  274. test "liking an activity which is already deleted does not generate a notification" do
  275. user = insert(:user)
  276. other_user = insert(:user)
  277. {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
  278. assert Enum.empty?(Notification.for_user(user))
  279. {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
  280. assert Enum.empty?(Notification.for_user(user))
  281. {:error, _} = CommonAPI.favorite(activity.id, other_user)
  282. assert Enum.empty?(Notification.for_user(user))
  283. end
  284. test "repeating an activity which is already deleted does not generate a notification" do
  285. user = insert(:user)
  286. other_user = insert(:user)
  287. {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
  288. assert Enum.empty?(Notification.for_user(user))
  289. {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
  290. assert Enum.empty?(Notification.for_user(user))
  291. {:error, _} = CommonAPI.repeat(activity.id, other_user)
  292. assert Enum.empty?(Notification.for_user(user))
  293. end
  294. test "replying to a deleted post without tagging does not generate a notification" do
  295. user = insert(:user)
  296. other_user = insert(:user)
  297. {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
  298. {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
  299. {:ok, _reply_activity} =
  300. CommonAPI.post(other_user, %{
  301. "status" => "test reply",
  302. "in_reply_to_status_id" => activity.id
  303. })
  304. assert Enum.empty?(Notification.for_user(user))
  305. end
  306. end
  307. end