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.

817 lines
29KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.StreamerTest do
  5. use Pleroma.DataCase
  6. import Pleroma.Factory
  7. alias Pleroma.Chat
  8. alias Pleroma.Chat.MessageReference
  9. alias Pleroma.Conversation.Participation
  10. alias Pleroma.List
  11. alias Pleroma.Object
  12. alias Pleroma.User
  13. alias Pleroma.Web.CommonAPI
  14. alias Pleroma.Web.Streamer
  15. alias Pleroma.Web.StreamerView
  16. @moduletag needs_streamer: true, capture_log: true
  17. setup do: clear_config([:instance, :skip_thread_containment])
  18. describe "get_topic/_ (unauthenticated)" do
  19. test "allows public" do
  20. assert {:ok, "public"} = Streamer.get_topic("public", nil, nil)
  21. assert {:ok, "public:local"} = Streamer.get_topic("public:local", nil, nil)
  22. assert {:ok, "public:media"} = Streamer.get_topic("public:media", nil, nil)
  23. assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", nil, nil)
  24. end
  25. test "allows instance streams" do
  26. assert {:ok, "public:remote:lain.com"} =
  27. Streamer.get_topic("public:remote", nil, nil, %{"instance" => "lain.com"})
  28. assert {:ok, "public:remote:media:lain.com"} =
  29. Streamer.get_topic("public:remote:media", nil, nil, %{"instance" => "lain.com"})
  30. end
  31. test "allows hashtag streams" do
  32. assert {:ok, "hashtag:cofe"} = Streamer.get_topic("hashtag", nil, nil, %{"tag" => "cofe"})
  33. end
  34. test "disallows user streams" do
  35. assert {:error, _} = Streamer.get_topic("user", nil, nil)
  36. assert {:error, _} = Streamer.get_topic("user:notification", nil, nil)
  37. assert {:error, _} = Streamer.get_topic("direct", nil, nil)
  38. end
  39. test "disallows list streams" do
  40. assert {:error, _} = Streamer.get_topic("list", nil, nil, %{"list" => 42})
  41. end
  42. end
  43. describe "get_topic/_ (authenticated)" do
  44. setup do: oauth_access(["read"])
  45. test "allows public streams (regardless of OAuth token scopes)", %{
  46. user: user,
  47. token: read_oauth_token
  48. } do
  49. with oauth_token <- [nil, read_oauth_token] do
  50. assert {:ok, "public"} = Streamer.get_topic("public", user, oauth_token)
  51. assert {:ok, "public:local"} = Streamer.get_topic("public:local", user, oauth_token)
  52. assert {:ok, "public:media"} = Streamer.get_topic("public:media", user, oauth_token)
  53. assert {:ok, "public:local:media"} =
  54. Streamer.get_topic("public:local:media", user, oauth_token)
  55. end
  56. end
  57. test "allows user streams (with proper OAuth token scopes)", %{
  58. user: user,
  59. token: read_oauth_token
  60. } do
  61. %{token: read_notifications_token} = oauth_access(["read:notifications"], user: user)
  62. %{token: read_statuses_token} = oauth_access(["read:statuses"], user: user)
  63. %{token: badly_scoped_token} = oauth_access(["irrelevant:scope"], user: user)
  64. expected_user_topic = "user:#{user.id}"
  65. expected_notification_topic = "user:notification:#{user.id}"
  66. expected_direct_topic = "direct:#{user.id}"
  67. expected_pleroma_chat_topic = "user:pleroma_chat:#{user.id}"
  68. for valid_user_token <- [read_oauth_token, read_statuses_token] do
  69. assert {:ok, ^expected_user_topic} = Streamer.get_topic("user", user, valid_user_token)
  70. assert {:ok, ^expected_direct_topic} =
  71. Streamer.get_topic("direct", user, valid_user_token)
  72. assert {:ok, ^expected_pleroma_chat_topic} =
  73. Streamer.get_topic("user:pleroma_chat", user, valid_user_token)
  74. end
  75. for invalid_user_token <- [read_notifications_token, badly_scoped_token],
  76. user_topic <- ["user", "direct", "user:pleroma_chat"] do
  77. assert {:error, :unauthorized} = Streamer.get_topic(user_topic, user, invalid_user_token)
  78. end
  79. for valid_notification_token <- [read_oauth_token, read_notifications_token] do
  80. assert {:ok, ^expected_notification_topic} =
  81. Streamer.get_topic("user:notification", user, valid_notification_token)
  82. end
  83. for invalid_notification_token <- [read_statuses_token, badly_scoped_token] do
  84. assert {:error, :unauthorized} =
  85. Streamer.get_topic("user:notification", user, invalid_notification_token)
  86. end
  87. end
  88. test "allows hashtag streams (regardless of OAuth token scopes)", %{
  89. user: user,
  90. token: read_oauth_token
  91. } do
  92. for oauth_token <- [nil, read_oauth_token] do
  93. assert {:ok, "hashtag:cofe"} =
  94. Streamer.get_topic("hashtag", user, oauth_token, %{"tag" => "cofe"})
  95. end
  96. end
  97. test "disallows registering to another user's stream", %{user: user, token: read_oauth_token} do
  98. another_user = insert(:user)
  99. assert {:error, _} = Streamer.get_topic("user:#{another_user.id}", user, read_oauth_token)
  100. assert {:error, _} =
  101. Streamer.get_topic("user:notification:#{another_user.id}", user, read_oauth_token)
  102. assert {:error, _} = Streamer.get_topic("direct:#{another_user.id}", user, read_oauth_token)
  103. end
  104. test "allows list stream that are owned by the user (with `read` or `read:lists` scopes)", %{
  105. user: user,
  106. token: read_oauth_token
  107. } do
  108. %{token: read_lists_token} = oauth_access(["read:lists"], user: user)
  109. %{token: invalid_token} = oauth_access(["irrelevant:scope"], user: user)
  110. {:ok, list} = List.create("Test", user)
  111. assert {:error, _} = Streamer.get_topic("list:#{list.id}", user, read_oauth_token)
  112. for valid_token <- [read_oauth_token, read_lists_token] do
  113. assert {:ok, _} = Streamer.get_topic("list", user, valid_token, %{"list" => list.id})
  114. end
  115. assert {:error, _} = Streamer.get_topic("list", user, invalid_token, %{"list" => list.id})
  116. end
  117. test "disallows list stream that are not owned by the user", %{user: user, token: oauth_token} do
  118. another_user = insert(:user)
  119. {:ok, list} = List.create("Test", another_user)
  120. assert {:error, _} = Streamer.get_topic("list:#{list.id}", user, oauth_token)
  121. assert {:error, _} = Streamer.get_topic("list", user, oauth_token, %{"list" => list.id})
  122. end
  123. end
  124. describe "user streams" do
  125. setup do
  126. %{user: user, token: token} = oauth_access(["read"])
  127. notify = insert(:notification, user: user, activity: build(:note_activity))
  128. {:ok, %{user: user, notify: notify, token: token}}
  129. end
  130. test "it streams the user's post in the 'user' stream", %{user: user, token: oauth_token} do
  131. Streamer.get_topic_and_add_socket("user", user, oauth_token)
  132. {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
  133. assert_receive {:render_with_user, _, _, ^activity}
  134. refute Streamer.filtered_by_user?(user, activity)
  135. end
  136. test "it streams boosts of the user in the 'user' stream", %{user: user, token: oauth_token} do
  137. Streamer.get_topic_and_add_socket("user", user, oauth_token)
  138. other_user = insert(:user)
  139. {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
  140. {:ok, announce} = CommonAPI.repeat(activity.id, user)
  141. assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
  142. refute Streamer.filtered_by_user?(user, announce)
  143. end
  144. test "it does not stream announces of the user's own posts in the 'user' stream", %{
  145. user: user,
  146. token: oauth_token
  147. } do
  148. Streamer.get_topic_and_add_socket("user", user, oauth_token)
  149. other_user = insert(:user)
  150. {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
  151. {:ok, announce} = CommonAPI.repeat(activity.id, other_user)
  152. assert Streamer.filtered_by_user?(user, announce)
  153. end
  154. test "it does stream notifications announces of the user's own posts in the 'user' stream", %{
  155. user: user,
  156. token: oauth_token
  157. } do
  158. Streamer.get_topic_and_add_socket("user", user, oauth_token)
  159. other_user = insert(:user)
  160. {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
  161. {:ok, announce} = CommonAPI.repeat(activity.id, other_user)
  162. notification =
  163. Pleroma.Notification
  164. |> Repo.get_by(%{user_id: user.id, activity_id: announce.id})
  165. |> Repo.preload(:activity)
  166. refute Streamer.filtered_by_user?(user, notification)
  167. end
  168. test "it streams boosts of mastodon user in the 'user' stream", %{
  169. user: user,
  170. token: oauth_token
  171. } do
  172. Streamer.get_topic_and_add_socket("user", user, oauth_token)
  173. other_user = insert(:user)
  174. {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
  175. data =
  176. File.read!("test/fixtures/mastodon-announce.json")
  177. |> Jason.decode!()
  178. |> Map.put("object", activity.data["object"])
  179. |> Map.put("actor", user.ap_id)
  180. {:ok, %Pleroma.Activity{data: _data, local: false} = announce} =
  181. Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming(data)
  182. assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
  183. refute Streamer.filtered_by_user?(user, announce)
  184. end
  185. test "it sends notify to in the 'user' stream", %{
  186. user: user,
  187. token: oauth_token,
  188. notify: notify
  189. } do
  190. Streamer.get_topic_and_add_socket("user", user, oauth_token)
  191. Streamer.stream("user", notify)
  192. assert_receive {:render_with_user, _, _, ^notify}
  193. refute Streamer.filtered_by_user?(user, notify)
  194. end
  195. test "it sends notify to in the 'user:notification' stream", %{
  196. user: user,
  197. token: oauth_token,
  198. notify: notify
  199. } do
  200. Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
  201. Streamer.stream("user:notification", notify)
  202. assert_receive {:render_with_user, _, _, ^notify}
  203. refute Streamer.filtered_by_user?(user, notify)
  204. end
  205. test "it sends chat messages to the 'user:pleroma_chat' stream", %{
  206. user: user,
  207. token: oauth_token
  208. } do
  209. other_user = insert(:user)
  210. {:ok, create_activity} =
  211. CommonAPI.post_chat_message(other_user, user, "hey cirno", idempotency_key: "123")
  212. object = Object.normalize(create_activity, fetch: false)
  213. chat = Chat.get(user.id, other_user.ap_id)
  214. cm_ref = MessageReference.for_chat_and_object(chat, object)
  215. cm_ref = %{cm_ref | chat: chat, object: object}
  216. Streamer.get_topic_and_add_socket("user:pleroma_chat", user, oauth_token)
  217. Streamer.stream("user:pleroma_chat", {user, cm_ref})
  218. text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
  219. assert text =~ "hey cirno"
  220. assert_receive {:text, ^text}
  221. end
  222. test "it sends chat messages to the 'user' stream", %{user: user, token: oauth_token} do
  223. other_user = insert(:user)
  224. {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno")
  225. object = Object.normalize(create_activity, fetch: false)
  226. chat = Chat.get(user.id, other_user.ap_id)
  227. cm_ref = MessageReference.for_chat_and_object(chat, object)
  228. cm_ref = %{cm_ref | chat: chat, object: object}
  229. Streamer.get_topic_and_add_socket("user", user, oauth_token)
  230. Streamer.stream("user", {user, cm_ref})
  231. text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
  232. assert text =~ "hey cirno"
  233. assert_receive {:text, ^text}
  234. end
  235. test "it sends chat message notifications to the 'user:notification' stream", %{
  236. user: user,
  237. token: oauth_token
  238. } do
  239. other_user = insert(:user)
  240. {:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey")
  241. notify =
  242. Repo.get_by(Pleroma.Notification, user_id: user.id, activity_id: create_activity.id)
  243. |> Repo.preload(:activity)
  244. Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
  245. Streamer.stream("user:notification", notify)
  246. assert_receive {:render_with_user, _, _, ^notify}
  247. refute Streamer.filtered_by_user?(user, notify)
  248. end
  249. test "it doesn't send notify to the 'user:notification' stream when a user is blocked", %{
  250. user: user,
  251. token: oauth_token
  252. } do
  253. blocked = insert(:user)
  254. {:ok, _user_relationship} = User.block(user, blocked)
  255. Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
  256. {:ok, activity} = CommonAPI.post(user, %{status: ":("})
  257. {:ok, _} = CommonAPI.favorite(blocked, activity.id)
  258. refute_receive _
  259. end
  260. test "it doesn't send notify to the 'user:notification' stream when a thread is muted", %{
  261. user: user,
  262. token: oauth_token
  263. } do
  264. user2 = insert(:user)
  265. {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
  266. {:ok, _} = CommonAPI.add_mute(user, activity)
  267. Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
  268. {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
  269. refute_receive _
  270. assert Streamer.filtered_by_user?(user, favorite_activity)
  271. end
  272. test "it sends favorite to 'user:notification' stream'", %{
  273. user: user,
  274. token: oauth_token
  275. } do
  276. user2 = insert(:user, %{ap_id: "https://hecking-lewd-place.com/user/meanie"})
  277. {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
  278. Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
  279. {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
  280. assert_receive {:render_with_user, _, "notification.json", notif}
  281. assert notif.activity.id == favorite_activity.id
  282. refute Streamer.filtered_by_user?(user, notif)
  283. end
  284. test "it doesn't send the 'user:notification' stream' when a domain is blocked", %{
  285. user: user,
  286. token: oauth_token
  287. } do
  288. user2 = insert(:user, %{ap_id: "https://hecking-lewd-place.com/user/meanie"})
  289. {:ok, user} = User.block_domain(user, "hecking-lewd-place.com")
  290. {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
  291. Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
  292. {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
  293. refute_receive _
  294. assert Streamer.filtered_by_user?(user, favorite_activity)
  295. end
  296. test "it sends follow activities to the 'user:notification' stream", %{
  297. user: user,
  298. token: oauth_token
  299. } do
  300. user2 = insert(:user)
  301. Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
  302. {:ok, _follower, _followed, follow_activity} = CommonAPI.follow(user2, user)
  303. assert_receive {:render_with_user, _, "notification.json", notif}
  304. assert notif.activity.id == follow_activity.id
  305. refute Streamer.filtered_by_user?(user, notif)
  306. end
  307. test "it sends follow relationships updates to the 'user' stream", %{
  308. user: user,
  309. token: oauth_token
  310. } do
  311. user_id = user.id
  312. other_user = insert(:user)
  313. other_user_id = other_user.id
  314. Streamer.get_topic_and_add_socket("user", user, oauth_token)
  315. {:ok, _follower, _followed, _follow_activity} = CommonAPI.follow(user, other_user)
  316. assert_receive {:text, event}
  317. assert %{"event" => "pleroma:follow_relationships_update", "payload" => payload} =
  318. Jason.decode!(event)
  319. assert %{
  320. "follower" => %{
  321. "follower_count" => 0,
  322. "following_count" => 0,
  323. "id" => ^user_id
  324. },
  325. "following" => %{
  326. "follower_count" => 0,
  327. "following_count" => 0,
  328. "id" => ^other_user_id
  329. },
  330. "state" => "follow_pending"
  331. } = Jason.decode!(payload)
  332. assert_receive {:text, event}
  333. assert %{"event" => "pleroma:follow_relationships_update", "payload" => payload} =
  334. Jason.decode!(event)
  335. assert %{
  336. "follower" => %{
  337. "follower_count" => 0,
  338. "following_count" => 1,
  339. "id" => ^user_id
  340. },
  341. "following" => %{
  342. "follower_count" => 1,
  343. "following_count" => 0,
  344. "id" => ^other_user_id
  345. },
  346. "state" => "follow_accept"
  347. } = Jason.decode!(payload)
  348. end
  349. end
  350. describe "public streams" do
  351. test "it sends to public (authenticated)" do
  352. %{user: user, token: oauth_token} = oauth_access(["read"])
  353. other_user = insert(:user)
  354. Streamer.get_topic_and_add_socket("public", user, oauth_token)
  355. {:ok, activity} = CommonAPI.post(other_user, %{status: "Test"})
  356. assert_receive {:render_with_user, _, _, ^activity}
  357. refute Streamer.filtered_by_user?(other_user, activity)
  358. end
  359. test "it sends to public (unauthenticated)" do
  360. user = insert(:user)
  361. Streamer.get_topic_and_add_socket("public", nil, nil)
  362. {:ok, activity} = CommonAPI.post(user, %{status: "Test"})
  363. activity_id = activity.id
  364. assert_receive {:text, event}
  365. assert %{"event" => "update", "payload" => payload} = Jason.decode!(event)
  366. assert %{"id" => ^activity_id} = Jason.decode!(payload)
  367. {:ok, _} = CommonAPI.delete(activity.id, user)
  368. assert_receive {:text, event}
  369. assert %{"event" => "delete", "payload" => ^activity_id} = Jason.decode!(event)
  370. end
  371. test "handles deletions" do
  372. %{user: user, token: oauth_token} = oauth_access(["read"])
  373. other_user = insert(:user)
  374. {:ok, activity} = CommonAPI.post(other_user, %{status: "Test"})
  375. Streamer.get_topic_and_add_socket("public", user, oauth_token)
  376. {:ok, _} = CommonAPI.delete(activity.id, other_user)
  377. activity_id = activity.id
  378. assert_receive {:text, event}
  379. assert %{"event" => "delete", "payload" => ^activity_id} = Jason.decode!(event)
  380. end
  381. end
  382. describe "thread_containment/2" do
  383. test "it filters to user if recipients invalid and thread containment is enabled" do
  384. clear_config([:instance, :skip_thread_containment], false)
  385. author = insert(:user)
  386. %{user: user, token: oauth_token} = oauth_access(["read"])
  387. User.follow(user, author, :follow_accept)
  388. activity =
  389. insert(:note_activity,
  390. note:
  391. insert(:note,
  392. user: author,
  393. data: %{"to" => ["TEST-FFF"]}
  394. )
  395. )
  396. Streamer.get_topic_and_add_socket("public", user, oauth_token)
  397. Streamer.stream("public", activity)
  398. assert_receive {:render_with_user, _, _, ^activity}
  399. assert Streamer.filtered_by_user?(user, activity)
  400. end
  401. test "it sends message if recipients invalid and thread containment is disabled" do
  402. clear_config([:instance, :skip_thread_containment], true)
  403. author = insert(:user)
  404. %{user: user, token: oauth_token} = oauth_access(["read"])
  405. User.follow(user, author, :follow_accept)
  406. activity =
  407. insert(:note_activity,
  408. note:
  409. insert(:note,
  410. user: author,
  411. data: %{"to" => ["TEST-FFF"]}
  412. )
  413. )
  414. Streamer.get_topic_and_add_socket("public", user, oauth_token)
  415. Streamer.stream("public", activity)
  416. assert_receive {:render_with_user, _, _, ^activity}
  417. refute Streamer.filtered_by_user?(user, activity)
  418. end
  419. test "it sends message if recipients invalid and thread containment is enabled but user's thread containment is disabled" do
  420. clear_config([:instance, :skip_thread_containment], false)
  421. author = insert(:user)
  422. user = insert(:user, skip_thread_containment: true)
  423. %{token: oauth_token} = oauth_access(["read"], user: user)
  424. User.follow(user, author, :follow_accept)
  425. activity =
  426. insert(:note_activity,
  427. note:
  428. insert(:note,
  429. user: author,
  430. data: %{"to" => ["TEST-FFF"]}
  431. )
  432. )
  433. Streamer.get_topic_and_add_socket("public", user, oauth_token)
  434. Streamer.stream("public", activity)
  435. assert_receive {:render_with_user, _, _, ^activity}
  436. refute Streamer.filtered_by_user?(user, activity)
  437. end
  438. end
  439. describe "blocks" do
  440. setup do: oauth_access(["read"])
  441. test "it filters messages involving blocked users", %{user: user, token: oauth_token} do
  442. blocked_user = insert(:user)
  443. {:ok, _user_relationship} = User.block(user, blocked_user)
  444. Streamer.get_topic_and_add_socket("public", user, oauth_token)
  445. {:ok, activity} = CommonAPI.post(blocked_user, %{status: "Test"})
  446. assert_receive {:render_with_user, _, _, ^activity}
  447. assert Streamer.filtered_by_user?(user, activity)
  448. end
  449. test "it filters messages transitively involving blocked users", %{
  450. user: blocker,
  451. token: blocker_token
  452. } do
  453. blockee = insert(:user)
  454. friend = insert(:user)
  455. Streamer.get_topic_and_add_socket("public", blocker, blocker_token)
  456. {:ok, _user_relationship} = User.block(blocker, blockee)
  457. {:ok, activity_one} = CommonAPI.post(friend, %{status: "hey! @#{blockee.nickname}"})
  458. assert_receive {:render_with_user, _, _, ^activity_one}
  459. assert Streamer.filtered_by_user?(blocker, activity_one)
  460. {:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
  461. assert_receive {:render_with_user, _, _, ^activity_two}
  462. assert Streamer.filtered_by_user?(blocker, activity_two)
  463. {:ok, activity_three} = CommonAPI.post(blockee, %{status: "hey! @#{blocker.nickname}"})
  464. assert_receive {:render_with_user, _, _, ^activity_three}
  465. assert Streamer.filtered_by_user?(blocker, activity_three)
  466. end
  467. end
  468. describe "lists" do
  469. setup do: oauth_access(["read"])
  470. test "it doesn't send unwanted DMs to list", %{user: user_a, token: user_a_token} do
  471. user_b = insert(:user)
  472. user_c = insert(:user)
  473. {:ok, user_a, user_b} = User.follow(user_a, user_b)
  474. {:ok, list} = List.create("Test", user_a)
  475. {:ok, list} = List.follow(list, user_b)
  476. Streamer.get_topic_and_add_socket("list", user_a, user_a_token, %{"list" => list.id})
  477. {:ok, _activity} =
  478. CommonAPI.post(user_b, %{
  479. status: "@#{user_c.nickname} Test",
  480. visibility: "direct"
  481. })
  482. refute_receive _
  483. end
  484. test "it doesn't send unwanted private posts to list", %{user: user_a, token: user_a_token} do
  485. user_b = insert(:user)
  486. {:ok, list} = List.create("Test", user_a)
  487. {:ok, list} = List.follow(list, user_b)
  488. Streamer.get_topic_and_add_socket("list", user_a, user_a_token, %{"list" => list.id})
  489. {:ok, _activity} =
  490. CommonAPI.post(user_b, %{
  491. status: "Test",
  492. visibility: "private"
  493. })
  494. refute_receive _
  495. end
  496. test "it sends wanted private posts to list", %{user: user_a, token: user_a_token} do
  497. user_b = insert(:user)
  498. {:ok, user_a, user_b} = User.follow(user_a, user_b)
  499. {:ok, list} = List.create("Test", user_a)
  500. {:ok, list} = List.follow(list, user_b)
  501. Streamer.get_topic_and_add_socket("list", user_a, user_a_token, %{"list" => list.id})
  502. {:ok, activity} =
  503. CommonAPI.post(user_b, %{
  504. status: "Test",
  505. visibility: "private"
  506. })
  507. assert_receive {:render_with_user, _, _, ^activity}
  508. refute Streamer.filtered_by_user?(user_a, activity)
  509. end
  510. end
  511. describe "muted reblogs" do
  512. setup do: oauth_access(["read"])
  513. test "it filters muted reblogs", %{user: user1, token: user1_token} do
  514. user2 = insert(:user)
  515. user3 = insert(:user)
  516. CommonAPI.follow(user1, user2)
  517. CommonAPI.hide_reblogs(user1, user2)
  518. {:ok, create_activity} = CommonAPI.post(user3, %{status: "I'm kawen"})
  519. Streamer.get_topic_and_add_socket("user", user1, user1_token)
  520. {:ok, announce_activity} = CommonAPI.repeat(create_activity.id, user2)
  521. assert_receive {:render_with_user, _, _, ^announce_activity}
  522. assert Streamer.filtered_by_user?(user1, announce_activity)
  523. end
  524. test "it filters reblog notification for reblog-muted actors", %{
  525. user: user1,
  526. token: user1_token
  527. } do
  528. user2 = insert(:user)
  529. CommonAPI.follow(user1, user2)
  530. CommonAPI.hide_reblogs(user1, user2)
  531. {:ok, create_activity} = CommonAPI.post(user1, %{status: "I'm kawen"})
  532. Streamer.get_topic_and_add_socket("user", user1, user1_token)
  533. {:ok, _announce_activity} = CommonAPI.repeat(create_activity.id, user2)
  534. assert_receive {:render_with_user, _, "notification.json", notif}
  535. assert Streamer.filtered_by_user?(user1, notif)
  536. end
  537. test "it send non-reblog notification for reblog-muted actors", %{
  538. user: user1,
  539. token: user1_token
  540. } do
  541. user2 = insert(:user)
  542. CommonAPI.follow(user1, user2)
  543. CommonAPI.hide_reblogs(user1, user2)
  544. {:ok, create_activity} = CommonAPI.post(user1, %{status: "I'm kawen"})
  545. Streamer.get_topic_and_add_socket("user", user1, user1_token)
  546. {:ok, _favorite_activity} = CommonAPI.favorite(user2, create_activity.id)
  547. assert_receive {:render_with_user, _, "notification.json", notif}
  548. refute Streamer.filtered_by_user?(user1, notif)
  549. end
  550. end
  551. describe "muted threads" do
  552. test "it filters posts from muted threads" do
  553. user = insert(:user)
  554. %{user: user2, token: user2_token} = oauth_access(["read"])
  555. Streamer.get_topic_and_add_socket("user", user2, user2_token)
  556. {:ok, user2, user, _activity} = CommonAPI.follow(user2, user)
  557. {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
  558. {:ok, _} = CommonAPI.add_mute(user2, activity)
  559. assert_receive {:render_with_user, _, _, ^activity}
  560. assert Streamer.filtered_by_user?(user2, activity)
  561. end
  562. end
  563. describe "direct streams" do
  564. setup do: oauth_access(["read"])
  565. test "it sends conversation update to the 'direct' stream", %{user: user, token: oauth_token} do
  566. another_user = insert(:user)
  567. Streamer.get_topic_and_add_socket("direct", user, oauth_token)
  568. {:ok, _create_activity} =
  569. CommonAPI.post(another_user, %{
  570. status: "hey @#{user.nickname}",
  571. visibility: "direct"
  572. })
  573. assert_receive {:text, received_event}
  574. assert %{"event" => "conversation", "payload" => received_payload} =
  575. Jason.decode!(received_event)
  576. assert %{"last_status" => last_status} = Jason.decode!(received_payload)
  577. [participation] = Participation.for_user(user)
  578. assert last_status["pleroma"]["direct_conversation_id"] == participation.id
  579. end
  580. test "it doesn't send conversation update to the 'direct' stream when the last message in the conversation is deleted",
  581. %{user: user, token: oauth_token} do
  582. another_user = insert(:user)
  583. Streamer.get_topic_and_add_socket("direct", user, oauth_token)
  584. {:ok, create_activity} =
  585. CommonAPI.post(another_user, %{
  586. status: "hi @#{user.nickname}",
  587. visibility: "direct"
  588. })
  589. create_activity_id = create_activity.id
  590. assert_receive {:render_with_user, _, _, ^create_activity}
  591. assert_receive {:text, received_conversation1}
  592. assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
  593. {:ok, _} = CommonAPI.delete(create_activity_id, another_user)
  594. assert_receive {:text, received_event}
  595. assert %{"event" => "delete", "payload" => ^create_activity_id} =
  596. Jason.decode!(received_event)
  597. refute_receive _
  598. end
  599. test "it sends conversation update to the 'direct' stream when a message is deleted", %{
  600. user: user,
  601. token: oauth_token
  602. } do
  603. another_user = insert(:user)
  604. Streamer.get_topic_and_add_socket("direct", user, oauth_token)
  605. {:ok, create_activity} =
  606. CommonAPI.post(another_user, %{
  607. status: "hi @#{user.nickname}",
  608. visibility: "direct"
  609. })
  610. {:ok, create_activity2} =
  611. CommonAPI.post(another_user, %{
  612. status: "hi @#{user.nickname} 2",
  613. in_reply_to_status_id: create_activity.id,
  614. visibility: "direct"
  615. })
  616. assert_receive {:render_with_user, _, _, ^create_activity}
  617. assert_receive {:render_with_user, _, _, ^create_activity2}
  618. assert_receive {:text, received_conversation1}
  619. assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
  620. assert_receive {:text, received_conversation1}
  621. assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
  622. {:ok, _} = CommonAPI.delete(create_activity2.id, another_user)
  623. assert_receive {:text, received_event}
  624. assert %{"event" => "delete", "payload" => _} = Jason.decode!(received_event)
  625. assert_receive {:text, received_event}
  626. assert %{"event" => "conversation", "payload" => received_payload} =
  627. Jason.decode!(received_event)
  628. assert %{"last_status" => last_status} = Jason.decode!(received_payload)
  629. assert last_status["id"] == to_string(create_activity.id)
  630. end
  631. end
  632. end