Compare commits

...

4 commits

Author SHA1 Message Date
32fbd2e4e3 fix all tests
Some checks failed
ci/woodpecker/push/lint Pipeline failed
ci/woodpecker/push/test unknown status
ci/woodpecker/push/release unknown status
2022-06-11 16:14:22 +01:00
c3ed86cd1e fix emoji controller tests 2022-06-11 14:21:50 +01:00
142646426e fix emoji tests 2022-06-11 14:08:54 +01:00
71f4281850 fix quoting of custom emoji
Fixes #3
2022-06-11 14:08:13 +01:00
31 changed files with 288 additions and 80 deletions

View file

@ -152,12 +152,12 @@
config :logger, truncate: 65536 config :logger, truncate: 65536
config :logger, :console, config :logger, :console,
level: :debug, level: :info,
format: "\n$time $metadata[$level] $message\n", format: "\n$time $metadata[$level] $message\n",
metadata: [:request_id] metadata: [:request_id]
config :logger, :ex_syslogger, config :logger, :ex_syslogger,
level: :debug, level: :info,
ident: "pleroma", ident: "pleroma",
format: "$metadata[$level] $message", format: "$metadata[$level] $message",
metadata: [:request_id] metadata: [:request_id]

View file

@ -48,7 +48,8 @@
database: "pleroma_test", database: "pleroma_test",
hostname: System.get_env("DB_HOST") || "localhost", hostname: System.get_env("DB_HOST") || "localhost",
pool: Ecto.Adapters.SQL.Sandbox, pool: Ecto.Adapters.SQL.Sandbox,
pool_size: 50 pool_size: 50,
queue_target: 5000
config :pleroma, :dangerzone, override_repo_pool_size: true config :pleroma, :dangerzone, override_repo_pool_size: true

View file

@ -134,7 +134,7 @@ def bulk_post(data, :activities) do
Logger.error("Could not bulk put activity: #{err}") Logger.error("Could not bulk put activity: #{err}")
:skipped :skipped
{:ok, %{body: body}} -> {:ok, %{body: _}} ->
:skipped :skipped
end end
end end
@ -164,7 +164,7 @@ def bulk_post(data, :users) do
Logger.error("Could not bulk put users: #{err}") Logger.error("Could not bulk put users: #{err}")
:skipped :skipped
{:ok, %{body: body}} -> {:ok, %{body: _}} ->
:skipped :skipped
end end
end end
@ -193,7 +193,7 @@ def bulk_post(data, :hashtags) when is_list(data) do
Logger.error("Could not bulk put hashtags: #{err}") Logger.error("Could not bulk put hashtags: #{err}")
:skipped :skipped
{:ok, %{body: body}} -> {:ok, %{body: _}} ->
:skipped :skipped
end end
end end

View file

@ -146,4 +146,23 @@ def is_unicode_emoji?(unquote(emoji)), do: true
end end
def is_unicode_emoji?(_), do: false def is_unicode_emoji?(_), do: false
def stripped_name(name) when is_binary(name) do
name
|> String.replace_leading(":", "")
|> String.replace_trailing(":", "")
end
def stripped_name(name), do: name
def maybe_quote(name) when is_binary(name) do
if is_unicode_emoji?(name) do
name
else
":#{name}:"
end
end
def maybe_quote(name), do: name
end end

View file

