logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma

follow_handling_test.exs (6891B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
  5. use Pleroma.DataCase
  6. alias Pleroma.Activity
  7. alias Pleroma.Notification
  8. alias Pleroma.Repo
  9. alias Pleroma.User
  10. alias Pleroma.Web.ActivityPub.Transmogrifier
  11. alias Pleroma.Web.ActivityPub.Utils
  12. import Pleroma.Factory
  13. import Ecto.Query
  14. import Mock
  15. setup_all do
  16. Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
  17. :ok
  18. end
  19. describe "handle_incoming" do
  20. setup do: clear_config([:user, :deny_follow_blocked])
  21. test "it works for osada follow request" do
  22. user = insert(:user)
  23. data =
  24. File.read!("test/fixtures/osada-follow-activity.json")
  25. |> Poison.decode!()
  26. |> Map.put("object", user.ap_id)
  27. {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
  28. assert data["actor"] == "https://apfed.club/channel/indio"
  29. assert data["type"] == "Follow"
  30. assert data["id"] == "https://apfed.club/follow/9"
  31. activity = Repo.get(Activity, activity.id)
  32. assert activity.data["state"] == "accept"
  33. assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
  34. end
  35. test "it works for incoming follow requests" do
  36. user = insert(:user)
  37. data =
  38. File.read!("test/fixtures/mastodon-follow-activity.json")
  39. |> Poison.decode!()
  40. |> Map.put("object", user.ap_id)
  41. {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
  42. assert data["actor"] == "http://mastodon.example.org/users/admin"
  43. assert data["type"] == "Follow"
  44. assert data["id"] == "http://mastodon.example.org/users/admin#follows/2"
  45. activity = Repo.get(Activity, activity.id)
  46. assert activity.data["state"] == "accept"
  47. assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
  48. [notification] = Notification.for_user(user)
  49. assert notification.type == "follow"
  50. end
  51. test "with locked accounts, it does create a Follow, but not an Accept" do
  52. user = insert(:user, locked: true)
  53. data =
  54. File.read!("test/fixtures/mastodon-follow-activity.json")
  55. |> Poison.decode!()
  56. |> Map.put("object", user.ap_id)
  57. {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
  58. assert data["state"] == "pending"
  59. refute User.following?(User.get_cached_by_ap_id(data["actor"]), user)
  60. accepts =
  61. from(
  62. a in Activity,
  63. where: fragment("?->>'type' = ?", a.data, "Accept")
  64. )
  65. |> Repo.all()
  66. assert Enum.empty?(accepts)
  67. [notification] = Notification.for_user(user)
  68. assert notification.type == "follow_request"
  69. end
  70. test "it works for follow requests when you are already followed, creating a new accept activity" do
  71. # This is important because the remote might have the wrong idea about the
  72. # current follow status. This can lead to instance A thinking that x@A is
  73. # followed by y@B, but B thinks they are not. In this case, the follow can
  74. # never go through again because it will never get an Accept.
  75. user = insert(:user)
  76. data =
  77. File.read!("test/fixtures/mastodon-follow-activity.json")
  78. |> Poison.decode!()
  79. |> Map.put("object", user.ap_id)
  80. {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
  81. accepts =
  82. from(
  83. a in Activity,
  84. where: fragment("?->>'type' = ?", a.data, "Accept")
  85. )
  86. |> Repo.all()
  87. assert length(accepts) == 1
  88. data =
  89. File.read!("test/fixtures/mastodon-follow-activity.json")
  90. |> Poison.decode!()
  91. |> Map.put("id", String.replace(data["id"], "2", "3"))
  92. |> Map.put("object", user.ap_id)
  93. {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
  94. accepts =
  95. from(
  96. a in Activity,
  97. where: fragment("?->>'type' = ?", a.data, "Accept")
  98. )
  99. |> Repo.all()
  100. assert length(accepts) == 2
  101. end
  102. test "it rejects incoming follow requests from blocked users when deny_follow_blocked is enabled" do
  103. Pleroma.Config.put([:user, :deny_follow_blocked], true)
  104. user = insert(:user)
  105. {:ok, target} = User.get_or_fetch("http://mastodon.example.org/users/admin")
  106. {:ok, _user_relationship} = User.block(user, target)
  107. data =
  108. File.read!("test/fixtures/mastodon-follow-activity.json")
  109. |> Poison.decode!()
  110. |> Map.put("object", user.ap_id)
  111. {:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
  112. %Activity{} = activity = Activity.get_by_ap_id(id)
  113. assert activity.data["state"] == "reject"
  114. end
  115. test "it rejects incoming follow requests if the following errors for some reason" do
  116. user = insert(:user)
  117. data =
  118. File.read!("test/fixtures/mastodon-follow-activity.json")
  119. |> Poison.decode!()
  120. |> Map.put("object", user.ap_id)
  121. with_mock Pleroma.User, [:passthrough], follow: fn _, _, _ -> {:error, :testing} end do
  122. {:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
  123. %Activity{} = activity = Activity.get_by_ap_id(id)
  124. assert activity.data["state"] == "reject"
  125. end
  126. end
  127. test "it works for incoming follow requests from hubzilla" do
  128. user = insert(:user)
  129. data =
  130. File.read!("test/fixtures/hubzilla-follow-activity.json")
  131. |> Poison.decode!()
  132. |> Map.put("object", user.ap_id)
  133. |> Utils.normalize_params()
  134. {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
  135. assert data["actor"] == "https://hubzilla.example.org/channel/kaniini"
  136. assert data["type"] == "Follow"
  137. assert data["id"] == "https://hubzilla.example.org/channel/kaniini#follows/2"
  138. assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
  139. end
  140. test "it works for incoming follows to locked account" do
  141. pending_follower = insert(:user, ap_id: "http://mastodon.example.org/users/admin")
  142. user = insert(:user, locked: true)
  143. data =
  144. File.read!("test/fixtures/mastodon-follow-activity.json")
  145. |> Poison.decode!()
  146. |> Map.put("object", user.ap_id)
  147. {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
  148. assert data["type"] == "Follow"
  149. assert data["object"] == user.ap_id
  150. assert data["state"] == "pending"
  151. assert data["actor"] == "http://mastodon.example.org/users/admin"
  152. assert [^pending_follower] = User.get_follow_requests(user)
  153. end
  154. end
  155. end