462 lines
14 KiB
Elixir
462 lines
14 KiB
Elixir
# Pleroma: A lightweight social networking server
|
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
|
|
use Pleroma.Web.ConnCase
|
|
|
|
import Tesla.Mock
|
|
import Pleroma.Factory
|
|
|
|
@emoji_dir_path Path.join(
|
|
Pleroma.Config.get!([:instance, :static_dir]),
|
|
"emoji"
|
|
)
|
|
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
|
|
|
|
test "shared & non-shared pack information in list_packs is ok" do
|
|
conn = build_conn()
|
|
resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
|
|
|
|
assert Map.has_key?(resp, "test_pack")
|
|
|
|
pack = resp["test_pack"]
|
|
|
|
assert Map.has_key?(pack["pack"], "download-sha256")
|
|
assert pack["pack"]["can-download"]
|
|
|
|
assert pack["files"] == %{"blank" => "blank.png"}
|
|
|
|
# Non-shared pack
|
|
|
|
assert Map.has_key?(resp, "test_pack_nonshared")
|
|
|
|
pack = resp["test_pack_nonshared"]
|
|
|
|
refute pack["pack"]["shared"]
|
|
refute pack["pack"]["can-download"]
|
|
end
|
|
|
|
test "listing remote packs" do
|
|
conn = build_conn()
|
|
|
|
resp =
|
|
build_conn()
|
|
|> get(emoji_api_path(conn, :list_packs))
|
|
|> json_response(200)
|
|
|
|
mock(fn
|
|
%{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
|
|
json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
|
|
|
|
%{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
|
|
json(%{metadata: %{features: ["shareable_emoji_packs"]}})
|
|
|
|
%{method: :get, url: "https://example.com/api/pleroma/emoji/packs"} ->
|
|
json(resp)
|
|
end)
|
|
|
|
assert conn
|
|
|> post(emoji_api_path(conn, :list_from), %{instance_address: "https://example.com"})
|
|
|> json_response(200) == resp
|
|
end
|
|
|
|
test "downloading a shared pack from download_shared" do
|
|
conn = build_conn()
|
|
|
|
resp =
|
|
conn
|
|
|> get(emoji_api_path(conn, :download_shared, "test_pack"))
|
|
|> response(200)
|
|
|
|
{:ok, arch} = :zip.unzip(resp, [:memory])
|
|
|
|
assert Enum.find(arch, fn {n, _} -> n == 'pack.json' end)
|
|
assert Enum.find(arch, fn {n, _} -> n == 'blank.png' end)
|
|
end
|
|
|
|
test "downloading shared & unshared packs from another instance, deleting them" do
|
|
on_exit(fn ->
|
|
File.rm_rf!("#{@emoji_dir_path}/test_pack2")
|
|
File.rm_rf!("#{@emoji_dir_path}/test_pack_nonshared2")
|
|
end)
|
|
|
|
mock(fn
|
|
%{method: :get, url: "https://old-instance/.well-known/nodeinfo"} ->
|
|
json(%{links: [%{href: "https://old-instance/nodeinfo/2.1.json"}]})
|
|
|
|
%{method: :get, url: "https://old-instance/nodeinfo/2.1.json"} ->
|
|
json(%{metadata: %{features: []}})
|
|
|
|
%{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
|
|
json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
|
|
|
|
%{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
|
|
json(%{metadata: %{features: ["shareable_emoji_packs"]}})
|
|
|
|
%{
|
|
method: :get,
|
|
url: "https://example.com/api/pleroma/emoji/packs/list"
|
|
} ->
|
|
conn = build_conn()
|
|
|
|
conn
|
|
|> get(emoji_api_path(conn, :list_packs))
|
|
|> json_response(200)
|
|
|> json()
|
|
|
|
%{
|
|
method: :get,
|
|
url: "https://example.com/api/pleroma/emoji/packs/download_shared/test_pack"
|
|
} ->
|
|
conn = build_conn()
|
|
|
|
conn
|
|
|> get(emoji_api_path(conn, :download_shared, "test_pack"))
|
|
|> response(200)
|
|
|> text()
|
|
|
|
%{
|
|
method: :get,
|
|
url: "https://nonshared-pack"
|
|
} ->
|
|
text(File.read!("#{@emoji_dir_path}/test_pack_nonshared/nonshared.zip"))
|
|
end)
|
|
|
|
admin = insert(:user, is_admin: true)
|
|
|
|
conn =
|
|
build_conn()
|
|
|> assign(:user, admin)
|
|
|> assign(:token, insert(:oauth_admin_token, user: admin, scopes: ["admin:write"]))
|
|
|
|
assert (conn
|
|
|> put_req_header("content-type", "application/json")
|
|
|> post(
|
|
emoji_api_path(
|
|
conn,
|
|
:save_from
|
|
),
|
|
%{
|
|
instance_address: "https://old-instance",
|
|
pack_name: "test_pack",
|
|
as: "test_pack2"
|
|
}
|
|
|> Jason.encode!()
|
|
)
|
|
|> json_response(500))["error"] =~ "does not support"
|
|
|
|
assert conn
|
|
|> put_req_header("content-type", "application/json")
|
|
|> post(
|
|
emoji_api_path(
|
|
conn,
|
|
:save_from
|
|
),
|
|
%{
|
|
instance_address: "https://example.com",
|
|
pack_name: "test_pack",
|
|
as: "test_pack2"
|
|
}
|
|
|> Jason.encode!()
|
|
)
|
|
|> json_response(200) == "ok"
|
|
|
|
assert File.exists?("#{@emoji_dir_path}/test_pack2/pack.json")
|
|
assert File.exists?("#{@emoji_dir_path}/test_pack2/blank.png")
|
|
|
|
assert conn
|
|
|> delete(emoji_api_path(conn, :delete, "test_pack2"))
|
|
|> json_response(200) == "ok"
|
|
|
|
refute File.exists?("#{@emoji_dir_path}/test_pack2")
|
|
|
|
# non-shared, downloaded from the fallback URL
|
|
|
|
assert conn
|
|
|> put_req_header("content-type", "application/json")
|
|
|> post(
|
|
emoji_api_path(
|
|
conn,
|
|
:save_from
|
|
),
|
|
%{
|
|
instance_address: "https://example.com",
|
|
pack_name: "test_pack_nonshared",
|
|
as: "test_pack_nonshared2"
|
|
}
|
|
|> Jason.encode!()
|
|
)
|
|
|> json_response(200) == "ok"
|
|
|
|
assert File.exists?("#{@emoji_dir_path}/test_pack_nonshared2/pack.json")
|
|
assert File.exists?("#{@emoji_dir_path}/test_pack_nonshared2/blank.png")
|
|
|
|
assert conn
|
|
|> delete(emoji_api_path(conn, :delete, "test_pack_nonshared2"))
|
|
|> json_response(200) == "ok"
|
|
|
|
refute File.exists?("#{@emoji_dir_path}/test_pack_nonshared2")
|
|
end
|
|
|
|
describe "updating pack metadata" do
|
|
setup do
|
|
pack_file = "#{@emoji_dir_path}/test_pack/pack.json"
|
|
original_content = File.read!(pack_file)
|
|
|
|
on_exit(fn ->
|
|
File.write!(pack_file, original_content)
|
|
end)
|
|
|
|
admin = insert(:user, is_admin: true)
|
|
%{conn: conn} = oauth_access(["admin:write"], user: admin)
|
|
|
|
{:ok,
|
|
admin: admin,
|
|
conn: conn,
|
|
pack_file: pack_file,
|
|
new_data: %{
|
|
"license" => "Test license changed",
|
|
"homepage" => "https://pleroma.social",
|
|
"description" => "Test description",
|
|
"share-files" => false
|
|
}}
|
|
end
|
|
|
|
test "for a pack without a fallback source", ctx do
|
|
conn = ctx[:conn]
|
|
|
|
assert conn
|
|
|> post(
|
|
emoji_api_path(conn, :update_metadata, "test_pack"),
|
|
%{
|
|
"new_data" => ctx[:new_data]
|
|
}
|
|
)
|
|
|> json_response(200) == ctx[:new_data]
|
|
|
|
assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data]
|
|
end
|
|
|
|
test "for a pack with a fallback source", ctx do
|
|
mock(fn
|
|
%{
|
|
method: :get,
|
|
url: "https://nonshared-pack"
|
|
} ->
|
|
text(File.read!("#{@emoji_dir_path}/test_pack_nonshared/nonshared.zip"))
|
|
end)
|
|
|
|
new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
|
|
|
|
new_data_with_sha =
|
|
Map.put(
|
|
new_data,
|
|
"fallback-src-sha256",
|
|
"74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF"
|
|
)
|
|
|
|
conn = ctx[:conn]
|
|
|
|
assert conn
|
|
|> post(
|
|
emoji_api_path(conn, :update_metadata, "test_pack"),
|
|
%{
|
|
"new_data" => new_data
|
|
}
|
|
)
|
|
|> json_response(200) == new_data_with_sha
|
|
|
|
assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha
|
|
end
|
|
|
|
test "when the fallback source doesn't have all the files", ctx do
|
|
mock(fn
|
|
%{
|
|
method: :get,
|
|
url: "https://nonshared-pack"
|
|
} ->
|
|
{:ok, {'empty.zip', empty_arch}} = :zip.zip('empty.zip', [], [:memory])
|
|
text(empty_arch)
|
|
end)
|
|
|
|
new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
|
|
|
|
conn = ctx[:conn]
|
|
|
|
assert (conn
|
|
|> post(
|
|
emoji_api_path(conn, :update_metadata, "test_pack"),
|
|
%{
|
|
"new_data" => new_data
|
|
}
|
|
)
|
|
|> json_response(:bad_request))["error"] =~ "does not have all"
|
|
end
|
|
end
|
|
|
|
test "updating pack files" do
|
|
pack_file = "#{@emoji_dir_path}/test_pack/pack.json"
|
|
original_content = File.read!(pack_file)
|
|
|
|
on_exit(fn ->
|
|
File.write!(pack_file, original_content)
|
|
|
|
File.rm_rf!("#{@emoji_dir_path}/test_pack/blank_url.png")
|
|
File.rm_rf!("#{@emoji_dir_path}/test_pack/dir")
|
|
File.rm_rf!("#{@emoji_dir_path}/test_pack/dir_2")
|
|
end)
|
|
|
|
admin = insert(:user, is_admin: true)
|
|
%{conn: conn} = oauth_access(["admin:write"], user: admin)
|
|
|
|
same_name = %{
|
|
"action" => "add",
|
|
"shortcode" => "blank",
|
|
"filename" => "dir/blank.png",
|
|
"file" => %Plug.Upload{
|
|
filename: "blank.png",
|
|
path: "#{@emoji_dir_path}/test_pack/blank.png"
|
|
}
|
|
}
|
|
|
|
different_name = %{same_name | "shortcode" => "blank_2"}
|
|
|
|
assert (conn
|
|
|> post(emoji_api_path(conn, :update_file, "test_pack"), same_name)
|
|
|> json_response(:conflict))["error"] =~ "already exists"
|
|
|
|
assert conn
|
|
|> post(emoji_api_path(conn, :update_file, "test_pack"), different_name)
|
|
|> json_response(200) == %{"blank" => "blank.png", "blank_2" => "dir/blank.png"}
|
|
|
|
assert File.exists?("#{@emoji_dir_path}/test_pack/dir/blank.png")
|
|
|
|
assert conn
|
|
|> post(emoji_api_path(conn, :update_file, "test_pack"), %{
|
|
"action" => "update",
|
|
"shortcode" => "blank_2",
|
|
"new_shortcode" => "blank_3",
|
|
"new_filename" => "dir_2/blank_3.png"
|
|
})
|
|
|> json_response(200) == %{"blank" => "blank.png", "blank_3" => "dir_2/blank_3.png"}
|
|
|
|
refute File.exists?("#{@emoji_dir_path}/test_pack/dir/")
|
|
assert File.exists?("#{@emoji_dir_path}/test_pack/dir_2/blank_3.png")
|
|
|
|
assert conn
|
|
|> post(emoji_api_path(conn, :update_file, "test_pack"), %{
|
|
"action" => "remove",
|
|
"shortcode" => "blank_3"
|
|
})
|
|
|> json_response(200) == %{"blank" => "blank.png"}
|
|
|
|
refute File.exists?("#{@emoji_dir_path}/test_pack/dir_2/")
|
|
|
|
mock(fn
|
|
%{
|
|
method: :get,
|
|
url: "https://test-blank/blank_url.png"
|
|
} ->
|
|
text(File.read!("#{@emoji_dir_path}/test_pack/blank.png"))
|
|
end)
|
|
|
|
# The name should be inferred from the URL ending
|
|
from_url = %{
|
|
"action" => "add",
|
|
"shortcode" => "blank_url",
|
|
"file" => "https://test-blank/blank_url.png"
|
|
}
|
|
|
|
assert conn
|
|
|> post(emoji_api_path(conn, :update_file, "test_pack"), from_url)
|
|
|> json_response(200) == %{
|
|
"blank" => "blank.png",
|
|
"blank_url" => "blank_url.png"
|
|
}
|
|
|
|
assert File.exists?("#{@emoji_dir_path}/test_pack/blank_url.png")
|
|
|
|
assert conn
|
|
|> post(emoji_api_path(conn, :update_file, "test_pack"), %{
|
|
"action" => "remove",
|
|
"shortcode" => "blank_url"
|
|
})
|
|
|> json_response(200) == %{"blank" => "blank.png"}
|
|
|
|
refute File.exists?("#{@emoji_dir_path}/test_pack/blank_url.png")
|
|
end
|
|
|
|
test "creating and deleting a pack" do
|
|
on_exit(fn ->
|
|
File.rm_rf!("#{@emoji_dir_path}/test_created")
|
|
end)
|
|
|
|
admin = insert(:user, is_admin: true)
|
|
%{conn: conn} = oauth_access(["admin:write"], user: admin)
|
|
|
|
assert conn
|
|
|> put_req_header("content-type", "application/json")
|
|
|> put(
|
|
emoji_api_path(
|
|
conn,
|
|
:create,
|
|
"test_created"
|
|
)
|
|
)
|
|
|> json_response(200) == "ok"
|
|
|
|
assert File.exists?("#{@emoji_dir_path}/test_created/pack.json")
|
|
|
|
assert Jason.decode!(File.read!("#{@emoji_dir_path}/test_created/pack.json")) == %{
|
|
"pack" => %{},
|
|
"files" => %{}
|
|
}
|
|
|
|
assert conn
|
|
|> delete(emoji_api_path(conn, :delete, "test_created"))
|
|
|> json_response(200) == "ok"
|
|
|
|
refute File.exists?("#{@emoji_dir_path}/test_created/pack.json")
|
|
end
|
|
|
|
test "filesystem import" do
|
|
on_exit(fn ->
|
|
File.rm!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt")
|
|
File.rm!("#{@emoji_dir_path}/test_pack_for_import/pack.json")
|
|
end)
|
|
|
|
conn = build_conn()
|
|
resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
|
|
|
|
refute Map.has_key?(resp, "test_pack_for_import")
|
|
|
|
admin = insert(:user, is_admin: true)
|
|
%{conn: conn} = oauth_access(["admin:write"], user: admin)
|
|
|
|
assert conn
|
|
|> post(emoji_api_path(conn, :import_from_fs))
|
|
|> json_response(200) == ["test_pack_for_import"]
|
|
|
|
resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
|
|
assert resp["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}
|
|
|
|
File.rm!("#{@emoji_dir_path}/test_pack_for_import/pack.json")
|
|
refute File.exists?("#{@emoji_dir_path}/test_pack_for_import/pack.json")
|
|
|
|
emoji_txt_content = "blank, blank.png, Fun\n\nblank2, blank.png"
|
|
|
|
File.write!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt", emoji_txt_content)
|
|
|
|
assert conn
|
|
|> post(emoji_api_path(conn, :import_from_fs))
|
|
|> json_response(200) == ["test_pack_for_import"]
|
|
|
|
resp = build_conn() |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
|
|
|
|
assert resp["test_pack_for_import"]["files"] == %{
|
|
"blank" => "blank.png",
|
|
"blank2" => "blank.png"
|
|
}
|
|
end
|
|
end
|