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.

275 lines
8.4KB

  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.UploadTest do
  5. use Pleroma.DataCase
  6. import ExUnit.CaptureLog
  7. alias Pleroma.Upload
  8. alias Pleroma.Uploaders.Uploader
  9. @upload_file %Plug.Upload{
  10. content_type: "image/jpg",
  11. path: Path.absname("test/fixtures/image_tmp.jpg"),
  12. filename: "image.jpg"
  13. }
  14. defmodule TestUploaderBase do
  15. def put_file(%{path: path} = _upload, module_name) do
  16. task_pid =
  17. Task.async(fn ->
  18. :timer.sleep(10)
  19. {Uploader, path}
  20. |> :global.whereis_name()
  21. |> send({Uploader, self(), {:test}, %{}})
  22. assert_receive {Uploader, {:test}}, 4_000
  23. end)
  24. Agent.start(fn -> task_pid end, name: module_name)
  25. :wait_callback
  26. end
  27. end
  28. describe "Tried storing a file when http callback response success result" do
  29. defmodule TestUploaderSuccess do
  30. def http_callback(conn, _params),
  31. do: {:ok, conn, {:file, "post-process-file.jpg"}}
  32. def put_file(upload), do: TestUploaderBase.put_file(upload, __MODULE__)
  33. end
  34. setup do: [uploader: TestUploaderSuccess]
  35. setup [:ensure_local_uploader]
  36. test "it returns file" do
  37. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  38. assert Upload.store(@upload_file) ==
  39. {:ok,
  40. %{
  41. "name" => "image.jpg",
  42. "type" => "Document",
  43. "mediaType" => "image/jpeg",
  44. "url" => [
  45. %{
  46. "href" => "http://localhost:4001/media/post-process-file.jpg",
  47. "mediaType" => "image/jpeg",
  48. "type" => "Link"
  49. }
  50. ]
  51. }}
  52. Task.await(Agent.get(TestUploaderSuccess, fn task_pid -> task_pid end))
  53. end
  54. end
  55. describe "Tried storing a file when http callback response error" do
  56. defmodule TestUploaderError do
  57. def http_callback(conn, _params), do: {:error, conn, "Errors"}
  58. def put_file(upload), do: TestUploaderBase.put_file(upload, __MODULE__)
  59. end
  60. setup do: [uploader: TestUploaderError]
  61. setup [:ensure_local_uploader]
  62. test "it returns error" do
  63. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  64. assert capture_log(fn ->
  65. assert Upload.store(@upload_file) == {:error, "Errors"}
  66. Task.await(Agent.get(TestUploaderError, fn task_pid -> task_pid end))
  67. end) =~
  68. "[error] Elixir.Pleroma.Upload store (using Pleroma.UploadTest.TestUploaderError) failed: \"Errors\""
  69. end
  70. end
  71. describe "Tried storing a file when http callback doesn't response by timeout" do
  72. defmodule(TestUploader, do: def(put_file(_upload), do: :wait_callback))
  73. setup do: [uploader: TestUploader]
  74. setup [:ensure_local_uploader]
  75. test "it returns error" do
  76. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  77. assert capture_log(fn ->
  78. assert Upload.store(@upload_file) == {:error, "Uploader callback timeout"}
  79. end) =~
  80. "[error] Elixir.Pleroma.Upload store (using Pleroma.UploadTest.TestUploader) failed: \"Uploader callback timeout\""
  81. end
  82. end
  83. describe "Storing a file with the Local uploader" do
  84. setup [:ensure_local_uploader]
  85. test "returns a media url" do
  86. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  87. file = %Plug.Upload{
  88. content_type: "image/jpg",
  89. path: Path.absname("test/fixtures/image_tmp.jpg"),
  90. filename: "image.jpg"
  91. }
  92. {:ok, data} = Upload.store(file)
  93. assert %{"url" => [%{"href" => url}]} = data
  94. assert String.starts_with?(url, Pleroma.Web.base_url() <> "/media/")
  95. end
  96. test "copies the file to the configured folder with deduping" do
  97. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  98. file = %Plug.Upload{
  99. content_type: "image/jpg",
  100. path: Path.absname("test/fixtures/image_tmp.jpg"),
  101. filename: "an [image.jpg"
  102. }
  103. {:ok, data} = Upload.store(file, filters: [Pleroma.Upload.Filter.Dedupe])
  104. assert List.first(data["url"])["href"] ==
  105. Pleroma.Web.base_url() <>
  106. "/media/e30397b58d226d6583ab5b8b3c5defb0c682bda5c31ef07a9f57c1c4986e3781.jpg"
  107. end
  108. test "copies the file to the configured folder without deduping" do
  109. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  110. file = %Plug.Upload{
  111. content_type: "image/jpg",
  112. path: Path.absname("test/fixtures/image_tmp.jpg"),
  113. filename: "an [image.jpg"
  114. }
  115. {:ok, data} = Upload.store(file)
  116. assert data["name"] == "an [image.jpg"
  117. end
  118. test "fixes incorrect content type" do
  119. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  120. file = %Plug.Upload{
  121. content_type: "application/octet-stream",
  122. path: Path.absname("test/fixtures/image_tmp.jpg"),
  123. filename: "an [image.jpg"
  124. }
  125. {:ok, data} = Upload.store(file, filters: [Pleroma.Upload.Filter.Dedupe])
  126. assert hd(data["url"])["mediaType"] == "image/jpeg"
  127. end
  128. test "adds missing extension" do
  129. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  130. file = %Plug.Upload{
  131. content_type: "image/jpg",
  132. path: Path.absname("test/fixtures/image_tmp.jpg"),
  133. filename: "an [image"
  134. }
  135. {:ok, data} = Upload.store(file)
  136. assert data["name"] == "an [image.jpg"
  137. end
  138. test "fixes incorrect file extension" do
  139. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  140. file = %Plug.Upload{
  141. content_type: "image/jpg",
  142. path: Path.absname("test/fixtures/image_tmp.jpg"),
  143. filename: "an [image.blah"
  144. }
  145. {:ok, data} = Upload.store(file)
  146. assert data["name"] == "an [image.jpg"
  147. end
  148. test "don't modify filename of an unknown type" do
  149. File.cp("test/fixtures/test.txt", "test/fixtures/test_tmp.txt")
  150. file = %Plug.Upload{
  151. content_type: "text/plain",
  152. path: Path.absname("test/fixtures/test_tmp.txt"),
  153. filename: "test.txt"
  154. }
  155. {:ok, data} = Upload.store(file)
  156. assert data["name"] == "test.txt"
  157. end
  158. test "copies the file to the configured folder with anonymizing filename" do
  159. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  160. file = %Plug.Upload{
  161. content_type: "image/jpg",
  162. path: Path.absname("test/fixtures/image_tmp.jpg"),
  163. filename: "an [image.jpg"
  164. }
  165. {:ok, data} = Upload.store(file, filters: [Pleroma.Upload.Filter.AnonymizeFilename])
  166. refute data["name"] == "an [image.jpg"
  167. end
  168. test "escapes invalid characters in url" do
  169. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  170. file = %Plug.Upload{
  171. content_type: "image/jpg",
  172. path: Path.absname("test/fixtures/image_tmp.jpg"),
  173. filename: "an… image.jpg"
  174. }
  175. {:ok, data} = Upload.store(file)
  176. [attachment_url | _] = data["url"]
  177. assert Path.basename(attachment_url["href"]) == "an%E2%80%A6%20image.jpg"
  178. end
  179. test "escapes reserved uri characters" do
  180. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  181. file = %Plug.Upload{
  182. content_type: "image/jpg",
  183. path: Path.absname("test/fixtures/image_tmp.jpg"),
  184. filename: ":?#[]@!$&\\'()*+,;=.jpg"
  185. }
  186. {:ok, data} = Upload.store(file)
  187. [attachment_url | _] = data["url"]
  188. assert Path.basename(attachment_url["href"]) ==
  189. "%3A%3F%23%5B%5D%40%21%24%26%5C%27%28%29%2A%2B%2C%3B%3D.jpg"
  190. end
  191. end
  192. describe "Setting a custom base_url for uploaded media" do
  193. setup do: clear_config([Pleroma.Upload, :base_url], "https://cache.pleroma.social")
  194. test "returns a media url with configured base_url" do
  195. base_url = Pleroma.Config.get([Pleroma.Upload, :base_url])
  196. File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
  197. file = %Plug.Upload{
  198. content_type: "image/jpg",
  199. path: Path.absname("test/fixtures/image_tmp.jpg"),
  200. filename: "image.jpg"
  201. }
  202. {:ok, data} = Upload.store(file, base_url: base_url)
  203. assert %{"url" => [%{"href" => url}]} = data
  204. refute String.starts_with?(url, base_url <> "/media/")
  205. end
  206. end
  207. end