Merge branch 'develop' of ssh://git.pleroma.social:2222/pleroma/pleroma into froth
This commit is contained in:
commit
35a748e959
22 changed files with 273 additions and 38 deletions
|
@ -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:
|
||||
|
|
|
@ -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
0
changelog.d/3739.skip
Normal 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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
|
@ -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
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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()) ::
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
1
test/fixtures/hubzilla-actor.json
vendored
Normal 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="}}
|
1
test/fixtures/hubzilla-create-image.json
vendored
Normal file
1
test/fixtures/hubzilla-create-image.json
vendored
Normal 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="}}
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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"})
|
||||
|
|
|
@ -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
22
tools/check-changelog
Normal 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
|
Loading…
Reference in a new issue