Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

378 lines
12KB

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