1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.UploadTest do
8 import ExUnit.CaptureLog
11 alias Pleroma.UnstubbedConfigMock, as: ConfigMock
13 alias Pleroma.Uploaders.Uploader
17 |> stub_with(Pleroma.Test.StaticConfig)
22 @upload_file %Plug.Upload{
23 content_type: "image/jpeg",
24 path: Path.absname("test/fixtures/image_tmp.jpg"),
28 defmodule TestUploaderBase do
29 def put_file(%{path: path} = _upload, module_name) do
35 |> :global.whereis_name()
36 |> send({Uploader, self(), {:test}, %{}})
38 assert_receive {Uploader, {:test}}, 4_000
41 Agent.start(fn -> task_pid end, name: module_name)
47 describe "Tried storing a file when http callback response success result" do
48 defmodule TestUploaderSuccess do
49 def http_callback(conn, _params),
50 do: {:ok, conn, {:file, "post-process-file.jpg"}}
52 def put_file(upload), do: TestUploaderBase.put_file(upload, __MODULE__)
55 setup do: [uploader: TestUploaderSuccess]
56 setup [:ensure_local_uploader]
58 test "it returns file" do
59 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
61 assert {:ok, result} = Upload.store(@upload_file)
66 "name" => "image.jpg",
68 "mediaType" => "image/jpeg",
71 "href" => "http://localhost:4001/media/post-process-file.jpg",
72 "mediaType" => "image/jpeg",
78 Task.await(Agent.get(TestUploaderSuccess, fn task_pid -> task_pid end))
82 describe "Tried storing a file when http callback response error" do
83 defmodule TestUploaderError do
84 def http_callback(conn, _params), do: {:error, conn, "Errors"}
86 def put_file(upload), do: TestUploaderBase.put_file(upload, __MODULE__)
89 setup do: [uploader: TestUploaderError]
90 setup [:ensure_local_uploader]
92 test "it returns error" do
93 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
95 assert capture_log(fn ->
96 assert Upload.store(@upload_file) == {:error, "Errors"}
97 Task.await(Agent.get(TestUploaderError, fn task_pid -> task_pid end))
99 "[error] Elixir.Pleroma.Upload store (using Pleroma.UploadTest.TestUploaderError) failed: \"Errors\""
103 describe "Tried storing a file when http callback doesn't response by timeout" do
104 defmodule(TestUploader, do: def(put_file(_upload), do: :wait_callback))
105 setup do: [uploader: TestUploader]
106 setup [:ensure_local_uploader]
108 test "it returns error" do
109 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
111 assert capture_log(fn ->
112 assert Upload.store(@upload_file) == {:error, "Uploader callback timeout"}
114 "[error] Elixir.Pleroma.Upload store (using Pleroma.UploadTest.TestUploader) failed: \"Uploader callback timeout\""
118 describe "Storing a file with the Local uploader" do
119 setup [:ensure_local_uploader]
121 test "does not allow descriptions longer than the post limit" do
122 clear_config([:instance, :description_limit], 2)
123 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
126 content_type: "image/jpeg",
127 path: Path.absname("test/fixtures/image_tmp.jpg"),
128 filename: "image.jpg"
131 {:error, :description_too_long} = Upload.store(file, description: "123")
134 test "returns a media url" do
135 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
138 content_type: "image/jpeg",
139 path: Path.absname("test/fixtures/image_tmp.jpg"),
140 filename: "image.jpg"
143 {:ok, data} = Upload.store(file)
145 assert %{"url" => [%{"href" => url}]} = data
147 assert String.starts_with?(url, Pleroma.Upload.base_url())
150 test "copies the file to the configured folder with deduping" do
151 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
154 content_type: "image/jpeg",
155 path: Path.absname("test/fixtures/image_tmp.jpg"),
156 filename: "an [image.jpg"
159 {:ok, data} = Upload.store(file, filters: [Pleroma.Upload.Filter.Dedupe])
161 assert List.first(data["url"])["href"] ==
162 Pleroma.Upload.base_url() <>
163 "e30397b58d226d6583ab5b8b3c5defb0c682bda5c31ef07a9f57c1c4986e3781.jpg"
166 test "copies the file to the configured folder without deduping" do
167 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
170 content_type: "image/jpeg",
171 path: Path.absname("test/fixtures/image_tmp.jpg"),
172 filename: "an [image.jpg"
175 {:ok, data} = Upload.store(file)
176 assert data["name"] == "an [image.jpg"
179 test "fixes incorrect content type when base64 is given" do
181 img: "data:image/png;base64,#{Base.encode64(File.read!("test/fixtures/image.jpg"))}"
184 {:ok, data} = Upload.store(params)
185 assert hd(data["url"])["mediaType"] == "image/jpeg"
188 test "adds extension when base64 is given" do
189 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
192 img: "data:image/png;base64,#{Base.encode64(File.read!("test/fixtures/image.jpg"))}"
195 {:ok, data} = Upload.store(params)
196 assert String.ends_with?(data["name"], ".jpg")
199 test "copies the file to the configured folder with anonymizing filename" do
200 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
203 content_type: "image/jpeg",
204 path: Path.absname("test/fixtures/image_tmp.jpg"),
205 filename: "an [image.jpg"
208 {:ok, data} = Upload.store(file, filters: [Pleroma.Upload.Filter.AnonymizeFilename])
210 refute data["name"] == "an [image.jpg"
213 test "escapes invalid characters in url" do
214 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
217 content_type: "image/jpeg",
218 path: Path.absname("test/fixtures/image_tmp.jpg"),
219 filename: "an… image.jpg"
222 {:ok, data} = Upload.store(file)
223 [attachment_url | _] = data["url"]
225 assert Path.basename(attachment_url["href"]) == "an%E2%80%A6%20image.jpg"
228 test "escapes reserved uri characters" do
229 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
232 content_type: "image/jpeg",
233 path: Path.absname("test/fixtures/image_tmp.jpg"),
234 filename: ":?#[]@!$&\\'()*+,;=.jpg"
237 {:ok, data} = Upload.store(file)
238 [attachment_url | _] = data["url"]
240 assert Path.basename(attachment_url["href"]) ==
241 "%3A%3F%23%5B%5D%40%21%24%26%5C%27%28%29%2A%2B%2C%3B%3D.jpg"
245 describe "Setting a custom base_url for uploaded media" do
246 setup do: clear_config([Pleroma.Upload, :base_url], "https://cache.pleroma.social")
248 # This seems to be backwards. Skipped for that reason
250 test "returns a media url with configured base_url" do
251 base_url = Pleroma.Config.get([Pleroma.Upload, :base_url])
253 File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
256 content_type: "image/jpeg",
257 path: Path.absname("test/fixtures/image_tmp.jpg"),
258 filename: "image.jpg"
261 {:ok, data} = Upload.store(file, base_url: base_url)
263 assert %{"url" => [%{"href" => url}]} = data
265 refute String.starts_with?(url, base_url <> "/media/")