Merge branch 'develop' of ssh://git.pleroma.social:2222/pleroma/pleroma into froth

This commit is contained in:
Sam Therapy 2023-04-08 12:58:26 -05:00
commit 35a748e959
Signed by: sam
GPG Key ID: 4D8B07C18F31ACBD
22 changed files with 273 additions and 38 deletions

View File

@ -8,6 +8,13 @@ variables: &global_variables
DB_PORT: 5432
MIX_ENV: test
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
cache: &global_cache_policy
key:
files:
@ -17,6 +24,7 @@ cache: &global_cache_policy
- _build
stages:
- check-changelog
- build
- test
- benchmark
@ -32,6 +40,17 @@ before_script:
after_script:
- rm -rf _build/*/lib/pleroma
check-changelog:
stage: check-changelog
image: alpine
rules:
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"
before_script: ''
after_script: ''
cache: {}
script:
- sh ./tools/check-changelog
build:
stage: build
only:

View File

@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
### Added
- Support for Image activities, namely from Hubzilla
### Fixed

0
changelog.d/3739.skip Normal file
View File

View File

@ -3,12 +3,6 @@ Note: Additional clients may be working but theses are officially supporting Ple
Feel free to contact us to be added to this list!
## Desktop
### Roma for Desktop
- Homepage: <https://www.pleroma.com/#desktopApp>
- Source Code: <https://github.com/roma-apps/roma-desktop>
- Platforms: Windows, Mac, Linux
- Features: MastoAPI, Streaming Ready
### Social
- Source Code: <https://gitlab.gnome.org/World/Social>
- Contact: [@brainblasted@social.libre.fi](https://social.libre.fi/users/brainblasted)
@ -19,7 +13,14 @@ Feel free to contact us to be added to this list!
### Whalebird
- Homepage: <https://whalebird.social/>
- Source Code: <https://github.com/h3poteto/whalebird-desktop>
- Contact: [@h3poteto@pleroma.io](https://pleroma.io/users/h3poteto)
- Contact: [@whalebird@pleroma.io](https://pleroma.io/users/whalebird)
- Platforms: Windows, Mac, Linux
- Features: MastoAPI, Streaming Ready
### Fedistar
- Homepage: <https://fedistar.net>
- Source Code: <https://github.com/h3poteto/fedistar>
- Contact: [@fedistar@pleroma.io](https://pleroma.io/users/fedistar)
- Platforms: Windows, Mac, Linux
- Features: MastoAPI, Streaming Ready

View File

@ -425,4 +425,30 @@ def object_data_hashtags(%{"tag" => tags}) when is_list(tags) do
end
def object_data_hashtags(_), do: []
def get_emoji_reactions(object) do
reactions = object.data["reactions"]
if is_list(reactions) or is_map(reactions) do
reactions
|> Enum.map(fn
[_emoji, users, _maybe_url] = item when is_list(users) ->
item
[emoji, users] when is_list(users) ->
[emoji, users, nil]
# This case is here to process the Map situation, which will happen
# only with the legacy two-value format.
{emoji, users} when is_list(users) ->
[emoji, users, nil]
_ ->
nil
end)
|> Enum.reject(&is_nil/1)
else
[]
end
end
end

View File

@ -96,7 +96,7 @@ defp increase_replies_count_if_reply(%{
defp increase_replies_count_if_reply(_create_data), do: :noop
@object_types ~w[ChatMessage Question Answer Audio Video Event Article Note Page]
@object_types ~w[ChatMessage Question Answer Audio Video Image Event Article Note Page]
@impl true
def persist(%{"type" => type} = object, meta) when type in @object_types do
with {:ok, object} <- Object.create(object) do

View File

@ -21,7 +21,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
alias Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.AudioImageVideoValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator
@ -102,7 +102,7 @@ def validate(
%{"type" => "Create", "object" => %{"type" => objtype} = object} = create_activity,
meta
)
when objtype in ~w[Question Answer Audio Video Event Article Note Page] do
when objtype in ~w[Question Answer Audio Video Image Event Article Note Page] do
with {:ok, object_data} <- cast_and_apply_and_stringify_with_history(object),
meta = Keyword.put(meta, :object_data, object_data),
{:ok, create_activity} <-
@ -115,13 +115,14 @@ def validate(
end
def validate(%{"type" => type} = object, meta)
when type in ~w[Event Question Audio Video Article Note Page] do
when type in ~w[Event Question Audio Video Image Article Note Page] do
validator =
case type do
"Event" -> EventValidator
"Question" -> QuestionValidator
"Audio" -> AudioVideoValidator
"Video" -> AudioVideoValidator
"Audio" -> AudioImageVideoValidator
"Video" -> AudioImageVideoValidator
"Image" -> AudioImageVideoValidator
"Article" -> ArticleNotePageValidator
"Note" -> ArticleNotePageValidator
"Page" -> ArticleNotePageValidator
@ -233,8 +234,8 @@ def cast_and_apply(%{"type" => "Answer"} = object) do
AnswerValidator.cast_and_apply(object)
end
def cast_and_apply(%{"type" => type} = object) when type in ~w[Audio Video] do
AudioVideoValidator.cast_and_apply(object)
def cast_and_apply(%{"type" => type} = object) when type in ~w[Audio Image Video] do
AudioImageVideoValidator.cast_and_apply(object)
end
def cast_and_apply(%{"type" => "Event"} = object) do

View File

@ -2,7 +2,7 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator do
defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioImageVideoValidator do
use Ecto.Schema
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
@ -55,9 +55,14 @@ defp find_attachment(url) do
url
|> Enum.concat(mpeg_url["tag"] || [])
|> Enum.find(fn
%{"mediaType" => mime_type} -> String.starts_with?(mime_type, ["video/", "audio/"])
%{"mimeType" => mime_type} -> String.starts_with?(mime_type, ["video/", "audio/"])
_ -> false
%{"mediaType" => mime_type} ->
String.starts_with?(mime_type, ["video/", "audio/", "image/"])
%{"mimeType" => mime_type} ->
String.starts_with?(mime_type, ["video/", "audio/", "image/"])
_ ->
false
end)
end
@ -110,7 +115,7 @@ def changeset(struct, data) do
defp validate_data(data_cng) do
data_cng
|> validate_inclusion(:type, ["Audio", "Video"])
|> validate_inclusion(:type, ~w[Audio Image Video])
|> validate_required([:id, :actor, :attributedTo, :type, :context])
|> CommonValidations.validate_any_presence([:cc, :to])
|> CommonValidations.validate_fields_match([:actor, :attributedTo])

View File

@ -520,7 +520,7 @@ def handle_object_creation(%{"type" => "Answer"} = object_map, _activity, meta)
end
def handle_object_creation(%{"type" => objtype} = object, _activity, meta)
when objtype in ~w[Audio Video Event Article Note Page] do
when objtype in ~w[Audio Video Image Event Article Note Page] do
with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
{:ok, object, meta}
end

View File

@ -447,7 +447,7 @@ def handle_incoming(
%{"type" => "Create", "object" => %{"type" => objtype, "id" => obj_id}} = data,
options
)
when objtype in ~w{Question Answer ChatMessage Audio Video Event Article Note Page} do
when objtype in ~w{Question Answer ChatMessage Audio Video Event Article Note Page Image} do
fetch_options = Keyword.put(options, :depth, (options[:depth] || 0) + 1)
object =

View File

@ -31,7 +31,8 @@ defmodule Pleroma.Web.ActivityPub.Utils do
"Page",
"Question",
"Answer",
"Audio"
"Audio",
"Image"
]
@strip_status_report_states ~w(closed resolved)
@supported_report_states ~w(open closed resolved)
@ -407,11 +408,7 @@ def remove_emoji_reaction_from_object(
end
def get_cached_emoji_reactions(object) do
if is_list(object.data["reactions"]) do
object.data["reactions"]
else
[]
end
Object.get_emoji_reactions(object)
end
@spec add_like_to_object(Activity.t(), Object.t()) ::

View File

@ -334,8 +334,8 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
end
emoji_reactions =
object.data
|> Map.get("reactions", [])
object
|> Object.get_emoji_reactions()
|> EmojiReactionController.filter_allowed_users(
opts[:for],
Map.get(opts, :with_muted, false)

View File

@ -28,8 +28,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionController do
def index(%{assigns: %{user: user}} = conn, %{id: activity_id} = params) do
with true <- Pleroma.Config.get([:instance, :show_reactions]),
%Activity{} = activity <- Activity.get_by_id_with_object(activity_id),
%Object{data: %{"reactions" => reactions}} when is_list(reactions) <-
Object.normalize(activity, fetch: false) do
%Object{} = object <- Object.normalize(activity, fetch: false),
reactions <- Object.get_emoji_reactions(object) do
reactions =
reactions
|> filter(params)
@ -60,9 +60,6 @@ def filter_allowed_users(reactions, user, with_muted) do
reactions
|> 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} when is_list(users) -> filter_emoji.(emoji, users, nil)
_ -> nil
end)
|> Stream.reject(&is_nil/1)
end

View File

@ -45,5 +45,5 @@ def perform(%Job{args: %{"op" => "delete_instance", "host" => host}}) do
end
@impl Oban.Worker
def timeout(_job), do: :timer.seconds(5)
def timeout(_job), do: :timer.seconds(900)
end

1
test/fixtures/hubzilla-actor.json vendored Normal file
View File

@ -0,0 +1 @@
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://hub.somaton.com/apschema/v1.9"],"type":"Person","id":"https://hub.somaton.com/channel/testc6","preferredUsername":"testc6","name":"testc6 lala","updated":"2021-08-29T10:07:23Z","icon":{"type":"Image","mediaType":"image/png","updated":"2021-10-09T04:54:35Z","url":"https://hub.somaton.com/photo/profile/l/33","height":300,"width":300},"url":"https://hub.somaton.com/channel/testc6","publicKey":{"id":"https://hub.somaton.com/channel/testc6","owner":"https://hub.somaton.com/channel/testc6","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq5ep+6MhhaAiqZSd8nXe\nUAokXNgqTr/DjUic5VDudjQgvetchaiBUieBnqpJSPNNAvvf6Qs4eDW4w2JQeA6y\nqEplKrmb8l1EyhwXeFLDUGQdf0f6hg++x5mIrO6uX0tlQGU6nutvhItn6JMZc5GU\nv3C/UW0OfHCCdHSGZ/1nIqq1P98FqF0+PA1pvTHCkLr4kcKzfpmkLjsccUSq0FGh\nQF+paW9FU89o4hkaH/X3E/Ac7DL8zgcyt29KSj4eUIvjBIEPAMdRno345fiZ+QYr\nlYQYaBC2gvozjxtxl9MyfqjBRzfl9VDHzoDvMn5+LD5dCRB1zOESv/b3EpiHYqXl\nwiPzP9az8e8cw6D72n/Mlrf27yIuVAdwaGdbAwekjIQZHIDoP0XNnA5i31RLpEMI\nbNpH47ChtjxeilQZ3va6qIShYfGlndpy/rx4i4Yt4xIG+BbGb/dWo3AbtHi64fPZ\nMoLuR71sEBe7uAvalJ+lopxuQ2qLJpCInukQ13p/G/n9tVDwbfGyumzr5hHk7JoY\nN+JqH737MCZqb9dRDof+fju58GY1VzFjBph38sHYJh0ykA+2BzYU2+nT7CDXfKWA\nsmHhizp7haoPjl/yclZG5FJwg3oqHTD14dASUs+OI4K+Q//74wfb4/6E3CDyOkW3\nUj+8TPZooKulxtQ9ezergr0CAwEAAQ==\n-----END PUBLIC KEY-----\n"},"outbox":"https://hub.somaton.com/outbox/testc6","inbox":"https://hub.somaton.com/inbox/testc6","followers":"https://hub.somaton.com/followers/testc6","following":"https://hub.somaton.com/following/testc6","endpoints":{"sharedInbox":"https://hub.somaton.com/inbox"},"discoverable":false,"signature":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"RsaSignature2017","nonce":"8d6dea03f04cbb7faaf43958a4cf39a115ff1c61c7febaa6154c463eab9a42c8","creator":"https://hub.somaton.com/channel/testc6","created":"2021-10-13T18:21:48Z","signatureValue":"N4CJBO2K/8v7KI97REyJXaSYOlLWscuEDlODDnjNYD1fbVQFO3s2JtqPcN2lVJvNTlW5HUze+owaAYNcvZe3mNm1iz05Xru3s8yRA8bNCdKBuWd/3zb3/JQVkbSb09D2PloeuoKBQmPIn+dNiTyFR0jxLsxCXXTomGKigWPtTOUIt52Dv9MFJ3jRZmfoykT9bHrAIVCASHoiluhTkPAzc6pt0lSyZd0D3X4J1K4/sLXa8HRoooMFu2dHWfqV4tyLU9WzofAhvnYg9tEbKCH42DIAbwDfjAeC4qL8xkqAlYWLvXYVGH76cZLdp9Zuv1p3NHqaPEJ85MbuaUkfnU75Bx/Fcfoi0pEieWRdFvMx5b/UFwGbJd6iSAO1zRbGYTPEMPWHzh0AEAaLeyY+g3ZmpNu88ujrIr8iJ1U4EkjOBn8ooxA5LaI2fXDiYC2NwRiAbY+xVtgJgvHDi9tXCdvzjZWfU/cgiwF/cYMbsB2BCyPRd+XZhudfXSOysFC4WYnawhiRVevba9lQ6rEP4FMepOGq4ZOSGzxgw2xNIXpu0IkrxX5mEv/ahEhDy1KGRIFc0GnPJrv3kMVxJrZ7SF8PNAGqftQBLkqQR+SEygs3XB4cd2DQ2lPeiMd8+Xv+lBjtzZtZAM/Y4CZCOdV9DHXDGNSKKFDzzna4QcUzQ+KRc8w="}}

View File

@ -0,0 +1 @@
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://hub.somaton.com/apschema/v1.9"],"type":"Create","id":"https://hub.somaton.com/activity/452583b2-7e1f-4ac3-8334-ff666f134afe","diaspora:guid":"452583b2-7e1f-4ac3-8334-ff666f134afe","name":"daf82c18ef92a84cda72(1).jpg","published":"2021-10-12T21:28:26Z","actor":"https://hub.somaton.com/channel/testc6","object":{"type":"Image","name":"daf82c18ef92a84cda72(1).jpg","published":"2021-10-12T21:28:23Z","updated":"2021-10-12T21:28:23Z","attributedTo":"https://hub.somaton.com/channel/testc6","id":"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe","url":[{"type":"Link","mediaType":"image/jpeg","href":"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-0.jpg","width":2200,"height":2200},{"type":"Link","mediaType":"image/jpeg","href":"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-1.jpg","width":1024,"height":1024},{"type":"Link","mediaType":"image/jpeg","href":"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-2.jpg","width":640,"height":640},{"type":"Link","mediaType":"image/jpeg","href":"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-3.jpg","width":320,"height":320},{"type":"Link","mediaType":"text/html","href":"https://hub.somaton.com/photos/testc6/image/452583b2-7e1f-4ac3-8334-ff666f134afe"}],"source":{"content":"[footer][zrl=https://hub.somaton.com/channel/testc6]testc6 lala[/zrl] posted [zrl=https://hub.somaton.com/photos/testc6/image/452583b2-7e1f-4ac3-8334-ff666f134afe]a new photo[/zrl] to [zrl=https://hub.somaton.com/photos/testc6/album/1e9b0d74-633e-4bd0-b37f-694bb0ed0145]test[/zrl][/footer]","mediaType":"text/bbcode"},"content":"<div class=\"wall-item-footer\"><a class=\"zrl\" href=\"https://hub.somaton.com/channel/testc6\" target=\"_blank\" rel=\"nofollow noopener\" >testc6 lala</a> posted <a class=\"zrl\" href=\"https://hub.somaton.com/photos/testc6/image/452583b2-7e1f-4ac3-8334-ff666f134afe\" target=\"_blank\" rel=\"nofollow noopener\" >a new photo</a> to <a class=\"zrl\" href=\"https://hub.somaton.com/photos/testc6/album/1e9b0d74-633e-4bd0-b37f-694bb0ed0145\" target=\"_blank\" rel=\"nofollow noopener\" >test</a></div>","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://hub.somaton.com/followers/testc6"]},"target":{"type":"orderedCollection","name":"test","id":"https://hub.somaton.com/album/testc6/test"},"to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://hub.somaton.com/followers/testc6"],"signature":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"RsaSignature2017","nonce":"e0d077edccf262f02ed59ff67e91a5324ccaffc3d2b3f23793b4bd24cdbe70bb","creator":"https://hub.somaton.com/channel/testc6","created":"2021-10-13T18:39:05Z","signatureValue":"YYU0/17PqqUmLCn4oVS2N62rV1G9WQ+wLax2cI+EpMw/WOWKuVvtGrvhzciQ5ITXoh3scrZRYH8Bke1jDWkjL9YtjVD6TjMsv6f3OoO1vvMNgEfQfgZJ78QQt5MoLrT2mkRa35lSmVHkTDROKJPrwIAnpN6bDb577wZ63BsuBjqW7ca/E6oXSIr+meCXv3kqkyYDSz0ImYvVmki+OfX97xbYkQlzM06EgK1LZTHfuf4sk09hVfDDqVB9tHO4ObYQCYNiOWRHjA5S1Cw8WX1OQJ+GCQ8yxHmtiU3tJsxeYhxGs7VEmTLUvf/QZ0VTPumkd1CewdxzNGvAP3f9JCakuV7eyk88oqF+p7xxfxmBjLYbMTuhrcZIdUdMcjW9pENOYBbt+a+FhPsjbm8zVU3iKPqe/8UAvo01hGW7jiKJUm4qdcX3H3MExTLEFuz0NTeqxl4djlyGTT9KBqNouD+/oSSgwm6qeRZ5y3RsC27N0HRbg74qNXhhWQZVWQtHdSCHjAfHVPOSpjxpSPs7qkMLQ0vPsVsCsukZz8JCoXRo+JoKuaiaRgfiIRGNBO/XEicKMyu2JCU+UmkroiDJHy+4IfZRevnlneRa1jmu5KA/4xk5KU8l0I0Inap7TSPhv14Ex2sF89LkT8MbcDM3S3QL4urYsQj37zOKRDTFzE96TmI="}}

View File

@ -444,4 +444,42 @@ test "Hashtag records are created with Object record and updated on its change"
Enum.sort_by(object.hashtags, & &1.name)
end
end
describe "get_emoji_reactions/1" do
test "3-tuple current format" do
object = %Object{
data: %{
"reactions" => [
["x", ["https://some/user"], "https://some/emoji"]
]
}
}
assert Object.get_emoji_reactions(object) == object.data["reactions"]
end
test "2-tuple legacy format" do
object = %Object{
data: %{
"reactions" => [
["x", ["https://some/user"]]
]
}
}
assert Object.get_emoji_reactions(object) == [["x", ["https://some/user"], nil]]
end
test "Map format" do
object = %Object{
data: %{
"reactions" => %{
"x" => ["https://some/user"]
}
}
}
assert Object.get_emoji_reactions(object) == [["x", ["https://some/user"], nil]]
end
end
end

View File

@ -0,0 +1,50 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Transmogrifier.ImageHandlingTest do
use Oban.Testing, repo: Pleroma.Repo
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.Transmogrifier
test "Hubzilla Image object" do
Tesla.Mock.mock(fn
%{url: "https://hub.somaton.com/channel/testc6"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/hubzilla-actor.json"),
headers: HttpRequestMock.activitypub_object_headers()
}
end)
data = File.read!("test/fixtures/hubzilla-create-image.json") |> Poison.decode!()
{:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
assert object = Object.normalize(activity, fetch: false)
assert object.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
assert object.data["cc"] == ["https://hub.somaton.com/followers/testc6"]
assert object.data["attachment"] == [
%{
"mediaType" => "image/jpeg",
"type" => "Link",
"url" => [
%{
"height" => 2200,
"href" =>
"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-0.jpg",
"mediaType" => "image/jpeg",
"type" => "Link",
"width" => 2200
}
]
}
]
end
end

View File

@ -587,15 +587,38 @@ test "removes actor from announcements" do
end
describe "get_cached_emoji_reactions/1" do
test "returns the data or an emtpy list" do
test "returns the normalized data or an emtpy list" do
object = insert(:note)
assert Utils.get_cached_emoji_reactions(object) == []
object = insert(:note, data: %{"reactions" => [["x", ["lain"]]]})
assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"]]]
assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"], nil]]
object = insert(:note, data: %{"reactions" => %{}})
assert Utils.get_cached_emoji_reactions(object) == []
end
end
describe "add_emoji_reaction_to_object/1" do
test "works with legacy 2-tuple format" do
user = insert(:user)
other_user = insert(:user)
third_user = insert(:user)
note =
insert(:note,
user: user,
data: %{
"reactions" => [["😿", [other_user.ap_id]]]
}
)
_activity = insert(:note_activity, user: user, note: note)
Utils.add_emoji_reaction_to_object(
%Activity{data: %{"content" => "😿", "actor" => third_user.ap_id}},
note
)
end
end
end

View File

@ -74,6 +74,27 @@ test "has an emoji reaction list" do
]
end
test "works with legacy-formatted reactions" do
user = insert(:user)
other_user = insert(:user)
note =
insert(:note,
user: user,
data: %{
"reactions" => [["😿", [other_user.ap_id]]]
}
)
activity = insert(:note_activity, user: user, note: note)
status = StatusView.render("show.json", activity: activity, for: user)
assert status[:pleroma][:emoji_reactions] == [
%{name: "😿", count: 1, me: false, url: nil, account_ids: [other_user.id]}
]
end
test "works correctly with badly formatted emojis" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "yo"})

View File

@ -245,6 +245,38 @@ test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do
result
end
test "GET /api/v1/pleroma/statuses/:id/reactions with legacy format", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
note =
insert(:note,
user: user,
data: %{
"reactions" => [["😿", [other_user.ap_id]]]
}
)
activity = insert(:note_activity, user: user, note: note)
result =
conn
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
|> json_response_and_validate_schema(200)
other_user_id = other_user.id
assert [
%{
"name" => "😿",
"count" => 1,
"me" => false,
"url" => nil,
"accounts" => [%{"id" => ^other_user_id}]
}
] = result
end
test "GET /api/v1/pleroma/statuses/:id/reactions?with_muted=true", %{conn: conn} do
user = insert(:user)
user2 = insert(:user)

22
tools/check-changelog Normal file
View File

@ -0,0 +1,22 @@
#!/bin/sh
echo "looking for change log of $CI_MERGE_REQUEST_IID"
count=0
for i in add remove fix security skip; do
[ -f changelog.d/"$CI_MERGE_REQUEST_IID"."$i" ]
retcode=$?
if [ $retcode -eq 0 ]; then
echo "found $CI_MERGE_REQUEST_IID.$i"
count=$(( count + 1 ))
else
echo "no $CI_MERGE_REQUEST_IID.$i"
fi
done
if [ $count -gt 0 ]; then
echo "ok"
exit 0
else
echo "must have a changelog entry or explicitly skip it"
exit 1
fi