logo

pleroma

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

user_controller_test.exs (9047B)


  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.Feed.UserControllerTest do
  5. use Pleroma.Web.ConnCase
  6. import Pleroma.Factory
  7. import SweetXml
  8. alias Pleroma.Object
  9. alias Pleroma.User
  10. alias Pleroma.Web.CommonAPI
  11. alias Pleroma.Web.Feed.FeedView
  12. setup do: clear_config([:static_fe, :enabled], false)
  13. describe "feed" do
  14. setup do: clear_config([:feed])
  15. setup do
  16. clear_config(
  17. [:feed, :post_title],
  18. %{max_length: 15, omission: "..."}
  19. )
  20. activity = insert(:note_activity)
  21. note =
  22. insert(:note,
  23. data: %{
  24. "content" => "This & this is :moominmamma: note ",
  25. "source" => "This & this is :moominmamma: note ",
  26. "attachment" => [
  27. %{
  28. "url" => [
  29. %{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}
  30. ]
  31. }
  32. ],
  33. "inReplyTo" => activity.data["id"],
  34. "context" => "2hu & as",
  35. "summary" => "2hu & as"
  36. }
  37. )
  38. note_activity = insert(:note_activity, note: note)
  39. user = User.get_cached_by_ap_id(note_activity.data["actor"])
  40. note2 =
  41. insert(:note,
  42. user: user,
  43. data: %{
  44. "content" => "42 & This is :moominmamma: note ",
  45. "inReplyTo" => activity.data["id"]
  46. }
  47. )
  48. note_activity2 = insert(:note_activity, note: note2)
  49. note3 =
  50. insert(:note,
  51. user: user,
  52. data: %{
  53. "content" => "This note tests whether HTML entities are truncated properly",
  54. "summary" => "Won't, didn't fail",
  55. "inReplyTo" => note_activity2.id
  56. }
  57. )
  58. _note_activity3 = insert(:note_activity, note: note3)
  59. object = Object.normalize(note_activity, fetch: false)
  60. encoded_title = FeedView.activity_title(note3.data)
  61. [user: user, object: object, max_id: note_activity2.id, encoded_title: encoded_title]
  62. end
  63. test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_id} do
  64. resp =
  65. conn
  66. |> put_req_header("accept", "application/atom+xml")
  67. |> get(user_feed_path(conn, :feed, user.nickname))
  68. |> response(200)
  69. activity_titles =
  70. resp
  71. |> SweetXml.parse()
  72. |> SweetXml.xpath(~x"//entry/title/text()"l)
  73. assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
  74. assert resp =~ FeedView.escape(object.data["content"])
  75. assert resp =~ FeedView.escape(object.data["summary"])
  76. assert resp =~ FeedView.escape(object.data["context"])
  77. resp =
  78. conn
  79. |> put_req_header("accept", "application/atom+xml")
  80. |> get("/users/#{user.nickname}/feed", %{"max_id" => max_id})
  81. |> response(200)
  82. activity_titles =
  83. resp
  84. |> SweetXml.parse()
  85. |> SweetXml.xpath(~x"//entry/title/text()"l)
  86. assert activity_titles == ['2hu & as']
  87. end
  88. test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id} do
  89. resp =
  90. conn
  91. |> put_req_header("accept", "application/rss+xml")
  92. |> get("/users/#{user.nickname}/feed.rss")
  93. |> response(200)
  94. activity_titles =
  95. resp
  96. |> SweetXml.parse()
  97. |> SweetXml.xpath(~x"//item/title/text()"l)
  98. assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
  99. assert resp =~ FeedView.escape(object.data["content"])
  100. assert resp =~ FeedView.escape(object.data["summary"])
  101. assert resp =~ FeedView.escape(object.data["context"])
  102. resp =
  103. conn
  104. |> put_req_header("accept", "application/rss+xml")
  105. |> get("/users/#{user.nickname}/feed.rss", %{"max_id" => max_id})
  106. |> response(200)
  107. activity_titles =
  108. resp
  109. |> SweetXml.parse()
  110. |> SweetXml.xpath(~x"//item/title/text()"l)
  111. assert activity_titles == ['2hu & as']
  112. end
  113. test "returns 404 for a missing feed", %{conn: conn} do
  114. conn =
  115. conn
  116. |> put_req_header("accept", "application/atom+xml")
  117. |> get(user_feed_path(conn, :feed, "nonexisting"))
  118. assert response(conn, 404)
  119. end
  120. test "returns feed with public and unlisted activities", %{conn: conn} do
  121. user = insert(:user)
  122. {:ok, _} = CommonAPI.post(user, %{status: "public", visibility: "public"})
  123. {:ok, _} = CommonAPI.post(user, %{status: "direct", visibility: "direct"})
  124. {:ok, _} = CommonAPI.post(user, %{status: "unlisted", visibility: "unlisted"})
  125. {:ok, _} = CommonAPI.post(user, %{status: "private", visibility: "private"})
  126. resp =
  127. conn
  128. |> put_req_header("accept", "application/atom+xml")
  129. |> get(user_feed_path(conn, :feed, user.nickname))
  130. |> response(200)
  131. activity_titles =
  132. resp
  133. |> SweetXml.parse()
  134. |> SweetXml.xpath(~x"//entry/title/text()"l)
  135. |> Enum.sort()
  136. assert activity_titles == ['public', 'unlisted']
  137. end
  138. test "returns 404 when the user is remote", %{conn: conn} do
  139. user = insert(:user, local: false)
  140. {:ok, _} = CommonAPI.post(user, %{status: "test"})
  141. assert conn
  142. |> put_req_header("accept", "application/atom+xml")
  143. |> get(user_feed_path(conn, :feed, user.nickname))
  144. |> response(404)
  145. end
  146. test "does not require authentication on non-federating instances", %{conn: conn} do
  147. clear_config([:instance, :federating], false)
  148. user = insert(:user)
  149. conn
  150. |> put_req_header("accept", "application/rss+xml")
  151. |> get("/users/#{user.nickname}/feed.rss")
  152. |> response(200)
  153. end
  154. test "does not mangle HTML entities midway", %{
  155. conn: conn,
  156. user: user,
  157. object: object,
  158. encoded_title: encoded_title
  159. } do
  160. resp =
  161. conn
  162. |> put_req_header("accept", "application/atom+xml")
  163. |> get(user_feed_path(conn, :feed, user.nickname))
  164. |> response(200)
  165. activity_titles =
  166. resp
  167. |> SweetXml.parse()
  168. |> SweetXml.xpath(~x"//entry/title/text()"l)
  169. assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
  170. assert resp =~ FeedView.escape(object.data["content"])
  171. assert resp =~ FeedView.escape(object.data["summary"])
  172. assert resp =~ FeedView.escape(object.data["context"])
  173. assert resp =~ encoded_title
  174. end
  175. end
  176. # Note: see ActivityPubControllerTest for JSON format tests
  177. describe "feed_redirect" do
  178. test "with html format, it redirects to user feed", %{conn: conn} do
  179. note_activity = insert(:note_activity)
  180. user = User.get_cached_by_ap_id(note_activity.data["actor"])
  181. response =
  182. conn
  183. |> get("/users/#{user.nickname}")
  184. |> response(200)
  185. assert response ==
  186. Pleroma.Web.Fallback.RedirectController.redirector_with_meta(
  187. conn,
  188. %{user: user}
  189. ).resp_body
  190. end
  191. test "with html format, it falls back to frontend when user is remote", %{conn: conn} do
  192. user = insert(:user, local: false)
  193. {:ok, _} = CommonAPI.post(user, %{status: "test"})
  194. response =
  195. conn
  196. |> get("/users/#{user.nickname}")
  197. |> response(200)
  198. assert response =~ "</html>"
  199. end
  200. test "with html format, it falls back to frontend when user is not found", %{conn: conn} do
  201. response =
  202. conn
  203. |> get("/users/jimm")
  204. |> response(200)
  205. assert response =~ "</html>"
  206. end
  207. test "with non-html / non-json format, it redirects to user feed in atom format", %{
  208. conn: conn
  209. } do
  210. note_activity = insert(:note_activity)
  211. user = User.get_cached_by_ap_id(note_activity.data["actor"])
  212. conn =
  213. conn
  214. |> put_req_header("accept", "application/xml")
  215. |> get("/users/#{user.nickname}")
  216. assert conn.status == 302
  217. assert redirected_to(conn) ==
  218. "#{Pleroma.Web.Endpoint.url()}/users/#{user.nickname}/feed.atom"
  219. end
  220. test "with non-html / non-json format, it returns error when user is not found", %{conn: conn} do
  221. response =
  222. conn
  223. |> put_req_header("accept", "application/xml")
  224. |> get(user_feed_path(conn, :feed, "jimm"))
  225. |> response(404)
  226. assert response == ~S({"error":"Not found"})
  227. end
  228. end
  229. describe "private instance" do
  230. setup do: clear_config([:instance, :public])
  231. test "returns 404 for user feed", %{conn: conn} do
  232. clear_config([:instance, :public], false)
  233. user = insert(:user)
  234. {:ok, _} = CommonAPI.post(user, %{status: "test"})
  235. assert conn
  236. |> put_req_header("accept", "application/atom+xml")
  237. |> get(user_feed_path(conn, :feed, user.nickname))
  238. |> response(404)
  239. end
  240. end
  241. end