@ -69,7 +69,6 @@ def request(method, url, body, headers, options) when is_binary(url) do
adapter = Application.get_env(:tesla, :adapter) adapter = Application.get_env(:tesla, :adapter)
client = Tesla.client(adapter_middlewares(adapter), adapter) client = Tesla.client(adapter_middlewares(adapter), adapter)
maybe_limit( maybe_limit(
fn -> fn ->
request(client, request) request(client, request)

View file

@ -14,6 +14,7 @@ defmodule Pleroma.Search.Builtin do
def search(_conn, %{q: query} = params, options) do def search(_conn, %{q: query} = params, options) do
version = Keyword.get(options, :version) version = Keyword.get(options, :version)
timeout = Keyword.get(Repo.config(), :timeout, 15_000) timeout = Keyword.get(Repo.config(), :timeout, 15_000)
query = String.trim(query)
default_values = %{"statuses" => [], "accounts" => [], "hashtags" => []} default_values = %{"statuses" => [], "accounts" => [], "hashtags" => []}
default_values default_values

View file

@ -1321,7 +1321,7 @@ def fetch_activities_query(recipients, opts \\ %{}) do
fetch_activities_query_ap_ids_ops(opts) fetch_activities_query_ap_ids_ops(opts)
config = %{ config = %{
skip_thread_containment: true skip_thread_containment: Config.get([:instance, :skip_thread_containment])
} }
query = query =

View file

@ -64,25 +64,28 @@ def emoji_react(actor, object, emoji) do
|> Map.put("content", emoji) |> Map.put("content", emoji)
|> Map.put("type", "EmojiReact") |> Map.put("type", "EmojiReact")
else else
emojo = Emoji.get(emoji) with %{} = emojo <- Emoji.get(emoji) do
path = emojo |> Map.get(:file) path = emojo |> Map.get(:file)
url = "#{Endpoint.url()}#{path}" url = "#{Endpoint.url()}#{path}"
data data
|> Map.put("content", emoji) |> Map.put("content", emoji)
|> Map.put("type", "EmojiReact") |> Map.put("type", "EmojiReact")
|> Map.put("tag", [ |> Map.put("tag", [
%{}
|> Map.put("id", url)
|> Map.put("type", "Emoji")
|> Map.put("name", emojo.code)
|> Map.put(
"icon",
%{} %{}
|> Map.put("type", "Image") |> Map.put("id", url)
|> Map.put("url", url) |> Map.put("type", "Emoji")
) |> Map.put("name", emojo.code)
]) |> Map.put(
"icon",
%{}
|> Map.put("type", "Image")
|> Map.put("url", url)
)
])
else
_ -> {:error, "Emoji does not exist"}
end
end end
{:ok, data, meta} {:ok, data, meta}

View file

@ -71,7 +71,7 @@ defp fix_replies(%{"replies" => %{"first" => first}} = data) do
Fetcher.fetch_and_contain_remote_object_from_id(first) do Fetcher.fetch_and_contain_remote_object_from_id(first) do
Map.put(data, "replies", replies) Map.put(data, "replies", replies)
else else
{:error, e} -> {:error, _} ->
Logger.error("Could not fetch replies for #{first}") Logger.error("Could not fetch replies for #{first}")
Map.put(data, "replies", []) Map.put(data, "replies", [])
end end

View file

@ -5,6 +5,7 @@
defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
use Ecto.Schema use Ecto.Schema
alias Pleroma.Emoji
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
@ -62,19 +63,24 @@ defp fix(data) do
Map.put(data, "tag", []) Map.put(data, "tag", [])
end end
with %Object{} = object <- Object.normalize(data["object"]) do case Object.normalize(data["object"]) do
data %Object{} = object ->
|> CommonFixes.fix_activity_context(object) data
|> CommonFixes.fix_object_action_recipients(object) |> CommonFixes.fix_activity_context(object)
else |> CommonFixes.fix_object_action_recipients(object)
_ -> data
_ ->
data
end end
end end
defp matches_shortcode?(nil), do: false
defp matches_shortcode?(s), do: Regex.match?(@emoji_regex, s)
defp validate_emoji(cng) do defp validate_emoji(cng) do
content = get_field(cng, :content) content = get_field(cng, :content)
if Pleroma.Emoji.is_unicode_emoji?(content) || Regex.match?(@emoji_regex, content) do if Emoji.is_unicode_emoji?(content) || matches_shortcode?(content) do
cng cng
else else
cng cng
@ -82,6 +88,24 @@ defp validate_emoji(cng) do
end end
end end
defp maybe_validate_tag_presence(cng) do
content = get_field(cng, :content)
if Emoji.is_unicode_emoji?(content) do
cng
else
tag = get_field(cng, :tag)
emoji_name = Emoji.stripped_name(content)
case tag do
[%{name: ^emoji_name, type: "Emoji", icon: %{url: _}}] ->
cng
_ ->
cng
|> add_error(:tag, "does not contain an Emoji tag")
end
end
end
defp validate_data(data_cng) do defp validate_data(data_cng) do
data_cng data_cng
|> validate_inclusion(:type, ["EmojiReact"]) |> validate_inclusion(:type, ["EmojiReact"])
@ -89,5 +113,6 @@ defp validate_data(data_cng) do
|> validate_actor_presence() |> validate_actor_presence()
|> validate_object_presence() |> validate_object_presence()
|> validate_emoji() |> validate_emoji()
|> maybe_validate_tag_presence()
end end
end end

View file

@ -545,12 +545,7 @@ def fetch_latest_undo(%User{ap_id: ap_id}) do
def get_latest_reaction(internal_activity_id, %{ap_id: ap_id}, emoji) do def get_latest_reaction(internal_activity_id, %{ap_id: ap_id}, emoji) do
%{data: %{"object" => object_ap_id}} = Activity.get_by_id(internal_activity_id) %{data: %{"object" => object_ap_id}} = Activity.get_by_id(internal_activity_id)
emoji = emoji = Pleroma.Emoji.maybe_quote(emoji)
if String.starts_with?(emoji, ":") do
emoji
else
":#{emoji}:"
end
"EmojiReact" "EmojiReact"
|> Activity.Queries.by_type() |> Activity.Queries.by_type()

View file

@ -271,7 +271,7 @@ def unreact_with_emoji(id, user, emoji) do
{:ok, activity, _} <- Pipeline.common_pipeline(undo, local: true) do {:ok, activity, _} <- Pipeline.common_pipeline(undo, local: true) do
{:ok, activity} {:ok, activity}
else else
_ -> e ->
{:error, dgettext("errors", "Could not remove reaction emoji")} {:error, dgettext("errors", "Could not remove reaction emoji")}
end end
end end

View file

@ -61,13 +61,14 @@ def filter_allowed_users(reactions, user, with_muted) do
|> Stream.map(fn |> Stream.map(fn
[emoji, users, url] when is_list(users) -> filter_emoji.(emoji, users, url) [emoji, users, url] when is_list(users) -> filter_emoji.(emoji, users, url)
{emoji, users, url} when is_list(users) -> filter_emoji.(emoji, users, url) {emoji, users, url} when is_list(users) -> filter_emoji.(emoji, users, url)
{emoji, users} when is_list(users) -> filter_emoji.(emoji, users, nil)
_ -> nil _ -> nil
end) end)
|> Stream.reject(&is_nil/1) |> Stream.reject(&is_nil/1)
end end
defp filter(reactions, %{emoji: emoji}) when is_binary(emoji) do defp filter(reactions, %{emoji: emoji}) when is_binary(emoji) do
Enum.filter(reactions, fn [e, _] -> e == emoji end) Enum.filter(reactions, fn [e, _, _] -> e == emoji end)
end end
defp filter(reactions, _), do: reactions defp filter(reactions, _), do: reactions

View file

@ -132,7 +132,7 @@ defp deps do
{:calendar, "~> 1.0"}, {:calendar, "~> 1.0"},
{:cachex, "~> 3.2"}, {:cachex, "~> 3.2"},
{:poison, "~> 3.0", override: true}, {:poison, "~> 3.0", override: true},
{:tesla, "~> 1.4.0", override: true}, {:tesla, "~> 1.4.4", override: true},
{:castore, "~> 0.1"}, {:castore, "~> 0.1"},
{:cowlib, "~> 2.9", override: true}, {:cowlib, "~> 2.9", override: true},
{:gun, "~> 2.0.0-rc.1", override: true}, {:gun, "~> 2.0.0-rc.1", override: true},

View file

@ -10,8 +10,8 @@
"cachex": {:hex, :cachex, "3.3.0", "6f2ebb8f27491fe39121bd207c78badc499214d76c695658b19d6079beeca5c2", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "d90e5ee1dde14cef33f6b187af4335b88748b72b30c038969176cd4e6ccc31a1"}, "cachex": {:hex, :cachex, "3.3.0", "6f2ebb8f27491fe39121bd207c78badc499214d76c695658b19d6079beeca5c2", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "d90e5ee1dde14cef33f6b187af4335b88748b72b30c038969176cd4e6ccc31a1"},
"calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "990e9581920c82912a5ee50e62ff5ef96da6b15949a2ee4734f935fdef0f0a6f"}, "calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "990e9581920c82912a5ee50e62ff5ef96da6b15949a2ee4734f935fdef0f0a6f"},
"captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e0f16822d578866e186a0974d65ad58cddc1e2ab", [ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"]}, "captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e0f16822d578866e186a0974d65ad58cddc1e2ab", [ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"]},
"castore": {:hex, :castore, "0.1.10", "b01a007416a0ae4188e70b3b306236021b16c11474038ead7aff79dd75538c23", [:mix], [], "hexpm", "a48314e0cb45682db2ea27b8ebfa11bd6fa0a6e21a65e5772ad83ca136ff2665"}, "castore": {:hex, :castore, "0.1.17", "ba672681de4e51ed8ec1f74ed624d104c0db72742ea1a5e74edbc770c815182f", [:mix], [], "hexpm", "d9844227ed52d26e7519224525cb6868650c272d4a3d327ce3ca5570c12163f9"},
"certifi": {:hex, :certifi, "2.8.0", "d4fb0a6bb20b7c9c3643e22507e42f356ac090a1dcea9ab99e27e0376d695eba", [:rebar3], [], "hexpm", "6ac7efc1c6f8600b08d625292d4bbf584e14847ce1b6b5c44d983d273e1097ea"}, "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"comeonin": {:hex, :comeonin, "5.3.2", "5c2f893d05c56ae3f5e24c1b983c2d5dfb88c6d979c9287a76a7feb1e1d8d646", [:mix], [], "hexpm", "d0993402844c49539aeadb3fe46a3c9bd190f1ecf86b6f9ebd71957534c95f04"}, "comeonin": {:hex, :comeonin, "5.3.2", "5c2f893d05c56ae3f5e24c1b983c2d5dfb88c6d979c9287a76a7feb1e1d8d646", [:mix], [], "hexpm", "d0993402844c49539aeadb3fe46a3c9bd190f1ecf86b6f9ebd71957534c95f04"},
"concurrent_limiter": {:hex, :concurrent_limiter, "0.1.1", "43ae1dc23edda1ab03dd66febc739c4ff710d047bb4d735754909f9a474ae01c", [:mix], [{:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "53968ff238c0fbb4d7ed76ddb1af0be6f3b2f77909f6796e249e737c505a16eb"}, "concurrent_limiter": {:hex, :concurrent_limiter, "0.1.1", "43ae1dc23edda1ab03dd66febc739c4ff710d047bb4d735754909f9a474ae01c", [:mix], [{:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "53968ff238c0fbb4d7ed76ddb1af0be6f3b2f77909f6796e249e737c505a16eb"},
@ -51,7 +51,7 @@
"fast_html": {:hex, :fast_html, "2.0.5", "c61760340606c1077ff1f196f17834056cb1dd3d5cb92a9f2cabf28bc6221c3c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "605f4f4829443c14127694ebabb681778712ceecb4470ec32aa31012330e6506"}, "fast_html": {:hex, :fast_html, "2.0.5", "c61760340606c1077ff1f196f17834056cb1dd3d5cb92a9f2cabf28bc6221c3c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "605f4f4829443c14127694ebabb681778712ceecb4470ec32aa31012330e6506"},
"fast_sanitize": {:hex, :fast_sanitize, "0.2.2", "3cbbaebaea6043865dfb5b4ecb0f1af066ad410a51470e353714b10c42007b81", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "69f204db9250afa94a0d559d9110139850f57de2b081719fbafa1e9a89e94466"}, "fast_sanitize": {:hex, :fast_sanitize, "0.2.2", "3cbbaebaea6043865dfb5b4ecb0f1af066ad410a51470e353714b10c42007b81", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "69f204db9250afa94a0d559d9110139850f57de2b081719fbafa1e9a89e94466"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"finch": {:hex, :finch, "0.10.0", "8e5e6101ae98e7f1ef830594f774411a2f9cbce4f92d8179502da69fbbff52bc", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "80324ba22edbdebca6fac05c8517e7457b79dfe101e3bf6b2f7c5c65c93a9077"}, "finch": {:hex, :finch, "0.10.2", "9ad27d68270d879f73f26604bb2e573d40f29bf0e907064a9a337f90a16a0312", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dd8b11b282072cec2ef30852283949c248bd5d2820c88d8acc89402b81db7550"},
"flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"}, "flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"},
"floki": {:hex, :floki, "0.30.1", "75d35526d3a1459920b6e87fdbc2e0b8a3670f965dd0903708d2b267e0904c55", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "e9c03524447d1c4cbfccd672d739b8c18453eee377846b119d4fd71b1a176bb8"}, "floki": {:hex, :floki, "0.30.1", "75d35526d3a1459920b6e87fdbc2e0b8a3670f965dd0903708d2b267e0904c55", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "e9c03524447d1c4cbfccd672d739b8c18453eee377846b119d4fd71b1a176bb8"},
"gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"}, "gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"},
@ -59,7 +59,8 @@
"gen_state_machine": {:hex, :gen_state_machine, "2.0.5", "9ac15ec6e66acac994cc442dcc2c6f9796cf380ec4b08267223014be1c728a95", [:mix], [], "hexpm"}, "gen_state_machine": {:hex, :gen_state_machine, "2.0.5", "9ac15ec6e66acac994cc442dcc2c6f9796cf380ec4b08267223014be1c728a95", [:mix], [], "hexpm"},
"gettext": {:hex, :gettext, "0.18.2", "7df3ea191bb56c0309c00a783334b288d08a879f53a7014341284635850a6e55", [:mix], [], "hexpm", "f9f537b13d4fdd30f3039d33cb80144c3aa1f8d9698e47d7bcbcc8df93b1f5c5"}, "gettext": {:hex, :gettext, "0.18.2", "7df3ea191bb56c0309c00a783334b288d08a879f53a7014341284635850a6e55", [:mix], [], "hexpm", "f9f537b13d4fdd30f3039d33cb80144c3aa1f8d9698e47d7bcbcc8df93b1f5c5"},
"gun": {:hex, :gun, "2.0.0-rc.2", "7c489a32dedccb77b6e82d1f3c5a7dadfbfa004ec14e322cdb5e579c438632d2", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "6b9d1eae146410d727140dbf8b404b9631302ecc2066d1d12f22097ad7d254fc"}, "gun": {:hex, :gun, "2.0.0-rc.2", "7c489a32dedccb77b6e82d1f3c5a7dadfbfa004ec14e322cdb5e579c438632d2", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "6b9d1eae146410d727140dbf8b404b9631302ecc2066d1d12f22097ad7d254fc"},
"hackney": {:hex, :hackney, "1.18.0", "c4443d960bb9fba6d01161d01cd81173089686717d9490e5d3606644c48d121f", [:rebar3], [{:certifi, "~>2.8.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "9afcda620704d720db8c6a3123e9848d09c87586dc1c10479c42627b905b5c5e"}, "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
"hpax": {:hex, :hpax, "0.1.1", "2396c313683ada39e98c20a75a82911592b47e5c24391363343bde74f82396ca", [:mix], [], "hexpm", "0ae7d5a0b04a8a60caf7a39fcf3ec476f35cc2cc16c05abea730d3ce6ac6c826"},
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"}, "html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
"http_signatures": {:hex, :http_signatures, "0.1.1", "ca7ebc1b61542b163644c8c3b1f0e0f41037d35f2395940d3c6c7deceab41fd8", [:mix], [], "hexpm", "cc3b8a007322cc7b624c0c15eec49ee58ac977254ff529a3c482f681465942a3"}, "http_signatures": {:hex, :http_signatures, "0.1.1", "ca7ebc1b61542b163644c8c3b1f0e0f41037d35f2395940d3c6c7deceab41fd8", [:mix], [], "hexpm", "cc3b8a007322cc7b624c0c15eec49ee58ac977254ff529a3c482f681465942a3"},
@ -80,7 +81,7 @@
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"}, "mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"mint": {:hex, :mint, "1.4.0", "cd7d2451b201fc8e4a8fd86257fb3878d9e3752899eb67b0c5b25b180bde1212", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "10a99e144b815cbf8522dccbc8199d15802440fc7a64d67b6853adb6fa170217"}, "mint": {:hex, :mint, "1.4.1", "49b3b6ea35a9a38836d2ad745251b01ca9ec062f7cb66f546bf22e6699137126", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "cd261766e61011a9079cccf8fa9d826e7a397c24fbedf0e11b49312bea629b58"},
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"}, "mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
"mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"}, "mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"},
"mogrify": {:hex, :mogrify, "0.9.1", "a26f107c4987477769f272bd0f7e3ac4b7b75b11ba597fd001b877beffa9c068", [:mix], [], "hexpm", "134edf189337d2125c0948bf0c228fdeef975c594317452d536224069a5b7f05"}, "mogrify": {:hex, :mogrify, "0.9.1", "a26f107c4987477769f272bd0f7e3ac4b7b75b11ba597fd001b877beffa9c068", [:mix], [], "hexpm", "134edf189337d2125c0948bf0c228fdeef975c594317452d536224069a5b7f05"},
@ -88,7 +89,7 @@
"myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]}, "myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]},
"nimble_options": {:hex, :nimble_options, "0.4.0", "c89babbab52221a24b8d1ff9e7d838be70f0d871be823165c94dd3418eea728f", [:mix], [], "hexpm", "e6701c1af326a11eea9634a3b1c62b475339ace9456c1a23ec3bc9a847bca02d"}, "nimble_options": {:hex, :nimble_options, "0.4.0", "c89babbab52221a24b8d1ff9e7d838be70f0d871be823165c94dd3418eea728f", [:mix], [], "hexpm", "e6701c1af326a11eea9634a3b1c62b475339ace9456c1a23ec3bc9a847bca02d"},
"nimble_parsec": {:hex, :nimble_parsec, "1.2.0", "b44d75e2a6542dcb6acf5d71c32c74ca88960421b6874777f79153bbbbd7dccc", [:mix], [], "hexpm", "52b2871a7515a5ac49b00f214e4165a40724cf99798d8e4a65e4fd64ebd002c1"}, "nimble_parsec": {:hex, :nimble_parsec, "1.2.0", "b44d75e2a6542dcb6acf5d71c32c74ca88960421b6874777f79153bbbbd7dccc", [:mix], [], "hexpm", "52b2871a7515a5ac49b00f214e4165a40724cf99798d8e4a65e4fd64ebd002c1"},
"nimble_pool": {:hex, :nimble_pool, "0.2.4", "1db8e9f8a53d967d595e0b32a17030cdb6c0dc4a451b8ac787bf601d3f7704c3", [:mix], [], "hexpm", "367e8071e137b787764e6a9992ccb57b276dc2282535f767a07d881951ebeac6"}, "nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"},
"nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]}, "nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]},
"oban": {:hex, :oban, "2.3.4", "ec7509b9af2524d55f529cb7aee93d36131ae0bf0f37706f65d2fe707f4d9fd8", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c70ca0434758fd1805422ea4446af5e910ddc697c0c861549c8f0eb0cfbd2fdf"}, "oban": {:hex, :oban, "2.3.4", "ec7509b9af2524d55f529cb7aee93d36131ae0bf0f37706f65d2fe707f4d9fd8", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c70ca0434758fd1805422ea4446af5e910ddc697c0c861549c8f0eb0cfbd2fdf"},
"open_api_spex": {:hex, :open_api_spex, "3.10.0", "94e9521ad525b3fcf6dc77da7c45f87fdac24756d4de588cb0816b413e7c1844", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "2dbb2bde3d2b821f06936e8dfaf3284331186556291946d84eeba3750ac28765"}, "open_api_spex": {:hex, :open_api_spex, "3.10.0", "94e9521ad525b3fcf6dc77da7c45f87fdac24756d4de588cb0816b413e7c1844", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "2dbb2bde3d2b821f06936e8dfaf3284331186556291946d84eeba3750ac28765"},
@ -130,7 +131,7 @@
"table_rex": {:hex, :table_rex, "3.1.1", "0c67164d1714b5e806d5067c1e96ff098ba7ae79413cc075973e17c38a587caa", [:mix], [], "hexpm", "678a23aba4d670419c23c17790f9dcd635a4a89022040df7d5d772cb21012490"}, "table_rex": {:hex, :table_rex, "3.1.1", "0c67164d1714b5e806d5067c1e96ff098ba7ae79413cc075973e17c38a587caa", [:mix], [], "hexpm", "678a23aba4d670419c23c17790f9dcd635a4a89022040df7d5d772cb21012490"},
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"}, "telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"}, "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},
"tesla": {:hex, :tesla, "1.4.1", "ff855f1cac121e0d16281b49e8f066c4a0d89965f98864515713878cca849ac8", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "95f5de35922c8c4b3945bee7406f66eb680b0955232f78f5fb7e853aa1ce201a"}, "tesla": {:hex, :tesla, "1.4.4", "bb89aa0c9745190930366f6a2ac612cdf2d0e4d7fff449861baa7875afd797b2", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "d5503a49f9dec1b287567ea8712d085947e247cb11b06bc54adb05bfde466457"},
"timex": {:hex, :timex, "3.7.5", "3eca56e23bfa4e0848f0b0a29a92fa20af251a975116c6d504966e8a90516dfd", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a15608dca680f2ef663d71c95842c67f0af08a0f3b1d00e17bbd22872e2874e4"}, "timex": {:hex, :timex, "3.7.5", "3eca56e23bfa4e0848f0b0a29a92fa20af251a975116c6d504966e8a90516dfd", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a15608dca680f2ef663d71c95842c67f0af08a0f3b1d00e17bbd22872e2874e4"},
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"}, "trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"},
"tzdata": {:hex, :tzdata, "1.0.5", "69f1ee029a49afa04ad77801febaf69385f3d3e3d1e4b56b9469025677b89a28", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "55519aa2a99e5d2095c1e61cc74c9be69688f8ab75c27da724eb8279ff402a5a"}, "tzdata": {:hex, :tzdata, "1.0.5", "69f1ee029a49afa04ad77801febaf69385f3d3e3d1e4b56b9469025677b89a28", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "55519aa2a99e5d2095c1e61cc74c9be69688f8ab75c27da724eb8279ff402a5a"},

