emoji api packs changes in routes with docs update

This commit is contained in:
Alexander Strizhakov 2020-03-28 21:15:14 +03:00
parent f3070ddae5
commit ddb757f743
No known key found for this signature in database
GPG Key ID: 022896A53AEF1381
5 changed files with 231 additions and 356 deletions

View File

@ -323,27 +323,47 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Params: None * Params: None
* Response: JSON, returns a list of Mastodon Conversation entities that were marked as read (200 - healthy, 503 unhealthy). * Response: JSON, returns a list of Mastodon Conversation entities that were marked as read (200 - healthy, 503 unhealthy).
## `GET /api/pleroma/emoji/packs` ## `GET /api/pleroma/emoji/packs/import`
### Lists the custom emoji packs on the server ### Imports packs from filesystem
* Method `GET` * Method `GET`
* Authentication: not required * Authentication: required
* Params: None * Params: None
* Response: JSON, "ok" and 200 status and the JSON hashmap of "pack name" to "pack contents" * Response: JSON, returns a list of imported packs.
## `GET /api/pleroma/emoji/packs/:name` ## `GET /api/pleroma/emoji/packs/remote`
### Get pack.json for the pack ### Make request to another instance for packs list
* Method `GET` * Method `GET`
* Authentication: not required * Authentication: required
* Params: None * Params:
* Response: JSON, pack json with `files` and `pack` keys with 200 status or 404 if the pack does not exist * `url`: url of the instance to get packs from
* Response: JSON with the pack list, hashmap with pack name and pack contents
## `PUT /api/pleroma/emoji/packs/:name` ## `POST /api/pleroma/emoji/packs/download`
### Creates an empty custom emoji pack ### Download pack from another instance
* Method `PUT` * Method `POST`
* Authentication: required
* Params:
* `url`: url of the instance to download from
* `name`: pack to download from that instance
* Response: JSON, "ok" with 200 status if the pack was downloaded, or 500 if there were
errors downloading the pack
## `POST /api/pleroma/emoji/packs/:name`
### Creates an empty pack
* Method `POST`
* Authentication: required * Authentication: required
* Params: None * Params: None
* Response: JSON, "ok" and 200 status or 409 if the pack with that name already exists * Response: JSON, "ok" and 200 status or 409 if the pack with that name already exists
## `PATCH /api/pleroma/emoji/packs/:name`
### Updates (replaces) pack metadata
* Method `POST`
* Authentication: required
* Params:
* `metadata`: metadata to replace the old one
* Response: JSON, updated "metadata" section of the pack and 200 status or 400 if there was a
problem with the new metadata (the error is specified in the "error" part of the response JSON)
## `DELETE /api/pleroma/emoji/packs/:name` ## `DELETE /api/pleroma/emoji/packs/:name`
### Delete a custom emoji pack ### Delete a custom emoji pack
* Method `DELETE` * Method `DELETE`
@ -351,54 +371,50 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Params: None * Params: None
* Response: JSON, "ok" and 200 status or 500 if there was an error deleting the pack * Response: JSON, "ok" and 200 status or 500 if there was an error deleting the pack
## `POST /api/pleroma/emoji/packs/:name/update_file` ## `POST /api/pleroma/emoji/packs/:name/files`
### Update a file in a custom emoji pack ### Add new file to the pack
* Method `POST` * Method `POST`
* Authentication: required * Authentication: required
* Params: * Params:
* if the `action` is `add`, adds an emoji file to the pack `pack_name`, * `file`: uploaded file or link to remote file.
(thus requiring it to be a multipart request) and be named `file`. * `shortcode`: (*optional*) shortcode for new emoji, must be uniq for all emoji. If not sended, shortcode will be taken from original filename.
If `shortcode` is not specified, `shortcode` will be used from filename. * `filename`: (*optional*) new emoji file name. If not specified will be taken from original filename.
There can also be an optional `filename` that will be the new emoji file name * Response: JSON, list of files for updated pack (hasmap -> shortcode => filename) with status 200, either error status with error message.
(if it's not there, the name will be taken from the uploaded file).
* if the `action` is `update`, changes emoji shortcode
(from `shortcode` to `new_shortcode` or moves the file (from the current filename to `new_filename`).
If new_shortcode is used in another emoji 409 status will be returned. If you want to override shortcode
pass `force` option with `true` value.
* if the `action` is `remove`, removes the emoji named `shortcode` and it's associated file
* Response: JSON, updated "files" section of the pack and 200 status, 409 if the trying to use a shortcode
that is already taken, 400 if there was an error with the shortcode, filename or file (additional info
in the "error" part of the response JSON)
## `POST /api/pleroma/emoji/packs/:name/update_metadata` ## `PATCH /api/pleroma/emoji/packs/:name/files`
### Updates (replaces) pack metadata ### Update emoji file from pack
* Method `POST` * Method `PATCH`
* Authentication: required * Authentication: required
* Params: * Params:
* `new_data`: new metadata to replace the old one * `shortcode`: emoji file shortcode
* Response: JSON, updated "metadata" section of the pack and 200 status or 400 if there was a * `new_shortcode`: new emoji file shortcode
problem with the new metadata (the error is specified in the "error" part of the response JSON) * `new_filename`: new filename for emoji file
* `force`: (*optional*) with true value to overwrite existing emoji with new shortcode
* Response: JSON, list with updated files for updated pack (hasmap -> shortcode => filename) with status 200, either error status with error message.
## `POST /api/pleroma/emoji/packs/download_from` ## `DELETE /api/pleroma/emoji/packs/:name/files`
### Requests the instance to download the pack from another instance ### Delete emoji file from pack
* Method `POST` * Method `DELETE`
* Authentication: required * Authentication: required
* Params: * Params:
* `instance_address`: the address of the instance to download from * `shortcode`: emoji file shortcode
* `pack_name`: the pack to download from that instance * Response: JSON, list with updated files for updated pack (hasmap -> shortcode => filename) with status 200, either error status with error message.
* Response: JSON, "ok" and 200 status if the pack was downloaded, or 500 if there were
errors downloading the pack
## `POST /api/pleroma/emoji/packs/list_from` ## `GET /api/pleroma/emoji/packs`
### Requests the instance to list the packs from another instance ### Lists local custom emoji packs
* Method `POST` * Method `GET`
* Authentication: required * Authentication: not required
* Params: * Params: None
* `instance_address`: the address of the instance to get packs from * Response: JSON, "ok" and 200 status and the JSON hashmap of pack name to pack contents
* Response: JSON with the pack list, same as if the request was made to that instance's
list endpoint directly + 200 status
## `GET /api/pleroma/emoji/packs/:name/download_shared` ## `GET /api/pleroma/emoji/packs/:name`
### Get pack.json for the pack
* Method `GET`
* Authentication: not required
* Params: None
* Response: JSON, pack json with `files` and `pack` keys with 200 status or 404 if the pack does not exist
## `GET /api/pleroma/emoji/packs/:name/archive`
### Requests a local pack from the instance ### Requests a local pack from the instance
* Method `GET` * Method `GET`
* Authentication: not required * Authentication: not required

View File

@ -102,9 +102,9 @@ defp create_subdirs(file_path) do
end end
end end
@spec remove_file(String.t(), String.t()) :: @spec delete_file(String.t(), String.t()) ::
{:ok, t()} | {:error, File.posix()} | {:error, :empty_values} {:ok, t()} | {:error, File.posix()} | {:error, :empty_values}
def remove_file(name, shortcode) when byte_size(name) > 0 and byte_size(shortcode) > 0 do def delete_file(name, shortcode) when byte_size(name) > 0 and byte_size(shortcode) > 0 do
with {_, %__MODULE__{} = pack} <- {:loaded, load_pack(name)}, with {_, %__MODULE__{} = pack} <- {:loaded, load_pack(name)},
{_, {filename, files}} when not is_nil(filename) <- {_, {filename, files}} when not is_nil(filename) <-
{:exists, Map.pop(pack.files, shortcode)}, {:exists, Map.pop(pack.files, shortcode)},
@ -131,7 +131,7 @@ def remove_file(name, shortcode) when byte_size(name) > 0 and byte_size(shortcod
end end
end end
def remove_file(_, _), do: {:error, :empty_values} def delete_file(_, _), do: {:error, :empty_values}
@spec update_file(String.t(), String.t(), String.t(), String.t(), boolean()) :: @spec update_file(String.t(), String.t(), String.t(), String.t(), boolean()) ::
{:ok, t()} | {:error, File.posix()} | {:error, :empty_values} {:ok, t()} | {:error, File.posix()} | {:error, :empty_values}
@ -249,8 +249,8 @@ defp files_from_path(path) do
end end
end end
@spec list_remote_packs(String.t()) :: {:ok, map()} @spec list_remote(String.t()) :: {:ok, map()}
def list_remote_packs(url) do def list_remote(url) do
uri = uri =
url url
|> String.trim() |> String.trim()
@ -269,8 +269,8 @@ def list_remote_packs(url) do
end end
end end
@spec list_local_packs() :: {:ok, map()} @spec list_local() :: {:ok, map()}
def list_local_packs do def list_local do
emoji_path = emoji_path() emoji_path = emoji_path()
# Create the directory first if it does not exist. This is probably the first request made # Create the directory first if it does not exist. This is probably the first request made
@ -315,8 +315,8 @@ defp downloadable?(pack) do
end) end)
end end
@spec download(String.t()) :: {:ok, binary()} @spec get_archive(String.t()) :: {:ok, binary()}
def download(name) do def get_archive(name) do
with {_, %__MODULE__{} = pack} <- {:exists?, load_pack(name)}, with {_, %__MODULE__{} = pack} <- {:exists?, load_pack(name)},
{_, true} <- {:can_download?, downloadable?(pack)} do {_, true} <- {:can_download?, downloadable?(pack)} do
{:ok, fetch_archive(pack)} {:ok, fetch_archive(pack)}
@ -356,15 +356,14 @@ defp create_archive_and_cache(pack, hash) do
result result
end end
@spec download_from_source(String.t(), String.t(), String.t()) :: :ok @spec download(String.t(), String.t(), String.t()) :: :ok
def download_from_source(name, url, as) do def download(name, url, as) do
uri = uri =
url url
|> String.trim() |> String.trim()
|> URI.parse() |> URI.parse()
with {_, true} <- {:shareable, shareable_packs_available?(uri)} do with {_, true} <- {:shareable, shareable_packs_available?(uri)} do
# TODO: why do we load all packs, if we know the name of pack we need
remote_pack = remote_pack =
uri uri
|> URI.merge("/api/pleroma/emoji/packs/#{name}") |> URI.merge("/api/pleroma/emoji/packs/#{name}")
@ -379,8 +378,7 @@ def download_from_source(name, url, as) do
{:ok, {:ok,
%{ %{
sha: sha, sha: sha,
url: url: URI.merge(uri, "/api/pleroma/emoji/packs/#{name}/archive") |> to_string()
URI.merge(uri, "/api/pleroma/emoji/packs/#{name}/download_shared") |> to_string()
}} }}
%{"fallback-src" => src, "fallback-src-sha256" => sha} when is_binary(src) -> %{"fallback-src" => src, "fallback-src-sha256" => sha} when is_binary(src) ->

View File

@ -7,12 +7,15 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
Pleroma.Plugs.OAuthScopesPlug, Pleroma.Plugs.OAuthScopesPlug,
%{scopes: ["write"], admin: true} %{scopes: ["write"], admin: true}
when action in [ when action in [
:import,
:remote,
:download,
:create, :create,
:update,
:delete, :delete,
:download_from, :add_file,
:import_from_fs,
:update_file, :update_file,
:update_metadata :delete_file
] ]
) )
@ -22,14 +25,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
when action in [:download_shared, :list_packs, :list_from] when action in [:download_shared, :list_packs, :list_from]
) )
@doc """ def remote(conn, %{"url" => url}) do
Lists packs from the remote instance. with {:ok, packs} <- Pack.list_remote(url) do
Since JS cannot ask remote instances for their packs due to CPS, it has to
be done by the server
"""
def list_from(conn, %{"instance_address" => address}) do
with {:ok, packs} <- Pack.list_remote_packs(address) do
json(conn, packs) json(conn, packs)
else else
{:shareable, _} -> {:shareable, _} ->
@ -39,20 +36,14 @@ def list_from(conn, %{"instance_address" => address}) do
end end
end end
@doc """ def list(conn, _params) do
Lists the packs available on the instance as JSON.
The information is public and does not require authentication. The format is
a map of "pack directory name" to pack.json contents.
"""
def list_packs(conn, _params) do
emoji_path = emoji_path =
Path.join( Path.join(
Pleroma.Config.get!([:instance, :static_dir]), Pleroma.Config.get!([:instance, :static_dir]),
"emoji" "emoji"
) )
with {:ok, packs} <- Pack.list_local_packs() do with {:ok, packs} <- Pack.list_local() do
json(conn, packs) json(conn, packs)
else else
{:create_dir, {:error, e}} -> {:create_dir, {:error, e}} ->
@ -87,12 +78,8 @@ def show(conn, %{"name" => name}) do
end end
end end
@doc """ def archive(conn, %{"name" => name}) do
An endpoint for other instances (via admin UI) or users (via browser) with {:ok, archive} <- Pack.get_archive(name) do
to download packs that the instance shares.
"""
def download_shared(conn, %{"name" => name}) do
with {:ok, archive} <- Pack.download(name) do
send_download(conn, {:binary, archive}, filename: "#{name}.zip") send_download(conn, {:binary, archive}, filename: "#{name}.zip")
else else
{:can_download?, _} -> {:can_download?, _} ->
@ -110,15 +97,8 @@ def download_shared(conn, %{"name" => name}) do
end end
end end
@doc """ def download(conn, %{"url" => url, "name" => name} = params) do
An admin endpoint to request downloading and storing a pack named `pack_name` from the instance with :ok <- Pack.download(name, url, params["as"]) do
`instance_address`.
If the requested instance's admin chose to share the pack, it will be downloaded
from that instance, otherwise it will be downloaded from the fallback source, if there is one.
"""
def download_from(conn, %{"instance_address" => address, "pack_name" => name} = params) do
with :ok <- Pack.download_from_source(name, address, params["as"]) do
json(conn, "ok") json(conn, "ok")
else else
{:shareable, _} -> {:shareable, _} ->
@ -138,9 +118,6 @@ def download_from(conn, %{"instance_address" => address, "pack_name" => name} =
end end
end end
@doc """
Creates an empty pack named `name` which then can be updated via the admin UI.
"""
def create(conn, %{"name" => name}) do def create(conn, %{"name" => name}) do
name = String.trim(name) name = String.trim(name)
@ -166,9 +143,6 @@ def create(conn, %{"name" => name}) do
end end
end end
@doc """
Deletes the pack `name` and all it's files.
"""
def delete(conn, %{"name" => name}) do def delete(conn, %{"name" => name}) do
name = String.trim(name) name = String.trim(name)
@ -192,13 +166,8 @@ def delete(conn, %{"name" => name}) do
end end
end end
@doc """ def update(conn, %{"name" => name, "metadata" => metadata}) do
An endpoint to update `pack_names`'s metadata. with {:ok, pack} <- Pack.update_metadata(name, metadata) do
`new_data` is the new metadata for the pack, that will replace the old metadata.
"""
def update_metadata(conn, %{"pack_name" => name, "new_data" => new_data}) do
with {:ok, pack} <- Pack.update_metadata(name, new_data) do
json(conn, pack.pack) json(conn, pack.pack)
else else
{:has_all_files?, _} -> {:has_all_files?, _} ->
@ -215,30 +184,11 @@ def update_metadata(conn, %{"pack_name" => name, "new_data" => new_data}) do
end end
end end
@doc """ def add_file(conn, %{"name" => name} = params) do
Updates a file in a pack.
Updating can mean three things:
- `add` adds an emoji named `shortcode` to the pack `pack_name`,
that means that the emoji file needs to be uploaded with the request
(thus requiring it to be a multipart request) and be named `file`.
There can also be an optional `filename` that will be the new emoji file name
(if it's not there, the name will be taken from the uploaded file).
- `update` changes emoji shortcode (from `shortcode` to `new_shortcode` or moves the file
(from the current filename to `new_filename`)
- `remove` removes the emoji named `shortcode` and it's associated file
"""
# Add
def update_file(
conn,
%{"pack_name" => pack_name, "action" => "add"} = params
) do
filename = params["filename"] || get_filename(params["file"]) filename = params["filename"] || get_filename(params["file"])
shortcode = params["shortcode"] || Path.basename(filename, Path.extname(filename)) shortcode = params["shortcode"] || Path.basename(filename, Path.extname(filename))
with {:ok, pack} <- Pack.add_file(pack_name, shortcode, filename, params["file"]) do with {:ok, pack} <- Pack.add_file(name, shortcode, filename, params["file"]) do
json(conn, pack.files) json(conn, pack.files)
else else
{:exists, _} -> {:exists, _} ->
@ -249,7 +199,7 @@ def update_file(
{:loaded, _} -> {:loaded, _} ->
conn conn
|> put_status(:bad_request) |> put_status(:bad_request)
|> json(%{error: "pack \"#{pack_name}\" is not found"}) |> json(%{error: "pack \"#{name}\" is not found"})
{:error, :empty_values} -> {:error, :empty_values} ->
conn conn
@ -265,44 +215,7 @@ def update_file(
end end
end end
# Remove def update_file(conn, %{"name" => name, "shortcode" => shortcode} = params) do
def update_file(conn, %{
"pack_name" => pack_name,
"action" => "remove",
"shortcode" => shortcode
}) do
with {:ok, pack} <- Pack.remove_file(pack_name, shortcode) do
json(conn, pack.files)
else
{:exists, _} ->
conn
|> put_status(:bad_request)
|> json(%{error: "Emoji \"#{shortcode}\" does not exist"})
{:loaded, _} ->
conn
|> put_status(:bad_request)
|> json(%{error: "pack \"#{pack_name}\" is not found"})
{:error, :empty_values} ->
conn
|> put_status(:bad_request)
|> json(%{error: "pack name or shortcode cannot be empty"})
{:error, _} ->
render_error(
conn,
:internal_server_error,
"Unexpected error occurred while removing file from pack."
)
end
end
# Update
def update_file(
conn,
%{"pack_name" => name, "action" => "update", "shortcode" => shortcode} = params
) do
new_shortcode = params["new_shortcode"] new_shortcode = params["new_shortcode"]
new_filename = params["new_filename"] new_filename = params["new_filename"]
force = params["force"] == true force = params["force"] == true
@ -342,24 +255,35 @@ def update_file(
end end
end end
def update_file(conn, %{"action" => action}) do def delete_file(conn, %{"name" => name, "shortcode" => shortcode}) do
conn with {:ok, pack} <- Pack.delete_file(name, shortcode) do
|> put_status(:bad_request) json(conn, pack.files)
|> json(%{error: "Unknown action: #{action}"}) else
{:exists, _} ->
conn
|> put_status(:bad_request)
|> json(%{error: "Emoji \"#{shortcode}\" does not exist"})
{:loaded, _} ->
conn
|> put_status(:bad_request)
|> json(%{error: "pack \"#{name}\" is not found"})
{:error, :empty_values} ->
conn
|> put_status(:bad_request)
|> json(%{error: "pack name or shortcode cannot be empty"})
{:error, _} ->
render_error(
conn,
:internal_server_error,
"Unexpected error occurred while removing file from pack."
)
end
end end
@doc """ def import_from_filesystem(conn, _params) do
Imports emoji from the filesystem.
Importing means checking all the directories in the
`$instance_static/emoji/` for directories which do not have
`pack.json`. If one has an emoji.txt file, that file will be used
to create a `pack.json` file with it's contents. If the directory has
neither, all the files with specific configured extenstions will be
assumed to be emojis and stored in the new `pack.json` file.
"""
def import_from_fs(conn, _params) do
with {:ok, names} <- Pack.import_from_filesystem() do with {:ok, names} <- Pack.import_from_filesystem() do
json(conn, names) json(conn, names)
else else

View File

@ -214,25 +214,24 @@ defmodule Pleroma.Web.Router do
scope "/packs" do scope "/packs" do
pipe_through(:admin_api) pipe_through(:admin_api)
post("/import_from_fs", EmojiAPIController, :import_from_fs) get("/import", EmojiAPIController, :import_from_filesystem)
post("/:pack_name/update_file", EmojiAPIController, :update_file) get("/remote", EmojiAPIController, :remote)
post("/:pack_name/update_metadata", EmojiAPIController, :update_metadata) post("/download", EmojiAPIController, :download)
put("/:name", EmojiAPIController, :create)
post("/:name", EmojiAPIController, :create)
patch("/:name", EmojiAPIController, :update)
delete("/:name", EmojiAPIController, :delete) delete("/:name", EmojiAPIController, :delete)
# Note: /download_from downloads and saves to instance, not to requester post("/:name/files", EmojiAPIController, :add_file)
post("/download_from", EmojiAPIController, :download_from) patch("/:name/files", EmojiAPIController, :update_file)
delete("/:name/files", EmojiAPIController, :delete_file)
end end
# Pack info / downloading # Pack info / downloading
scope "/packs" do scope "/packs" do
get("/", EmojiAPIController, :list_packs) get("/", EmojiAPIController, :list)
get("/:name", EmojiAPIController, :show) get("/:name", EmojiAPIController, :show)
get("/:name/download_shared/", EmojiAPIController, :download_shared) get("/:name/archive", EmojiAPIController, :archive)
get("/list_from", EmojiAPIController, :list_from)
# Deprecated: POST /api/pleroma/emoji/packs/list_from (use GET instead)
post("/list_from", EmojiAPIController, :list_from)
end end
end end

View File

@ -41,7 +41,7 @@ test "GET /api/pleroma/emoji/packs", %{conn: conn} do
assert non_shared["pack"]["can-download"] == false assert non_shared["pack"]["can-download"] == false
end end
describe "POST /api/pleroma/emoji/packs/list_from" do describe "GET /api/pleroma/emoji/packs/remote" do
test "shareable instance", %{admin_conn: admin_conn, conn: conn} do test "shareable instance", %{admin_conn: admin_conn, conn: conn} do
resp = resp =
conn conn
@ -60,8 +60,8 @@ test "shareable instance", %{admin_conn: admin_conn, conn: conn} do
end) end)
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/list_from", %{ |> get("/api/pleroma/emoji/packs/remote", %{
instance_address: "https://example.com" url: "https://example.com"
}) })
|> json_response(200) == resp |> json_response(200) == resp
end end
@ -76,20 +76,18 @@ test "non shareable instance", %{admin_conn: admin_conn} do
end) end)
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/list_from", %{ |> get("/api/pleroma/emoji/packs/remote", %{url: "https://example.com"})
instance_address: "https://example.com"
})
|> json_response(500) == %{ |> json_response(500) == %{
"error" => "The requested instance does not support sharing emoji packs" "error" => "The requested instance does not support sharing emoji packs"
} }
end end
end end
describe "GET /api/pleroma/emoji/packs/:name/download_shared" do describe "GET /api/pleroma/emoji/packs/:name/archive" do
test "download shared pack", %{conn: conn} do test "download shared pack", %{conn: conn} do
resp = resp =
conn conn
|> get("/api/pleroma/emoji/packs/test_pack/download_shared") |> get("/api/pleroma/emoji/packs/test_pack/archive")
|> response(200) |> response(200)
{:ok, arch} = :zip.unzip(resp, [:memory]) {:ok, arch} = :zip.unzip(resp, [:memory])
@ -100,7 +98,7 @@ test "download shared pack", %{conn: conn} do
test "non existing pack", %{conn: conn} do test "non existing pack", %{conn: conn} do
assert conn assert conn
|> get("/api/pleroma/emoji/packs/test_pack_for_import/download_shared") |> get("/api/pleroma/emoji/packs/test_pack_for_import/archive")
|> json_response(:not_found) == %{ |> json_response(:not_found) == %{
"error" => "Pack test_pack_for_import does not exist" "error" => "Pack test_pack_for_import does not exist"
} }
@ -108,7 +106,7 @@ test "non existing pack", %{conn: conn} do
test "non downloadable pack", %{conn: conn} do test "non downloadable pack", %{conn: conn} do
assert conn assert conn
|> get("/api/pleroma/emoji/packs/test_pack_nonshared/download_shared") |> get("/api/pleroma/emoji/packs/test_pack_nonshared/archive")
|> json_response(:forbidden) == %{ |> json_response(:forbidden) == %{
"error" => "error" =>
"Pack test_pack_nonshared cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing" "Pack test_pack_nonshared cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing"
@ -116,7 +114,7 @@ test "non downloadable pack", %{conn: conn} do
end end
end end
describe "POST /api/pleroma/emoji/packs/download_from" do describe "POST /api/pleroma/emoji/packs/download" do
test "shared pack from remote and non shared from fallback-src", %{ test "shared pack from remote and non shared from fallback-src", %{
admin_conn: admin_conn, admin_conn: admin_conn,
conn: conn conn: conn
@ -139,10 +137,10 @@ test "shared pack from remote and non shared from fallback-src", %{
%{ %{
method: :get, method: :get,
url: "https://example.com/api/pleroma/emoji/packs/test_pack/download_shared" url: "https://example.com/api/pleroma/emoji/packs/test_pack/archive"
} -> } ->
conn conn
|> get("/api/pleroma/emoji/packs/test_pack/download_shared") |> get("/api/pleroma/emoji/packs/test_pack/archive")
|> response(200) |> response(200)
|> text() |> text()
@ -163,9 +161,9 @@ test "shared pack from remote and non shared from fallback-src", %{
end) end)
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/download_from", %{ |> post("/api/pleroma/emoji/packs/download", %{
instance_address: "https://example.com", url: "https://example.com",
pack_name: "test_pack", name: "test_pack",
as: "test_pack2" as: "test_pack2"
}) })
|> json_response(200) == "ok" |> json_response(200) == "ok"
@ -181,10 +179,10 @@ test "shared pack from remote and non shared from fallback-src", %{
assert admin_conn assert admin_conn
|> post( |> post(
"/api/pleroma/emoji/packs/download_from", "/api/pleroma/emoji/packs/download",
%{ %{
instance_address: "https://example.com", url: "https://example.com",
pack_name: "test_pack_nonshared", name: "test_pack_nonshared",
as: "test_pack_nonshared2" as: "test_pack_nonshared2"
} }
) )
@ -211,10 +209,10 @@ test "nonshareable instance", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post( |> post(
"/api/pleroma/emoji/packs/download_from", "/api/pleroma/emoji/packs/download",
%{ %{
instance_address: "https://old-instance", url: "https://old-instance",
pack_name: "test_pack", name: "test_pack",
as: "test_pack2" as: "test_pack2"
} }
) )
@ -242,7 +240,7 @@ test "checksum fail", %{admin_conn: admin_conn} do
%{ %{
method: :get, method: :get,
url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha/download_shared" url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha/archive"
} -> } ->
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
@ -251,9 +249,9 @@ test "checksum fail", %{admin_conn: admin_conn} do
end) end)
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/download_from", %{ |> post("/api/pleroma/emoji/packs/download", %{
instance_address: "https://example.com", url: "https://example.com",
pack_name: "pack_bad_sha", name: "pack_bad_sha",
as: "pack_bad_sha2" as: "pack_bad_sha2"
}) })
|> json_response(:internal_server_error) == %{ |> json_response(:internal_server_error) == %{
@ -275,23 +273,14 @@ test "other error", %{admin_conn: admin_conn} do
} -> } ->
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
body: %{"test_pack" => Pleroma.Emoji.Pack.load_pack("test_pack")} |> Jason.encode!() body: Pleroma.Emoji.Pack.load_pack("test_pack") |> Jason.encode!()
}
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/test_pack/download_shared"
} ->
%Tesla.Env{
status: 200,
body: File.read!("test/instance_static/emoji/test_pack/pack.json")
} }
end) end)
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/download_from", %{ |> post("/api/pleroma/emoji/packs/download", %{
instance_address: "https://example.com", url: "https://example.com",
pack_name: "test_pack", name: "test_pack",
as: "test_pack2" as: "test_pack2"
}) })
|> json_response(:internal_server_error) == %{ |> json_response(:internal_server_error) == %{
@ -301,7 +290,7 @@ test "other error", %{admin_conn: admin_conn} do
end end
end end
describe "updating pack metadata" do describe "PATCH /api/pleroma/emoji/packs/:name" do
setup do setup do
pack_file = "#{@emoji_path}/test_pack/pack.json" pack_file = "#{@emoji_path}/test_pack/pack.json"
original_content = File.read!(pack_file) original_content = File.read!(pack_file)
@ -322,12 +311,7 @@ test "other error", %{admin_conn: admin_conn} do
test "for a pack without a fallback source", ctx do test "for a pack without a fallback source", ctx do
assert ctx[:admin_conn] assert ctx[:admin_conn]
|> post( |> patch("/api/pleroma/emoji/packs/test_pack", %{"metadata" => ctx[:new_data]})
"/api/pleroma/emoji/packs/test_pack/update_metadata",
%{
"new_data" => ctx[:new_data]
}
)
|> json_response(200) == ctx[:new_data] |> json_response(200) == ctx[:new_data]
assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data] assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data]
@ -352,12 +336,7 @@ test "for a pack with a fallback source", ctx do
) )
assert ctx[:admin_conn] assert ctx[:admin_conn]
|> post( |> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data})
"/api/pleroma/emoji/packs/test_pack/update_metadata",
%{
"new_data" => new_data
}
)
|> json_response(200) == new_data_with_sha |> json_response(200) == new_data_with_sha
assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha
@ -376,19 +355,14 @@ test "when the fallback source doesn't have all the files", ctx do
new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack") new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
assert ctx[:admin_conn] assert ctx[:admin_conn]
|> post( |> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data})
"/api/pleroma/emoji/packs/test_pack/update_metadata",
%{
"new_data" => new_data
}
)
|> json_response(:bad_request) == %{ |> json_response(:bad_request) == %{
"error" => "The fallback archive does not have all files specified in pack.json" "error" => "The fallback archive does not have all files specified in pack.json"
} }
end end
end end
describe "POST /api/pleroma/emoji/packs/:pack_name/update_file" do describe "POST/PATCH/DELETE /api/pleroma/emoji/packs/:name/files" do
setup do setup do
pack_file = "#{@emoji_path}/test_pack/pack.json" pack_file = "#{@emoji_path}/test_pack/pack.json"
original_content = File.read!(pack_file) original_content = File.read!(pack_file)
@ -402,11 +376,10 @@ test "when the fallback source doesn't have all the files", ctx do
test "create shortcode exists", %{admin_conn: admin_conn} do test "create shortcode exists", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> post("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "add", shortcode: "blank",
"shortcode" => "blank", filename: "dir/blank.png",
"filename" => "dir/blank.png", file: %Plug.Upload{
"file" => %Plug.Upload{
filename: "blank.png", filename: "blank.png",
path: "#{@emoji_path}/test_pack/blank.png" path: "#{@emoji_path}/test_pack/blank.png"
} }
@ -420,11 +393,10 @@ test "don't rewrite old emoji", %{admin_conn: admin_conn} do
on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir/") end) on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir/") end)
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> post("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "add", shortcode: "blank2",
"shortcode" => "blank2", filename: "dir/blank.png",
"filename" => "dir/blank.png", file: %Plug.Upload{
"file" => %Plug.Upload{
filename: "blank.png", filename: "blank.png",
path: "#{@emoji_path}/test_pack/blank.png" path: "#{@emoji_path}/test_pack/blank.png"
} }
@ -434,11 +406,10 @@ test "don't rewrite old emoji", %{admin_conn: admin_conn} do
assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png") assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> patch("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "update", shortcode: "blank",
"shortcode" => "blank", new_shortcode: "blank2",
"new_shortcode" => "blank2", new_filename: "dir_2/blank_3.png"
"new_filename" => "dir_2/blank_3.png"
}) })
|> json_response(:conflict) == %{ |> json_response(:conflict) == %{
"error" => "error" =>
@ -450,11 +421,10 @@ test "rewrite old emoji with force option", %{admin_conn: admin_conn} do
on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir_2/") end) on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir_2/") end)
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> post("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "add", shortcode: "blank2",
"shortcode" => "blank2", filename: "dir/blank.png",
"filename" => "dir/blank.png", file: %Plug.Upload{
"file" => %Plug.Upload{
filename: "blank.png", filename: "blank.png",
path: "#{@emoji_path}/test_pack/blank.png" path: "#{@emoji_path}/test_pack/blank.png"
} }
@ -464,12 +434,11 @@ test "rewrite old emoji with force option", %{admin_conn: admin_conn} do
assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png") assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> patch("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "update", shortcode: "blank2",
"shortcode" => "blank2", new_shortcode: "blank3",
"new_shortcode" => "blank3", new_filename: "dir_2/blank_3.png",
"new_filename" => "dir_2/blank_3.png", force: true
"force" => true
}) })
|> json_response(200) == %{ |> json_response(200) == %{
"blank" => "blank.png", "blank" => "blank.png",
@ -481,11 +450,10 @@ test "rewrite old emoji with force option", %{admin_conn: admin_conn} do
test "with empty filename", %{admin_conn: admin_conn} do test "with empty filename", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> post("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "add", shortcode: "blank2",
"shortcode" => "blank2", filename: "",
"filename" => "", file: %Plug.Upload{
"file" => %Plug.Upload{
filename: "blank.png", filename: "blank.png",
path: "#{@emoji_path}/test_pack/blank.png" path: "#{@emoji_path}/test_pack/blank.png"
} }
@ -497,11 +465,10 @@ test "with empty filename", %{admin_conn: admin_conn} do
test "add file with not loaded pack", %{admin_conn: admin_conn} do test "add file with not loaded pack", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/not_loaded/update_file", %{ |> post("/api/pleroma/emoji/packs/not_loaded/files", %{
"action" => "add", shortcode: "blank2",
"shortcode" => "blank2", filename: "dir/blank.png",
"filename" => "dir/blank.png", file: %Plug.Upload{
"file" => %Plug.Upload{
filename: "blank.png", filename: "blank.png",
path: "#{@emoji_path}/test_pack/blank.png" path: "#{@emoji_path}/test_pack/blank.png"
} }
@ -513,19 +480,13 @@ test "add file with not loaded pack", %{admin_conn: admin_conn} do
test "remove file with not loaded pack", %{admin_conn: admin_conn} do test "remove file with not loaded pack", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/not_loaded/update_file", %{ |> delete("/api/pleroma/emoji/packs/not_loaded/files", %{shortcode: "blank3"})
"action" => "remove",
"shortcode" => "blank3"
})
|> json_response(:bad_request) == %{"error" => "pack \"not_loaded\" is not found"} |> json_response(:bad_request) == %{"error" => "pack \"not_loaded\" is not found"}
end end
test "remove file with empty shortcode", %{admin_conn: admin_conn} do test "remove file with empty shortcode", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/not_loaded/update_file", %{ |> delete("/api/pleroma/emoji/packs/not_loaded/files", %{shortcode: ""})
"action" => "remove",
"shortcode" => ""
})
|> json_response(:bad_request) == %{ |> json_response(:bad_request) == %{
"error" => "pack name or shortcode cannot be empty" "error" => "pack name or shortcode cannot be empty"
} }
@ -533,22 +494,20 @@ test "remove file with empty shortcode", %{admin_conn: admin_conn} do
test "update file with not loaded pack", %{admin_conn: admin_conn} do test "update file with not loaded pack", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/not_loaded/update_file", %{ |> patch("/api/pleroma/emoji/packs/not_loaded/files", %{
"action" => "update", shortcode: "blank4",
"shortcode" => "blank4", new_shortcode: "blank3",
"new_shortcode" => "blank3", new_filename: "dir_2/blank_3.png"
"new_filename" => "dir_2/blank_3.png"
}) })
|> json_response(:bad_request) == %{"error" => "pack \"not_loaded\" is not found"} |> json_response(:bad_request) == %{"error" => "pack \"not_loaded\" is not found"}
end end
test "new with shortcode as file with update", %{admin_conn: admin_conn} do test "new with shortcode as file with update", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> post("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "add", shortcode: "blank4",
"shortcode" => "blank4", filename: "dir/blank.png",
"filename" => "dir/blank.png", file: %Plug.Upload{
"file" => %Plug.Upload{
filename: "blank.png", filename: "blank.png",
path: "#{@emoji_path}/test_pack/blank.png" path: "#{@emoji_path}/test_pack/blank.png"
} }
@ -558,11 +517,10 @@ test "new with shortcode as file with update", %{admin_conn: admin_conn} do
assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png") assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> patch("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "update", shortcode: "blank4",
"shortcode" => "blank4", new_shortcode: "blank3",
"new_shortcode" => "blank3", new_filename: "dir_2/blank_3.png"
"new_filename" => "dir_2/blank_3.png"
}) })
|> json_response(200) == %{"blank3" => "dir_2/blank_3.png", "blank" => "blank.png"} |> json_response(200) == %{"blank3" => "dir_2/blank_3.png", "blank" => "blank.png"}
@ -570,10 +528,7 @@ test "new with shortcode as file with update", %{admin_conn: admin_conn} do
assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png") assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png")
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> delete("/api/pleroma/emoji/packs/test_pack/files", %{shortcode: "blank3"})
"action" => "remove",
"shortcode" => "blank3"
})
|> json_response(200) == %{"blank" => "blank.png"} |> json_response(200) == %{"blank" => "blank.png"}
refute File.exists?("#{@emoji_path}/test_pack/dir_2/") refute File.exists?("#{@emoji_path}/test_pack/dir_2/")
@ -591,10 +546,9 @@ test "new with shortcode from url", %{admin_conn: admin_conn} do
end) end)
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> post("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "add", shortcode: "blank_url",
"shortcode" => "blank_url", file: "https://test-blank/blank_url.png"
"file" => "https://test-blank/blank_url.png"
}) })
|> json_response(200) == %{ |> json_response(200) == %{
"blank_url" => "blank_url.png", "blank_url" => "blank_url.png",
@ -610,9 +564,8 @@ test "new without shortcode", %{admin_conn: admin_conn} do
on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/shortcode.png") end) on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/shortcode.png") end)
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> post("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "add", file: %Plug.Upload{
"file" => %Plug.Upload{
filename: "shortcode.png", filename: "shortcode.png",
path: "#{Pleroma.Config.get([:instance, :static_dir])}/add/shortcode.png" path: "#{Pleroma.Config.get([:instance, :static_dir])}/add/shortcode.png"
} }
@ -622,51 +575,36 @@ test "new without shortcode", %{admin_conn: admin_conn} do
test "remove non existing shortcode in pack.json", %{admin_conn: admin_conn} do test "remove non existing shortcode in pack.json", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> delete("/api/pleroma/emoji/packs/test_pack/files", %{shortcode: "blank2"})
"action" => "remove",
"shortcode" => "blank2"
})
|> json_response(:bad_request) == %{"error" => "Emoji \"blank2\" does not exist"} |> json_response(:bad_request) == %{"error" => "Emoji \"blank2\" does not exist"}
end end
test "update non existing emoji", %{admin_conn: admin_conn} do test "update non existing emoji", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> patch("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "update", shortcode: "blank2",
"shortcode" => "blank2", new_shortcode: "blank3",
"new_shortcode" => "blank3", new_filename: "dir_2/blank_3.png"
"new_filename" => "dir_2/blank_3.png"
}) })
|> json_response(:bad_request) == %{"error" => "Emoji \"blank2\" does not exist"} |> json_response(:bad_request) == %{"error" => "Emoji \"blank2\" does not exist"}
end end
test "update with empty shortcode", %{admin_conn: admin_conn} do test "update with empty shortcode", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{ |> patch("/api/pleroma/emoji/packs/test_pack/files", %{
"action" => "update", shortcode: "blank",
"shortcode" => "blank", new_filename: "dir_2/blank_3.png"
"new_filename" => "dir_2/blank_3.png"
}) })
|> json_response(:bad_request) == %{ |> json_response(:bad_request) == %{
"error" => "new_shortcode or new_filename cannot be empty" "error" => "new_shortcode or new_filename cannot be empty"
} }
end end
test "undefined action", %{admin_conn: admin_conn} do
assert admin_conn
|> post("/api/pleroma/emoji/packs/test_pack/update_file", %{
"action" => "undefined"
})
|> json_response(:bad_request) == %{
"error" => "Unknown action: undefined"
}
end
end end
describe "PUT /api/pleroma/emoji/packs/:name" do describe "POST/DELETE /api/pleroma/emoji/packs/:name" do
test "creating and deleting a pack", %{admin_conn: admin_conn} do test "creating and deleting a pack", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> put("/api/pleroma/emoji/packs/test_created") |> post("/api/pleroma/emoji/packs/test_created")
|> json_response(200) == "ok" |> json_response(200) == "ok"
assert File.exists?("#{@emoji_path}/test_created/pack.json") assert File.exists?("#{@emoji_path}/test_created/pack.json")
@ -690,7 +628,7 @@ test "if pack exists", %{admin_conn: admin_conn} do
File.write!(Path.join(path, "pack.json"), pack_file) File.write!(Path.join(path, "pack.json"), pack_file)
assert admin_conn assert admin_conn
|> put("/api/pleroma/emoji/packs/test_created") |> post("/api/pleroma/emoji/packs/test_created")
|> json_response(:conflict) == %{ |> json_response(:conflict) == %{
"error" => "A pack named \"test_created\" already exists" "error" => "A pack named \"test_created\" already exists"
} }
@ -700,7 +638,7 @@ test "if pack exists", %{admin_conn: admin_conn} do
test "with empty name", %{admin_conn: admin_conn} do test "with empty name", %{admin_conn: admin_conn} do
assert admin_conn assert admin_conn
|> put("/api/pleroma/emoji/packs/ ") |> post("/api/pleroma/emoji/packs/ ")
|> json_response(:bad_request) == %{"error" => "pack name cannot be empty"} |> json_response(:bad_request) == %{"error" => "pack name cannot be empty"}
end end
end end
@ -728,7 +666,7 @@ test "filesystem import", %{admin_conn: admin_conn, conn: conn} do
refute Map.has_key?(resp, "test_pack_for_import") refute Map.has_key?(resp, "test_pack_for_import")
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/import_from_fs") |> get("/api/pleroma/emoji/packs/import")
|> json_response(200) == ["test_pack_for_import"] |> json_response(200) == ["test_pack_for_import"]
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200) resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200)
@ -747,7 +685,7 @@ test "filesystem import", %{admin_conn: admin_conn, conn: conn} do
File.write!("#{@emoji_path}/test_pack_for_import/emoji.txt", emoji_txt_content) File.write!("#{@emoji_path}/test_pack_for_import/emoji.txt", emoji_txt_content)
assert admin_conn assert admin_conn
|> post("/api/pleroma/emoji/packs/import_from_fs") |> get("/api/pleroma/emoji/packs/import")
|> json_response(200) == ["test_pack_for_import"] |> json_response(200) == ["test_pack_for_import"]
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200) resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200)