View file

@ -0,0 +1,28 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"Hashtag": "as:Hashtag"
}
],
"type": "Like",
"id": "https://misskey.local.live/likes/917ocsybgp",
"actor": "https://misskey.local.live/users/8x8yep20u2",
"object": "https://pleroma.local.live/objects/89937a53-2692-4631-bb62-770091267391",
"content": ":hanapog:",
"_misskey_reaction": ":hanapog:",
"tag": [
{
"id": "https://misskey.local.live/emojis/hanapog",
"type": "Emoji",
"name": ":hanapog:",
"updated": "2022-06-07T12:00:05.773Z",
"icon": {
"type": "Image",
"mediaType": "image/png",
"url": "https://misskey.local.live/files/webpublic-8f8a9768-7264-4171-88d6-2356aabeadcd"
}
}
]
}

View file

@ -4,11 +4,24 @@
"https://w3id.org/security/v1", "https://w3id.org/security/v1",
{"Hashtag" : "as:Hashtag"} {"Hashtag" : "as:Hashtag"}
], ],
"_misskey_reaction" : "pudding", "_misskey_reaction" : ":pudding:",
"content": ":pudding:",
"actor": "http://mastodon.example.org/users/admin", "actor": "http://mastodon.example.org/users/admin",
"cc" : ["https://testing.pleroma.lol/users/lain"], "cc" : ["https://testing.pleroma.lol/users/lain"],
"id" : "https://misskey.xyz/75149198-2f45-46e4-930a-8b0538297075", "id" : "https://misskey.xyz/75149198-2f45-46e4-930a-8b0538297075",
"nickname" : "lain", "nickname" : "lain",
"object" : "https://testing.pleroma.lol/objects/c331bbf7-2eb9-4801-a709-2a6103492a5a", "object" : "https://testing.pleroma.lol/objects/c331bbf7-2eb9-4801-a709-2a6103492a5a",
"type" : "Like" "type" : "Like",
"tag": [
{
"id": "https://somewhere/emoji/pudding",
"name": ":pudding:",
"type": "Emoji",
"icon": {
"type": "Image",
"mediaType": "image/png",
"url": "http://somewhere"
}
}
]
} }

View file

@ -11,10 +11,10 @@ test "tells if a string is an unicode emoji" do
refute Emoji.is_unicode_emoji?("X") refute Emoji.is_unicode_emoji?("X")
refute Emoji.is_unicode_emoji?("") refute Emoji.is_unicode_emoji?("")
# Only accept fully-qualified (RGI) emoji # Accept fully-qualified and unqualified emoji
# See http://www.unicode.org/reports/tr51/ # See http://www.unicode.org/reports/tr51/
refute Emoji.is_unicode_emoji?("") assert Emoji.is_unicode_emoji?("")
refute Emoji.is_unicode_emoji?("") assert Emoji.is_unicode_emoji?("")
assert Emoji.is_unicode_emoji?("🥺") assert Emoji.is_unicode_emoji?("🥺")
assert Emoji.is_unicode_emoji?("🤰") assert Emoji.is_unicode_emoji?("🤰")

View file

@ -9,6 +9,7 @@ defmodule Pleroma.HTTPTest do
alias Pleroma.HTTP alias Pleroma.HTTP
setup do setup do
clear_config([:http, :send_user_agent], false)
mock(fn mock(fn
%{ %{
method: :get, method: :get,

View file

@ -130,7 +130,7 @@ test "max_body_length returns error if streaming body more than that option", %{
assert capture_log(fn -> assert capture_log(fn ->
ReverseProxy.call(conn, "/stream-bytes/50", max_body_length: 30) ReverseProxy.call(conn, "/stream-bytes/50", max_body_length: 30)
end) =~ end) =~
"[warn] Elixir.Pleroma.ReverseProxy request to /stream-bytes/50 failed while reading/chunking: :body_too_large" "Elixir.Pleroma.ReverseProxy request to /stream-bytes/50 failed while reading/chunking: :body_too_large"
end end
end end

View file

@ -38,16 +38,70 @@ test "it is not valid without a 'content' field", %{valid_emoji_react: valid_emo
assert {:content, {"can't be blank", [validation: :required]}} in cng.errors assert {:content, {"can't be blank", [validation: :required]}} in cng.errors
end end
test "it is not valid with a non-emoji content field", %{valid_emoji_react: valid_emoji_react} do test "it is valid when custom emoji is used", %{valid_emoji_react: valid_emoji_react} do
without_emoji_content = without_emoji_content =
valid_emoji_react valid_emoji_react
|> Map.put("content", "x") |> Map.put("content", ":hello:")
|> Map.put("tag", [
%{
"type" => "Emoji",
"name" => ":hello:",
"icon" => %{"url" => "http://somewhere", "type" => "Image"}
}
])
{:ok, _, _} = ObjectValidator.validate(without_emoji_content, [])
end
test "it is not valid when custom emoji don't have a matching tag", %{
valid_emoji_react: valid_emoji_react
} do
without_emoji_content =
valid_emoji_react
|> Map.put("content", ":hello:")
|> Map.put("tag", [
%{
"type" => "Emoji",
"name" => ":whoops:",
"icon" => %{"url" => "http://somewhere", "type" => "Image"}
}
])
{:error, cng} = ObjectValidator.validate(without_emoji_content, []) {:error, cng} = ObjectValidator.validate(without_emoji_content, [])
refute cng.valid? refute cng.valid?
assert {:content, {"must be a single character emoji", []}} in cng.errors assert {:tag, {"does not contain an Emoji tag", []}} in cng.errors
end
test "it is not valid when custom emoji have no tags", %{
valid_emoji_react: valid_emoji_react
} do
without_emoji_content =
valid_emoji_react
|> Map.put("content", ":hello:")
|> Map.put("tag", [])
{:error, cng} = ObjectValidator.validate(without_emoji_content, [])
refute cng.valid?
assert {:tag, {"does not contain an Emoji tag", []}} in cng.errors
end
test "it is not valid when custom emoji doesn't match a shortcode format", %{
valid_emoji_react: valid_emoji_react
} do
without_emoji_content =
valid_emoji_react
|> Map.put("content", "hello")
|> Map.put("tag", [])
{:error, cng} = ObjectValidator.validate(without_emoji_content, [])
refute cng.valid?
assert {:tag, {"does not contain an Emoji tag", []}} in cng.errors
end end
end end
end end

View file

@ -28,6 +28,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
SideEffectsMock SideEffectsMock
|> expect(:handle, fn o, m -> {:ok, o, m} end) |> expect(:handle, fn o, m -> {:ok, o, m} end)
|> expect(:handle_after_transaction, fn m -> m end) |> expect(:handle_after_transaction, fn m -> m end)
|> expect(:handle_after_transaction, fn m -> m end)
:ok :ok
end end

View file

@ -158,7 +158,7 @@ test "adds the reaction to the object", %{emoji_react: emoji_react, user: user}
object = Object.get_by_ap_id(emoji_react.data["object"]) object = Object.get_by_ap_id(emoji_react.data["object"])
assert object.data["reaction_count"] == 1 assert object.data["reaction_count"] == 1
assert ["👌", [user.ap_id]] in object.data["reactions"] assert ["👌", [user.ap_id], nil] in object.data["reactions"]
end end
test "creates a notification", %{emoji_react: emoji_react, poster: poster} do test "creates a notification", %{emoji_react: emoji_react, poster: poster} do

View file

@ -34,7 +34,46 @@ test "it works for incoming emoji reactions" do
object = Object.get_by_ap_id(data["object"]) object = Object.get_by_ap_id(data["object"])
assert object.data["reaction_count"] == 1 assert object.data["reaction_count"] == 1
assert match?([["👌", _]], object.data["reactions"]) assert match?([["👌", _, nil]], object.data["reactions"])
end
test "it works for incoming custom emoji reactions" do
user = insert(:user)
other_user = insert(:user, local: false)
{:ok, activity} = CommonAPI.post(user, %{status: "hello"})
data =
File.read!("test/fixtures/custom-emoji-reaction.json")
|> Jason.decode!()
|> Map.put("object", activity.data["object"])
|> Map.put("actor", other_user.ap_id)
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["actor"] == other_user.ap_id
assert data["type"] == "EmojiReact"
assert data["id"] == "https://misskey.local.live/likes/917ocsybgp"
assert data["object"] == activity.data["object"]
assert data["content"] == ":hanapog:"
assert data["tag"] == [
%{
"id" => "https://misskey.local.live/emojis/hanapog",
"type" => "Emoji",
"name" => "hanapog",
"updated" => "2022-06-07T12:00:05.773Z",
"icon" => %{
"type" => "Image",
"url" =>
"https://misskey.local.live/files/webpublic-8f8a9768-7264-4171-88d6-2356aabeadcd"
}
}
]
object = Object.get_by_ap_id(data["object"])
assert object.data["reaction_count"] == 1
assert match?([["hanapog", _, "https://misskey.local.live/files/webpublic-8f8a9768-7264-4171-88d6-2356aabeadcd"]], object.data["reactions"])
end end
test "it reject invalid emoji reactions" do test "it reject invalid emoji reactions" do

View file

@ -51,7 +51,7 @@ test "it works for incoming misskey likes, turning them into EmojiReacts" do
assert activity_data["type"] == "EmojiReact" assert activity_data["type"] == "EmojiReact"
assert activity_data["id"] == data["id"] assert activity_data["id"] == data["id"]
assert activity_data["object"] == activity.data["object"] assert activity_data["object"] == activity.data["object"]
assert activity_data["content"] == "🍮" assert activity_data["content"] == ":pudding:"
end end
test "it works for incoming misskey likes that contain unicode emojis, turning them into EmojiReacts" do test "it works for incoming misskey likes that contain unicode emojis, turning them into EmojiReacts" do

View file

@ -360,7 +360,13 @@ test "it returns reports with notes", %{conn: conn, admin: admin} do
response = json_response_and_validate_schema(conn, 200) response = json_response_and_validate_schema(conn, 200)
notes = hd(response["reports"])["notes"] notes = hd(response["reports"])["notes"]
[note, _] = notes assert 2 == Enum.count(notes)
note =
notes
|> Enum.find(fn note -> note["content"] == "this is disgusting!" end)
refute is_nil(note)
assert note["user"]["nickname"] == admin.nickname assert note["user"]["nickname"] == admin.nickname
assert note["content"] == "this is disgusting!" assert note["content"] == "this is disgusting!"

View file

@ -309,7 +309,7 @@ test "when date is a binary in wrong format" do
assert capture_log(fn -> assert capture_log(fn ->
assert Utils.date_to_asctime(date) == expected assert Utils.date_to_asctime(date) == expected
end) =~ "[warn] Date #{date} in wrong format, must be ISO 8601" end) =~ "[warning] Date #{date} in wrong format, must be ISO 8601"
end end
test "when date is a Unix timestamp" do test "when date is a Unix timestamp" do
@ -319,7 +319,7 @@ test "when date is a Unix timestamp" do
assert capture_log(fn -> assert capture_log(fn ->
assert Utils.date_to_asctime(date) == expected assert Utils.date_to_asctime(date) == expected
end) =~ "[warn] Date #{date} in wrong format, must be ISO 8601" end) =~ "[warning] Date #{date} in wrong format, must be ISO 8601"
end end
test "when date is nil" do test "when date is nil" do
@ -327,13 +327,13 @@ test "when date is nil" do
assert capture_log(fn -> assert capture_log(fn ->
assert Utils.date_to_asctime(nil) == expected assert Utils.date_to_asctime(nil) == expected
end) =~ "[warn] Date in wrong format, must be ISO 8601" end) =~ "[warning] Date in wrong format, must be ISO 8601"
end end
test "when date is a random string" do test "when date is a random string" do
assert capture_log(fn -> assert capture_log(fn ->
assert Utils.date_to_asctime("foo") == "" assert Utils.date_to_asctime("foo") == ""
end) =~ "[warn] Date foo in wrong format, must be ISO 8601" end) =~ "[warning] Date foo in wrong format, must be ISO 8601"
end end
end end

View file

@ -323,7 +323,6 @@ test "search fetches remote accounts", %{conn: conn} do
|> assign(:token, insert(:oauth_token, user: user, scopes: ["read"])) |> assign(:token, insert(:oauth_token, user: user, scopes: ["read"]))
|> get("/api/v1/search?#{query}") |> get("/api/v1/search?#{query}")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
[account] = results["accounts"] [account] = results["accounts"]
assert account["acct"] == "mike@osada.macgirvin.com" assert account["acct"] == "mike@osada.macgirvin.com"
end end

View file

@ -34,16 +34,25 @@ test "has an emoji reaction list" do
{:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"}) {:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"})
{:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "") {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, user, ":dinosaur:")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵") {:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "") {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, ":dinosaur:")
activity = Repo.get(Activity, activity.id) activity = Repo.get(Activity, activity.id)
status = StatusView.render("show.json", activity: activity) status = StatusView.render("show.json", activity: activity)
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
assert status[:pleroma][:emoji_reactions] == [ assert status[:pleroma][:emoji_reactions] == [
%{name: "", count: 2, me: false}, %{name: "", count: 2, me: false, url: nil},
%{name: "🍵", count: 1, me: false} %{
count: 2,
me: false,
name: "dinosaur",
url: "http://localhost:4001/emoji/dino walking.gif"
},
%{name: "🍵", count: 1, me: false, url: nil}
] ]
status = StatusView.render("show.json", activity: activity, for: user) status = StatusView.render("show.json", activity: activity, for: user)
@ -51,8 +60,14 @@ test "has an emoji reaction list" do
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
assert status[:pleroma][:emoji_reactions] == [ assert status[:pleroma][:emoji_reactions] == [
%{name: "", count: 2, me: true}, %{name: "", count: 2, me: true, url: nil},
%{name: "🍵", count: 1, me: false} %{
count: 2,
me: true,
name: "dinosaur",
url: "http://localhost:4001/emoji/dino walking.gif"
},
%{name: "🍵", count: 1, me: false, url: nil}
] ]
end end
@ -65,11 +80,10 @@ test "works correctly with badly formatted emojis" do
|> Object.update_data(%{"reactions" => %{"" => [user.ap_id], "x" => 1}}) |> Object.update_data(%{"reactions" => %{"" => [user.ap_id], "x" => 1}})
activity = Activity.get_by_id(activity.id) activity = Activity.get_by_id(activity.id)
status = StatusView.render("show.json", activity: activity, for: user) status = StatusView.render("show.json", activity: activity, for: user)
assert status[:pleroma][:emoji_reactions] == [ assert status[:pleroma][:emoji_reactions] == [
%{name: "", count: 1, me: true} %{name: "", count: 1, me: true, url: nil}
] ]
end end
@ -89,7 +103,7 @@ test "doesn't show reactions from muted and blocked users" do
status = StatusView.render("show.json", activity: activity) status = StatusView.render("show.json", activity: activity)
assert status[:pleroma][:emoji_reactions] == [ assert status[:pleroma][:emoji_reactions] == [
%{name: "", count: 1, me: false} %{name: "", count: 1, me: false, url: nil}
] ]
status = StatusView.render("show.json", activity: activity, for: user) status = StatusView.render("show.json", activity: activity, for: user)
@ -101,19 +115,19 @@ test "doesn't show reactions from muted and blocked users" do
status = StatusView.render("show.json", activity: activity) status = StatusView.render("show.json", activity: activity)
assert status[:pleroma][:emoji_reactions] == [ assert status[:pleroma][:emoji_reactions] == [
%{name: "", count: 2, me: false} %{name: "", count: 2, me: false, url: nil}
] ]
status = StatusView.render("show.json", activity: activity, for: user) status = StatusView.render("show.json", activity: activity, for: user)
assert status[:pleroma][:emoji_reactions] == [ assert status[:pleroma][:emoji_reactions] == [
%{name: "", count: 1, me: false} %{name: "", count: 1, me: false, url: nil}
] ]
status = StatusView.render("show.json", activity: activity, for: other_user) status = StatusView.render("show.json", activity: activity, for: other_user)
assert status[:pleroma][:emoji_reactions] == [ assert status[:pleroma][:emoji_reactions] == [
%{name: "", count: 1, me: true} %{name: "", count: 1, me: true, url: nil}
] ]
end end

View file

@ -144,7 +144,7 @@ test "video attachments have image thumbnail with WxH metadata with Preview Prox
[ [
property: "og:image", property: "og:image",
content: content:
"http://localhost:4001/proxy/preview/LzAnlke-l5oZbNzWsrHfprX1rGw/aHR0cHM6Ly9wbGVyb21hLmdvdi9hYm91dC9qdWNoZS53ZWJt/juche.webm" "http://localhost:4001/proxy/preview/FElXD3PfapZSKq-u62Dc3BiaIM8/aHR0cHM6Ly9wbGVyb21hLmdvdi9hYm91dC9qdWNoZS53ZWJt/juche.webm"
], []} in result ], []} in result
end end

View file

@ -31,7 +31,7 @@ test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
assert to_string(activity.id) == id assert to_string(activity.id) == id
assert result["pleroma"]["emoji_reactions"] == [ assert result["pleroma"]["emoji_reactions"] == [
%{"name" => "", "count" => 1, "me" => true} %{"name" => "", "count" => 1, "me" => true, "url" => nil}
] ]
# Reacting with a non-emoji # Reacting with a non-emoji
@ -181,7 +181,15 @@ test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅") {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "") {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "")
assert [%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = assert [
%{
"name" => "🎅",
"count" => 1,
"accounts" => [represented_user],
"me" => false,
"url" => nil
}
] =
conn conn
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅") |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)