2018-12-23 20:11:29 +00:00
# Pleroma: A lightweight social networking server
2020-03-02 05:08:45 +00:00
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
2018-12-23 20:11:29 +00:00
# SPDX-License-Identifier: AGPL-3.0-only
2018-02-15 19:00:06 +00:00
defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
2020-01-25 07:47:30 +00:00
use Oban.Testing , repo : Pleroma.Repo
2018-02-15 19:00:06 +00:00
use Pleroma.DataCase
2020-01-25 07:47:30 +00:00
2019-03-05 02:52:23 +00:00
alias Pleroma.Activity
2019-03-14 19:04:33 +00:00
alias Pleroma.Object
2019-04-17 14:03:35 +00:00
alias Pleroma.Object.Fetcher
2019-08-13 17:20:26 +00:00
alias Pleroma.Tests.ObanHelpers
2019-03-05 02:52:23 +00:00
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
2018-02-15 19:00:06 +00:00
alias Pleroma.Web.ActivityPub.Transmogrifier
2019-10-23 19:27:22 +00:00
alias Pleroma.Web.AdminAPI.AccountView
2019-06-29 17:04:50 +00:00
alias Pleroma.Web.CommonAPI
2018-02-17 19:13:12 +00:00
2019-06-29 17:04:50 +00:00
import Mock
2018-02-17 13:11:20 +00:00
import Pleroma.Factory
2019-06-16 11:42:29 +00:00
import ExUnit.CaptureLog
2018-02-15 19:00:06 +00:00
2018-12-04 11:01:39 +00:00
setup_all do
Tesla.Mock . mock_global ( fn env -> apply ( HttpRequestMock , :request , [ env ] ) end )
2018-12-03 15:53:22 +00:00
:ok
end
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :instance , :max_remote_account_fields ] )
2019-08-21 18:24:35 +00:00
2018-02-15 19:00:06 +00:00
describe " handle_incoming " do
2018-02-19 16:37:45 +00:00
test " it ignores an incoming notice if we already have it " do
activity = insert ( :note_activity )
2018-03-30 13:01:53 +00:00
data =
File . read! ( " test/fixtures/mastodon-post-activity.json " )
|> Poison . decode! ( )
2019-07-08 16:53:02 +00:00
|> Map . put ( " object " , Object . normalize ( activity ) . data )
2018-02-19 16:37:45 +00:00
{ :ok , returned_activity } = Transmogrifier . handle_incoming ( data )
assert activity == returned_activity
end
2019-11-28 09:44:48 +00:00
@tag capture_log : true
2020-02-15 17:41:38 +00:00
test " it fetches reply-to activities if we don't have them " do
2018-03-30 13:01:53 +00:00
data =
File . read! ( " test/fixtures/mastodon-post-activity.json " )
|> Poison . decode! ( )
2018-02-21 14:22:24 +00:00
2018-03-30 13:01:53 +00:00
object =
data [ " object " ]
|> Map . put ( " inReplyTo " , " https://shitposter.club/notice/2827873 " )
2018-02-21 14:22:24 +00:00
2019-06-29 17:04:50 +00:00
data = Map . put ( data , " object " , object )
2018-02-21 14:22:24 +00:00
{ :ok , returned_activity } = Transmogrifier . handle_incoming ( data )
2019-07-09 18:46:16 +00:00
returned_object = Object . normalize ( returned_activity , false )
2018-02-21 14:22:24 +00:00
2018-03-30 13:01:53 +00:00
assert activity =
2019-01-21 06:14:20 +00:00
Activity . get_create_by_object_ap_id (
2018-03-30 13:01:53 +00:00
" tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment "
)
2018-11-25 22:31:07 +00:00
assert returned_object . data [ " inReplyToAtomUri " ] == " https://shitposter.club/notice/2827873 "
2018-02-25 09:56:01 +00:00
end
2020-02-15 17:41:38 +00:00
test " it does not fetch reply-to activities beyond max replies depth limit " do
2019-06-29 17:04:50 +00:00
data =
File . read! ( " test/fixtures/mastodon-post-activity.json " )
|> Poison . decode! ( )
object =
data [ " object " ]
|> Map . put ( " inReplyTo " , " https://shitposter.club/notice/2827873 " )
data = Map . put ( data , " object " , object )
with_mock Pleroma.Web.Federator ,
2020-02-15 17:41:38 +00:00
allowed_thread_distance? : fn _ -> false end do
2019-06-29 17:04:50 +00:00
{ :ok , returned_activity } = Transmogrifier . handle_incoming ( data )
2019-07-09 18:46:16 +00:00
returned_object = Object . normalize ( returned_activity , false )
2019-06-29 17:04:50 +00:00
refute Activity . get_create_by_object_ap_id (
" tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment "
)
assert returned_object . data [ " inReplyToAtomUri " ] ==
" https://shitposter.club/notice/2827873 "
end
end
2019-06-07 17:40:38 +00:00
test " it does not crash if the object in inReplyTo can't be fetched " do
data =
File . read! ( " test/fixtures/mastodon-post-activity.json " )
|> Poison . decode! ( )
object =
data [ " object " ]
2019-06-07 17:48:25 +00:00
|> Map . put ( " inReplyTo " , " https://404.site/whatever " )
2019-06-07 17:40:38 +00:00
data =
data
|> Map . put ( " object " , object )
2019-06-16 11:42:29 +00:00
assert capture_log ( fn ->
{ :ok , _returned_activity } = Transmogrifier . handle_incoming ( data )
2019-09-12 17:29:08 +00:00
end ) =~ " [error] Couldn't fetch \" https://404.site/whatever \" , error: nil "
2019-06-07 17:40:38 +00:00
end
2018-02-15 19:00:06 +00:00
test " it works for incoming notices " do
2018-03-30 13:01:53 +00:00
data = File . read! ( " test/fixtures/mastodon-post-activity.json " ) |> Poison . decode! ( )
2018-02-15 19:00:06 +00:00
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
2018-03-30 13:01:53 +00:00
assert data [ " id " ] ==
" http://mastodon.example.org/users/admin/statuses/99512778738411822/activity "
assert data [ " context " ] ==
" tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation "
2018-02-15 19:00:06 +00:00
assert data [ " to " ] == [ " https://www.w3.org/ns/activitystreams # Public " ]
2018-03-30 13:01:53 +00:00
2018-02-15 19:00:06 +00:00
assert data [ " cc " ] == [
2018-03-30 13:01:53 +00:00
" http://mastodon.example.org/users/admin/followers " ,
" http://localtesting.pleroma.lol/users/lain "
]
2018-02-15 19:00:06 +00:00
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
2019-07-08 16:53:02 +00:00
object_data = Object . normalize ( data [ " object " ] ) . data
assert object_data [ " id " ] ==
" http://mastodon.example.org/users/admin/statuses/99512778738411822 "
2018-02-15 19:00:06 +00:00
2019-07-08 16:53:02 +00:00
assert object_data [ " to " ] == [ " https://www.w3.org/ns/activitystreams # Public " ]
2018-03-30 13:01:53 +00:00
2019-07-08 16:53:02 +00:00
assert object_data [ " cc " ] == [
2018-03-30 13:01:53 +00:00
" http://mastodon.example.org/users/admin/followers " ,
" http://localtesting.pleroma.lol/users/lain "
]
2019-07-08 16:53:02 +00:00
assert object_data [ " actor " ] == " http://mastodon.example.org/users/admin "
assert object_data [ " attributedTo " ] == " http://mastodon.example.org/users/admin "
2018-03-30 13:01:53 +00:00
2019-07-08 16:53:02 +00:00
assert object_data [ " context " ] ==
2018-03-30 13:01:53 +00:00
" tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation "
2019-07-08 16:53:02 +00:00
assert object_data [ " sensitive " ] == true
2018-04-22 08:01:10 +00:00
2019-07-08 16:53:02 +00:00
user = User . get_cached_by_ap_id ( object_data [ " actor " ] )
2018-04-22 08:01:10 +00:00
2019-10-16 18:59:21 +00:00
assert user . note_count == 1
2018-02-15 19:00:06 +00:00
end
2018-02-17 13:55:44 +00:00
2018-03-24 21:39:37 +00:00
test " it works for incoming notices with hashtags " do
2018-03-30 13:01:53 +00:00
data = File . read! ( " test/fixtures/mastodon-post-activity-hashtag.json " ) |> Poison . decode! ( )
2018-03-24 21:39:37 +00:00
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
2018-11-25 22:31:07 +00:00
object = Object . normalize ( data [ " object " ] )
assert Enum . at ( object . data [ " tag " ] , 2 ) == " moo "
2018-03-24 21:39:37 +00:00
end
2019-05-15 17:10:16 +00:00
test " it works for incoming questions " do
data = File . read! ( " test/fixtures/mastodon-question-activity.json " ) |> Poison . decode! ( )
{ :ok , % Activity { local : false } = activity } = Transmogrifier . handle_incoming ( data )
object = Object . normalize ( activity )
assert Enum . all? ( object . data [ " oneOf " ] , fn choice ->
choice [ " name " ] in [
" Dunno " ,
" Everyone knows that! " ,
" 25 char limit is dumb " ,
" I can't even fit a funny "
]
end )
end
2019-09-27 12:40:31 +00:00
test " it works for incoming listens " do
data = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
" to " = > [ " https://www.w3.org/ns/activitystreams # Public " ] ,
" cc " = > [ ] ,
" type " = > " Listen " ,
" id " = > " http://mastodon.example.org/users/admin/listens/1234/activity " ,
" actor " = > " http://mastodon.example.org/users/admin " ,
" object " = > %{
" type " = > " Audio " ,
" id " = > " http://mastodon.example.org/users/admin/listens/1234 " ,
" attributedTo " = > " http://mastodon.example.org/users/admin " ,
" title " = > " lain radio episode 1 " ,
" artist " = > " lain " ,
" album " = > " lain radio " ,
" length " = > 180_000
}
}
{ :ok , % Activity { local : false } = activity } = Transmogrifier . handle_incoming ( data )
object = Object . normalize ( activity )
assert object . data [ " title " ] == " lain radio episode 1 "
assert object . data [ " artist " ] == " lain "
assert object . data [ " album " ] == " lain radio "
assert object . data [ " length " ] == 180_000
end
2019-05-22 18:17:57 +00:00
test " it rewrites Note votes to Answers and increments vote counters on question activities " do
2019-05-21 11:12:10 +00:00
user = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( user , %{
" status " = > " suya... " ,
" poll " = > %{ " options " = > [ " suya " , " suya. " , " suya.. " ] , " expires_in " = > 10 }
} )
object = Object . normalize ( activity )
data =
File . read! ( " test/fixtures/mastodon-vote.json " )
|> Poison . decode! ( )
|> Kernel . put_in ( [ " to " ] , user . ap_id )
|> Kernel . put_in ( [ " object " , " inReplyTo " ] , object . data [ " id " ] )
|> Kernel . put_in ( [ " object " , " to " ] , user . ap_id )
2019-05-22 18:17:57 +00:00
{ :ok , % Activity { local : false } = activity } = Transmogrifier . handle_incoming ( data )
answer_object = Object . normalize ( activity )
assert answer_object . data [ " type " ] == " Answer "
2019-05-21 11:12:10 +00:00
object = Object . get_by_ap_id ( object . data [ " id " ] )
assert Enum . any? (
object . data [ " oneOf " ] ,
fn
%{ " name " = > " suya.. " , " replies " = > %{ " totalItems " = > 1 } } -> true
_ -> false
end
)
end
2018-06-18 22:11:48 +00:00
test " it works for incoming notices with contentMap " do
data =
File . read! ( " test/fixtures/mastodon-post-activity-contentmap.json " ) |> Poison . decode! ( )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
2018-11-25 22:31:07 +00:00
object = Object . normalize ( data [ " object " ] )
2018-06-18 22:11:48 +00:00
2018-11-25 22:31:07 +00:00
assert object . data [ " content " ] ==
2018-06-18 22:11:48 +00:00
" <p><span class= \" h-card \" ><a href= \" http://localtesting.pleroma.lol/users/lain \" class= \" u-url mention \" >@<span>lain</span></a></span></p> "
end
2018-08-14 17:07:01 +00:00
test " it works for incoming notices with to/cc not being an array (kroeg) " do
data = File . read! ( " test/fixtures/kroeg-post-activity.json " ) |> Poison . decode! ( )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
2018-11-25 22:31:07 +00:00
object = Object . normalize ( data [ " object " ] )
2018-08-14 17:07:01 +00:00
2018-11-25 22:31:07 +00:00
assert object . data [ " content " ] ==
2018-08-14 17:07:01 +00:00
" <p>henlo from my Psion netBook</p><p>message sent from my Psion netBook</p> "
end
2018-09-27 07:14:15 +00:00
test " it works for incoming announces with actor being inlined (kroeg) " do
data = File . read! ( " test/fixtures/kroeg-announce-with-inline-actor.json " ) |> Poison . decode! ( )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " actor " ] == " https://puckipedia.com/ "
end
2018-09-26 09:27:00 +00:00
2018-09-26 05:48:34 +00:00
test " it works for incoming notices with tag not being an array (kroeg) " do
2018-09-26 09:27:00 +00:00
data = File . read! ( " test/fixtures/kroeg-array-less-emoji.json " ) |> Poison . decode! ( )
2018-09-26 05:48:34 +00:00
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
2018-11-25 22:31:07 +00:00
object = Object . normalize ( data [ " object " ] )
2018-09-26 05:48:34 +00:00
2018-11-25 22:31:07 +00:00
assert object . data [ " emoji " ] == %{
2018-09-26 05:48:34 +00:00
" icon_e_smile " = > " https://puckipedia.com/forum/images/smilies/icon_e_smile.png "
}
2018-09-26 09:27:00 +00:00
data = File . read! ( " test/fixtures/kroeg-array-less-hashtag.json " ) |> Poison . decode! ( )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
2018-11-25 22:31:07 +00:00
object = Object . normalize ( data [ " object " ] )
2018-09-26 09:27:00 +00:00
2018-11-25 22:31:07 +00:00
assert " test " in object . data [ " tag " ]
2018-09-26 05:48:34 +00:00
end
2018-11-01 10:27:22 +00:00
test " it works for incoming notices with url not being a string (prismo) " do
data = File . read! ( " test/fixtures/prismo-url-map.json " ) |> Poison . decode! ( )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
2018-11-25 22:31:07 +00:00
object = Object . normalize ( data [ " object " ] )
2018-11-01 10:27:22 +00:00
2018-11-25 22:31:07 +00:00
assert object . data [ " url " ] == " https://prismo.news/posts/83 "
2018-11-01 10:27:22 +00:00
end
2018-11-17 16:18:40 +00:00
test " it cleans up incoming notices which are not really DMs " do
user = insert ( :user )
other_user = insert ( :user )
to = [ user . ap_id , other_user . ap_id ]
data =
File . read! ( " test/fixtures/mastodon-post-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " to " , to )
|> Map . put ( " cc " , [ ] )
object =
data [ " object " ]
|> Map . put ( " to " , to )
|> Map . put ( " cc " , [ ] )
data = Map . put ( data , " object " , object )
2019-04-17 12:46:59 +00:00
{ :ok , % Activity { data : data , local : false } = activity } = Transmogrifier . handle_incoming ( data )
2018-11-17 16:18:40 +00:00
assert data [ " to " ] == [ ]
assert data [ " cc " ] == to
2019-04-17 12:46:59 +00:00
object_data = Object . normalize ( activity ) . data
2018-11-17 16:18:40 +00:00
2019-04-17 12:46:59 +00:00
assert object_data [ " to " ] == [ ]
assert object_data [ " cc " ] == to
2018-11-17 16:18:40 +00:00
end
2018-02-17 19:13:12 +00:00
test " it works for incoming likes " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hello " } )
2018-02-17 13:55:44 +00:00
2018-03-30 13:01:53 +00:00
data =
2018-04-21 07:43:53 +00:00
File . read! ( " test/fixtures/mastodon-like.json " )
|> Poison . decode! ( )
2018-11-25 22:31:07 +00:00
|> Map . put ( " object " , activity . data [ " object " ] )
2018-02-17 19:13:12 +00:00
2019-10-17 17:35:31 +00:00
{ :ok , % Activity { data : data , local : false } = activity } = Transmogrifier . handle_incoming ( data )
refute Enum . empty? ( activity . recipients )
2018-02-17 19:13:12 +00:00
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
assert data [ " type " ] == " Like "
assert data [ " id " ] == " http://mastodon.example.org/users/admin # likes/2 "
2018-11-25 22:31:07 +00:00
assert data [ " object " ] == activity . data [ " object " ]
2018-02-17 13:55:44 +00:00
end
2018-02-17 20:57:31 +00:00
2020-02-06 17:09:57 +00:00
test " it works for incoming misskey likes, turning them into EmojiReacts " do
2019-10-04 15:01:04 +00:00
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hello " } )
data =
File . read! ( " test/fixtures/misskey-like.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , activity . data [ " object " ] )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " actor " ] == data [ " actor " ]
2020-02-06 17:09:57 +00:00
assert data [ " type " ] == " EmojiReact "
2019-10-04 15:01:04 +00:00
assert data [ " id " ] == data [ " id " ]
assert data [ " object " ] == activity . data [ " object " ]
assert data [ " content " ] == " 🍮 "
end
2020-02-06 17:09:57 +00:00
test " it works for incoming misskey likes that contain unicode emojis, turning them into EmojiReacts " do
2019-10-05 08:45:42 +00:00
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hello " } )
data =
File . read! ( " test/fixtures/misskey-like.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , activity . data [ " object " ] )
|> Map . put ( " _misskey_reaction " , " ⭐ " )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " actor " ] == data [ " actor " ]
2020-02-06 17:09:57 +00:00
assert data [ " type " ] == " EmojiReact "
2019-10-05 08:45:42 +00:00
assert data [ " id " ] == data [ " id " ]
assert data [ " object " ] == activity . data [ " object " ]
assert data [ " content " ] == " ⭐ "
end
2019-08-26 21:47:31 +00:00
test " it works for incoming emoji reactions " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hello " } )
data =
File . read! ( " test/fixtures/emoji-reaction.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , activity . data [ " object " ] )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
2020-02-06 17:09:57 +00:00
assert data [ " type " ] == " EmojiReact "
2019-08-26 21:47:31 +00:00
assert data [ " id " ] == " http://mastodon.example.org/users/admin # reactions/2 "
assert data [ " object " ] == activity . data [ " object " ]
assert data [ " content " ] == " 👌 "
end
2020-01-30 15:07:37 +00:00
test " it reject invalid emoji reactions " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hello " } )
data =
File . read! ( " test/fixtures/emoji-reaction-too-long.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , activity . data [ " object " ] )
assert :error = Transmogrifier . handle_incoming ( data )
data =
File . read! ( " test/fixtures/emoji-reaction-no-emoji.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , activity . data [ " object " ] )
assert :error = Transmogrifier . handle_incoming ( data )
end
2019-10-03 16:37:23 +00:00
test " it works for incoming emoji reaction undos " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hello " } )
{ :ok , reaction_activity , _object } = CommonAPI . react_with_emoji ( activity . id , user , " 👌 " )
data =
File . read! ( " test/fixtures/mastodon-undo-like.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , reaction_activity . data [ " id " ] )
|> Map . put ( " actor " , user . ap_id )
{ :ok , activity } = Transmogrifier . handle_incoming ( data )
assert activity . actor == user . ap_id
assert activity . data [ " id " ] == data [ " id " ]
assert activity . data [ " type " ] == " Undo "
end
2018-05-19 13:22:43 +00:00
test " it returns an error for incoming unlikes wihout a like activity " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " leave a like pls " } )
data =
File . read! ( " test/fixtures/mastodon-undo-like.json " )
|> Poison . decode! ( )
2018-11-25 22:31:07 +00:00
|> Map . put ( " object " , activity . data [ " object " ] )
2018-05-19 13:22:43 +00:00
assert Transmogrifier . handle_incoming ( data ) == :error
end
test " it works for incoming unlikes with an existing like activity " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " leave a like pls " } )
like_data =
File . read! ( " test/fixtures/mastodon-like.json " )
|> Poison . decode! ( )
2018-11-25 22:31:07 +00:00
|> Map . put ( " object " , activity . data [ " object " ] )
2018-05-19 13:22:43 +00:00
{ :ok , % Activity { data : like_data , local : false } } = Transmogrifier . handle_incoming ( like_data )
data =
File . read! ( " test/fixtures/mastodon-undo-like.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , like_data )
|> Map . put ( " actor " , like_data [ " actor " ] )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
assert data [ " type " ] == " Undo "
assert data [ " id " ] == " http://mastodon.example.org/users/admin # likes/2/undo "
assert data [ " object " ] [ " id " ] == " http://mastodon.example.org/users/admin # likes/2 "
end
2019-09-30 16:13:05 +00:00
test " it works for incoming unlikes with an existing like activity and a compact object " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " leave a like pls " } )
like_data =
File . read! ( " test/fixtures/mastodon-like.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , activity . data [ " object " ] )
{ :ok , % Activity { data : like_data , local : false } } = Transmogrifier . handle_incoming ( like_data )
data =
File . read! ( " test/fixtures/mastodon-undo-like.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , like_data [ " id " ] )
|> Map . put ( " actor " , like_data [ " actor " ] )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
assert data [ " type " ] == " Undo "
assert data [ " id " ] == " http://mastodon.example.org/users/admin # likes/2/undo "
assert data [ " object " ] [ " id " ] == " http://mastodon.example.org/users/admin # likes/2 "
end
2018-02-17 20:57:31 +00:00
test " it works for incoming announces " do
2018-03-30 13:01:53 +00:00
data = File . read! ( " test/fixtures/mastodon-announce.json " ) |> Poison . decode! ( )
2018-02-17 20:57:31 +00:00
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
assert data [ " type " ] == " Announce "
2018-03-30 13:01:53 +00:00
assert data [ " id " ] ==
" http://mastodon.example.org/users/admin/statuses/99542391527669785/activity "
assert data [ " object " ] ==
" http://mastodon.example.org/users/admin/statuses/99541947525187367 "
2018-02-18 10:24:54 +00:00
2019-01-21 06:14:20 +00:00
assert Activity . get_create_by_object_ap_id ( data [ " object " ] )
2018-02-18 10:24:54 +00:00
end
test " it works for incoming announces with an existing activity " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hey " } )
2018-03-30 13:01:53 +00:00
data =
File . read! ( " test/fixtures/mastodon-announce.json " )
|> Poison . decode! ( )
2018-11-25 22:31:07 +00:00
|> Map . put ( " object " , activity . data [ " object " ] )
2018-02-18 10:24:54 +00:00
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
assert data [ " type " ] == " Announce "
2018-03-30 13:01:53 +00:00
assert data [ " id " ] ==
" http://mastodon.example.org/users/admin/statuses/99542391527669785/activity "
2018-11-25 22:31:07 +00:00
assert data [ " object " ] == activity . data [ " object " ]
2018-02-18 10:24:54 +00:00
2019-01-21 06:14:20 +00:00
assert Activity . get_create_by_object_ap_id ( data [ " object " ] ) . id == activity . id
2018-02-17 20:57:31 +00:00
end
2018-02-25 15:14:25 +00:00
2019-10-02 11:18:51 +00:00
test " it works for incoming announces with an inlined activity " do
data =
File . read! ( " test/fixtures/mastodon-announce-private.json " )
|> Poison . decode! ( )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
assert data [ " type " ] == " Announce "
assert data [ " id " ] ==
" http://mastodon.example.org/users/admin/statuses/99542391527669785/activity "
object = Object . normalize ( data [ " object " ] )
assert object . data [ " id " ] == " http://mastodon.example.org/@admin/99541947525187368 "
assert object . data [ " content " ] == " this is a private toot "
end
2019-11-28 09:44:48 +00:00
@tag capture_log : true
2019-10-05 10:46:06 +00:00
test " it rejects incoming announces with an inlined activity from another origin " do
data =
File . read! ( " test/fixtures/bogus-mastodon-announce.json " )
|> Poison . decode! ( )
assert :error = Transmogrifier . handle_incoming ( data )
end
2019-01-18 22:32:01 +00:00
test " it does not clobber the addressing on announce activities " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hey " } )
data =
File . read! ( " test/fixtures/mastodon-announce.json " )
|> Poison . decode! ( )
2019-04-17 12:46:59 +00:00
|> Map . put ( " object " , Object . normalize ( activity ) . data [ " id " ] )
2019-01-18 22:32:01 +00:00
|> Map . put ( " to " , [ " http://mastodon.example.org/users/admin/followers " ] )
|> Map . put ( " cc " , [ ] )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " to " ] == [ " http://mastodon.example.org/users/admin/followers " ]
end
2019-03-19 17:49:29 +00:00
test " it ensures that as:Public activities make it to their followers collection " do
user = insert ( :user )
data =
File . read! ( " test/fixtures/mastodon-post-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " actor " , user . ap_id )
|> Map . put ( " to " , [ " https://www.w3.org/ns/activitystreams # Public " ] )
|> Map . put ( " cc " , [ ] )
object =
data [ " object " ]
|> Map . put ( " attributedTo " , user . ap_id )
|> Map . put ( " to " , [ " https://www.w3.org/ns/activitystreams # Public " ] )
|> Map . put ( " cc " , [ ] )
2019-07-14 17:49:12 +00:00
|> Map . put ( " id " , user . ap_id <> " /activities/12345678 " )
2019-03-19 17:49:29 +00:00
data = Map . put ( data , " object " , object )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " cc " ] == [ User . ap_followers ( user ) ]
end
2019-03-19 17:53:40 +00:00
test " it ensures that address fields become lists " do
user = insert ( :user )
data =
File . read! ( " test/fixtures/mastodon-post-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " actor " , user . ap_id )
|> Map . put ( " to " , nil )
|> Map . put ( " cc " , nil )
object =
data [ " object " ]
|> Map . put ( " attributedTo " , user . ap_id )
|> Map . put ( " to " , nil )
|> Map . put ( " cc " , nil )
2019-07-14 17:49:12 +00:00
|> Map . put ( " id " , user . ap_id <> " /activities/12345678 " )
2019-03-19 17:53:40 +00:00
data = Map . put ( data , " object " , object )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert ! is_nil ( data [ " to " ] )
assert ! is_nil ( data [ " cc " ] )
2018-02-17 20:57:31 +00:00
end
2018-02-25 15:14:25 +00:00
2019-08-10 18:47:40 +00:00
test " it strips internal likes " do
data =
File . read! ( " test/fixtures/mastodon-post-activity.json " )
|> Poison . decode! ( )
likes = %{
" first " = >
" http://mastodon.example.org/objects/dbdbc507-52c8-490d-9b7c-1e1d52e5c132/likes?page=1 " ,
" id " = > " http://mastodon.example.org/objects/dbdbc507-52c8-490d-9b7c-1e1d52e5c132/likes " ,
" totalItems " = > 3 ,
" type " = > " OrderedCollection "
}
object = Map . put ( data [ " object " ] , " likes " , likes )
data = Map . put ( data , " object " , object )
{ :ok , % Activity { object : object } } = Transmogrifier . handle_incoming ( data )
refute Map . has_key? ( object . data , " likes " )
end
2019-09-12 16:59:13 +00:00
test " it strips internal reactions " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " # cofe " } )
{ :ok , _ , _ } = CommonAPI . react_with_emoji ( activity . id , user , " 📢 " )
%{ object : object } = Activity . get_by_id_with_object ( activity . id )
assert Map . has_key? ( object . data , " reactions " )
assert Map . has_key? ( object . data , " reaction_count " )
object_data = Transmogrifier . strip_internal_fields ( object . data )
refute Map . has_key? ( object_data , " reactions " )
refute Map . has_key? ( object_data , " reaction_count " )
end
2018-02-25 15:14:25 +00:00
test " it works for incoming update activities " do
2018-03-30 13:01:53 +00:00
data = File . read! ( " test/fixtures/mastodon-post-activity.json " ) |> Poison . decode! ( )
2018-02-25 15:14:25 +00:00
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
2018-03-30 13:01:53 +00:00
update_data = File . read! ( " test/fixtures/mastodon-update.json " ) |> Poison . decode! ( )
object =
update_data [ " object " ]
|> Map . put ( " actor " , data [ " actor " ] )
|> Map . put ( " id " , data [ " actor " ] )
2018-02-25 15:14:25 +00:00
2018-03-30 13:01:53 +00:00
update_data =
update_data
|> Map . put ( " actor " , data [ " actor " ] )
|> Map . put ( " object " , object )
2018-02-25 15:14:25 +00:00
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( update_data )
2019-10-05 12:49:45 +00:00
assert data [ " id " ] == update_data [ " id " ]
2018-02-25 15:14:25 +00:00
user = User . get_cached_by_ap_id ( data [ " actor " ] )
assert user . name == " gargle "
2018-03-30 13:01:53 +00:00
assert user . avatar [ " url " ] == [
%{
" href " = >
" https://cd.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg "
}
]
2019-10-16 18:59:21 +00:00
assert user . banner [ " url " ] == [
2018-03-30 13:01:53 +00:00
%{
" href " = >
" https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png "
}
]
2018-02-25 15:14:25 +00:00
assert user . bio == " <p>Some bio</p> "
end
2018-03-03 17:37:40 +00:00
2019-10-25 12:14:18 +00:00
test " it works with alsoKnownAs " do
{ :ok , % Activity { data : %{ " actor " = > actor } } } =
" test/fixtures/mastodon-post-activity.json "
|> File . read! ( )
|> Poison . decode! ( )
|> Transmogrifier . handle_incoming ( )
assert User . get_cached_by_ap_id ( actor ) . also_known_as == [ " http://example.org/users/foo " ]
{ :ok , _activity } =
" test/fixtures/mastodon-update.json "
|> File . read! ( )
|> Poison . decode! ( )
|> Map . put ( " actor " , actor )
|> Map . update! ( " object " , fn object ->
object
|> Map . put ( " actor " , actor )
|> Map . put ( " id " , actor )
|> Map . put ( " alsoKnownAs " , [
" http://mastodon.example.org/users/foo " ,
" http://example.org/users/bar "
] )
end )
|> Transmogrifier . handle_incoming ( )
assert User . get_cached_by_ap_id ( actor ) . also_known_as == [
" http://mastodon.example.org/users/foo " ,
" http://example.org/users/bar "
]
end
2019-07-29 12:01:15 +00:00
test " it works with custom profile fields " do
{ :ok , activity } =
" test/fixtures/mastodon-post-activity.json "
|> File . read! ( )
|> Poison . decode! ( )
|> Transmogrifier . handle_incoming ( )
user = User . get_cached_by_ap_id ( activity . actor )
2020-04-06 08:44:48 +00:00
assert user . fields == [
2019-08-06 11:21:25 +00:00
%{ " name " = > " foo " , " value " = > " bar " } ,
%{ " name " = > " foo1 " , " value " = > " bar1 " }
2019-07-29 12:01:15 +00:00
]
update_data = File . read! ( " test/fixtures/mastodon-update.json " ) |> Poison . decode! ( )
object =
update_data [ " object " ]
|> Map . put ( " actor " , user . ap_id )
|> Map . put ( " id " , user . ap_id )
update_data =
update_data
|> Map . put ( " actor " , user . ap_id )
|> Map . put ( " object " , object )
{ :ok , _update_activity } = Transmogrifier . handle_incoming ( update_data )
user = User . get_cached_by_ap_id ( user . ap_id )
2020-04-06 08:44:48 +00:00
assert user . fields == [
2019-08-07 11:14:22 +00:00
%{ " name " = > " foo " , " value " = > " updated " } ,
%{ " name " = > " foo1 " , " value " = > " updated " }
]
Pleroma.Config . put ( [ :instance , :max_remote_account_fields ] , 2 )
update_data =
put_in ( update_data , [ " object " , " attachment " ] , [
%{ " name " = > " foo " , " type " = > " PropertyValue " , " value " = > " bar " } ,
%{ " name " = > " foo11 " , " type " = > " PropertyValue " , " value " = > " bar11 " } ,
%{ " name " = > " foo22 " , " type " = > " PropertyValue " , " value " = > " bar22 " }
] )
{ :ok , _ } = Transmogrifier . handle_incoming ( update_data )
user = User . get_cached_by_ap_id ( user . ap_id )
2020-04-06 08:44:48 +00:00
assert user . fields == [
2019-08-06 11:21:25 +00:00
%{ " name " = > " foo " , " value " = > " updated " } ,
%{ " name " = > " foo1 " , " value " = > " updated " }
2019-07-29 12:01:15 +00:00
]
2019-08-25 17:00:41 +00:00
update_data = put_in ( update_data , [ " object " , " attachment " ] , [ ] )
{ :ok , _ } = Transmogrifier . handle_incoming ( update_data )
user = User . get_cached_by_ap_id ( user . ap_id )
2020-04-06 08:44:48 +00:00
assert user . fields == [ ]
2019-07-29 12:01:15 +00:00
end
2018-06-08 02:28:08 +00:00
test " it works for incoming update activities which lock the account " do
data = File . read! ( " test/fixtures/mastodon-post-activity.json " ) |> Poison . decode! ( )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
update_data = File . read! ( " test/fixtures/mastodon-update.json " ) |> Poison . decode! ( )
object =
update_data [ " object " ]
|> Map . put ( " actor " , data [ " actor " ] )
|> Map . put ( " id " , data [ " actor " ] )
|> Map . put ( " manuallyApprovesFollowers " , true )
update_data =
update_data
|> Map . put ( " actor " , data [ " actor " ] )
|> Map . put ( " object " , object )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( update_data )
user = User . get_cached_by_ap_id ( data [ " actor " ] )
2019-10-16 18:59:21 +00:00
assert user . locked == true
2018-06-08 02:28:08 +00:00
end
2018-05-11 19:30:47 +00:00
test " it works for incoming unannounces with an existing notice " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hey " } )
announce_data =
File . read! ( " test/fixtures/mastodon-announce.json " )
|> Poison . decode! ( )
2018-11-25 22:31:07 +00:00
|> Map . put ( " object " , activity . data [ " object " ] )
2018-05-11 19:30:47 +00:00
{ :ok , % Activity { data : announce_data , local : false } } =
Transmogrifier . handle_incoming ( announce_data )
data =
File . read! ( " test/fixtures/mastodon-undo-announce.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , announce_data )
|> Map . put ( " actor " , announce_data [ " actor " ] )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " type " ] == " Undo "
2019-07-08 16:53:02 +00:00
assert object_data = data [ " object " ]
assert object_data [ " type " ] == " Announce "
assert object_data [ " object " ] == activity . data [ " object " ]
2018-05-11 19:30:47 +00:00
2019-07-08 16:53:02 +00:00
assert object_data [ " id " ] ==
2018-05-11 19:30:47 +00:00
" http://mastodon.example.org/users/admin/statuses/99542391527669785/activity "
end
2018-05-18 03:55:00 +00:00
2018-05-21 09:00:58 +00:00
test " it works for incomming unfollows with an existing follow " do
2018-05-18 03:55:00 +00:00
user = insert ( :user )
follow_data =
File . read! ( " test/fixtures/mastodon-follow-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , user . ap_id )
{ :ok , % Activity { data : _ , local : false } } = Transmogrifier . handle_incoming ( follow_data )
data =
File . read! ( " test/fixtures/mastodon-unfollow-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , follow_data )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " type " ] == " Undo "
assert data [ " object " ] [ " type " ] == " Follow "
2018-05-20 01:23:52 +00:00
assert data [ " object " ] [ " object " ] == user . ap_id
2018-05-18 03:55:00 +00:00
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
2019-04-22 07:20:43 +00:00
refute User . following? ( User . get_cached_by_ap_id ( data [ " actor " ] ) , user )
2018-05-18 03:55:00 +00:00
end
2018-05-20 01:23:52 +00:00
2019-10-29 09:46:22 +00:00
test " it works for incoming follows to locked account " do
pending_follower = insert ( :user , ap_id : " http://mastodon.example.org/users/admin " )
user = insert ( :user , locked : true )
data =
File . read! ( " test/fixtures/mastodon-follow-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , user . ap_id )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " type " ] == " Follow "
assert data [ " object " ] == user . ap_id
assert data [ " state " ] == " pending "
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
assert [ ^ pending_follower ] = User . get_follow_requests ( user )
end
2018-05-20 01:23:52 +00:00
test " it works for incoming blocks " do
user = insert ( :user )
data =
File . read! ( " test/fixtures/mastodon-block-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , user . ap_id )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " type " ] == " Block "
assert data [ " object " ] == user . ap_id
2018-05-20 06:15:56 +00:00
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
2018-05-20 01:23:52 +00:00
2019-04-22 07:20:43 +00:00
blocker = User . get_cached_by_ap_id ( data [ " actor " ] )
2018-05-20 01:23:52 +00:00
2018-05-20 23:45:05 +00:00
assert User . blocks? ( blocker , user )
2018-05-20 01:23:52 +00:00
end
2018-06-19 00:57:57 +00:00
test " incoming blocks successfully tear down any follow relationship " do
blocker = insert ( :user )
blocked = insert ( :user )
data =
File . read! ( " test/fixtures/mastodon-block-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , blocked . ap_id )
|> Map . put ( " actor " , blocker . ap_id )
{ :ok , blocker } = User . follow ( blocker , blocked )
{ :ok , blocked } = User . follow ( blocked , blocker )
assert User . following? ( blocker , blocked )
assert User . following? ( blocked , blocker )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " type " ] == " Block "
assert data [ " object " ] == blocked . ap_id
assert data [ " actor " ] == blocker . ap_id
2019-04-22 07:20:43 +00:00
blocker = User . get_cached_by_ap_id ( data [ " actor " ] )
blocked = User . get_cached_by_ap_id ( data [ " object " ] )
2018-06-19 00:57:57 +00:00
assert User . blocks? ( blocker , blocked )
refute User . following? ( blocker , blocked )
refute User . following? ( blocked , blocker )
end
2018-05-21 09:00:58 +00:00
test " it works for incoming unblocks with an existing block " do
2018-05-20 01:23:52 +00:00
user = insert ( :user )
block_data =
File . read! ( " test/fixtures/mastodon-block-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , user . ap_id )
{ :ok , % Activity { data : _ , local : false } } = Transmogrifier . handle_incoming ( block_data )
data =
File . read! ( " test/fixtures/mastodon-unblock-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , block_data )
{ :ok , % Activity { data : data , local : false } } = Transmogrifier . handle_incoming ( data )
assert data [ " type " ] == " Undo "
assert data [ " object " ] [ " type " ] == " Block "
assert data [ " object " ] [ " object " ] == user . ap_id
2018-05-21 09:00:58 +00:00
assert data [ " actor " ] == " http://mastodon.example.org/users/admin "
2018-05-20 01:23:52 +00:00
2019-04-22 07:20:43 +00:00
blocker = User . get_cached_by_ap_id ( data [ " actor " ] )
2018-05-20 01:23:52 +00:00
2018-05-21 09:00:58 +00:00
refute User . blocks? ( blocker , user )
2018-05-20 01:23:52 +00:00
end
2018-05-25 12:51:04 +00:00
test " it works for incoming accepts which were pre-accepted " do
follower = insert ( :user )
followed = insert ( :user )
{ :ok , follower } = User . follow ( follower , followed )
assert User . following? ( follower , followed ) == true
2018-05-26 11:16:05 +00:00
{ :ok , follow_activity } = ActivityPub . follow ( follower , followed )
2018-05-25 12:51:04 +00:00
accept_data =
File . read! ( " test/fixtures/mastodon-accept-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " actor " , followed . ap_id )
2018-05-26 13:11:50 +00:00
object =
accept_data [ " object " ]
|> Map . put ( " actor " , follower . ap_id )
|> Map . put ( " id " , follow_activity . data [ " id " ] )
2018-05-26 13:07:21 +00:00
2018-05-26 13:11:50 +00:00
accept_data = Map . put ( accept_data , " object " , object )
2018-05-25 12:51:04 +00:00
2018-05-26 12:07:46 +00:00
{ :ok , activity } = Transmogrifier . handle_incoming ( accept_data )
refute activity . local
assert activity . data [ " object " ] == follow_activity . data [ " id " ]
2018-05-25 12:51:04 +00:00
2019-10-11 09:48:58 +00:00
assert activity . data [ " id " ] == accept_data [ " id " ]
2019-04-22 07:20:43 +00:00
follower = User . get_cached_by_id ( follower . id )
2018-05-25 12:51:04 +00:00
assert User . following? ( follower , followed ) == true
end
test " it works for incoming accepts which were orphaned " do
follower = insert ( :user )
2019-10-16 18:59:21 +00:00
followed = insert ( :user , locked : true )
2018-05-25 12:51:04 +00:00
{ :ok , follow_activity } = ActivityPub . follow ( follower , followed )
accept_data =
File . read! ( " test/fixtures/mastodon-accept-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " actor " , followed . ap_id )
accept_data =
Map . put ( accept_data , " object " , Map . put ( accept_data [ " object " ] , " actor " , follower . ap_id ) )
2018-05-26 12:07:46 +00:00
{ :ok , activity } = Transmogrifier . handle_incoming ( accept_data )
assert activity . data [ " object " ] == follow_activity . data [ " id " ]
2018-05-25 12:51:04 +00:00
2019-04-22 07:20:43 +00:00
follower = User . get_cached_by_id ( follower . id )
2018-05-25 12:51:04 +00:00
assert User . following? ( follower , followed ) == true
end
test " it works for incoming accepts which are referenced by IRI only " do
follower = insert ( :user )
2019-10-16 18:59:21 +00:00
followed = insert ( :user , locked : true )
2018-05-25 12:51:04 +00:00
{ :ok , follow_activity } = ActivityPub . follow ( follower , followed )
accept_data =
File . read! ( " test/fixtures/mastodon-accept-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " actor " , followed . ap_id )
|> Map . put ( " object " , follow_activity . data [ " id " ] )
2018-05-26 12:07:46 +00:00
{ :ok , activity } = Transmogrifier . handle_incoming ( accept_data )
assert activity . data [ " object " ] == follow_activity . data [ " id " ]
2018-05-25 12:51:04 +00:00
2019-04-22 07:20:43 +00:00
follower = User . get_cached_by_id ( follower . id )
2018-05-25 12:51:04 +00:00
assert User . following? ( follower , followed ) == true
end
2018-05-26 11:16:05 +00:00
test " it fails for incoming accepts which cannot be correlated " do
follower = insert ( :user )
2019-10-16 18:59:21 +00:00
followed = insert ( :user , locked : true )
2018-05-26 11:16:05 +00:00
accept_data =
File . read! ( " test/fixtures/mastodon-accept-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " actor " , followed . ap_id )
accept_data =
Map . put ( accept_data , " object " , Map . put ( accept_data [ " object " ] , " actor " , follower . ap_id ) )
:error = Transmogrifier . handle_incoming ( accept_data )
2019-04-22 07:20:43 +00:00
follower = User . get_cached_by_id ( follower . id )
2018-05-26 11:16:05 +00:00
refute User . following? ( follower , followed ) == true
end
2018-05-26 12:07:46 +00:00
test " it fails for incoming rejects which cannot be correlated " do
follower = insert ( :user )
2019-10-16 18:59:21 +00:00
followed = insert ( :user , locked : true )
2018-05-26 12:07:46 +00:00
accept_data =
File . read! ( " test/fixtures/mastodon-reject-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " actor " , followed . ap_id )
accept_data =
Map . put ( accept_data , " object " , Map . put ( accept_data [ " object " ] , " actor " , follower . ap_id ) )
:error = Transmogrifier . handle_incoming ( accept_data )
2019-04-22 07:20:43 +00:00
follower = User . get_cached_by_id ( follower . id )
2018-05-26 12:07:46 +00:00
refute User . following? ( follower , followed ) == true
end
2018-05-25 12:51:04 +00:00
test " it works for incoming rejects which are orphaned " do
follower = insert ( :user )
2019-10-16 18:59:21 +00:00
followed = insert ( :user , locked : true )
2018-05-25 12:51:04 +00:00
{ :ok , follower } = User . follow ( follower , followed )
2018-05-26 13:07:21 +00:00
{ :ok , _follow_activity } = ActivityPub . follow ( follower , followed )
2018-05-25 12:51:04 +00:00
assert User . following? ( follower , followed ) == true
reject_data =
File . read! ( " test/fixtures/mastodon-reject-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " actor " , followed . ap_id )
reject_data =
Map . put ( reject_data , " object " , Map . put ( reject_data [ " object " ] , " actor " , follower . ap_id ) )
2018-05-26 12:07:46 +00:00
{ :ok , activity } = Transmogrifier . handle_incoming ( reject_data )
refute activity . local
2019-10-11 09:48:58 +00:00
assert activity . data [ " id " ] == reject_data [ " id " ]
2018-05-25 12:51:04 +00:00
2019-04-22 07:20:43 +00:00
follower = User . get_cached_by_id ( follower . id )
2018-05-25 12:51:04 +00:00
assert User . following? ( follower , followed ) == false
end
test " it works for incoming rejects which are referenced by IRI only " do
follower = insert ( :user )
2019-10-16 18:59:21 +00:00
followed = insert ( :user , locked : true )
2018-05-25 12:51:04 +00:00
{ :ok , follower } = User . follow ( follower , followed )
{ :ok , follow_activity } = ActivityPub . follow ( follower , followed )
assert User . following? ( follower , followed ) == true
reject_data =
File . read! ( " test/fixtures/mastodon-reject-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " actor " , followed . ap_id )
|> Map . put ( " object " , follow_activity . data [ " id " ] )
{ :ok , % Activity { data : _ } } = Transmogrifier . handle_incoming ( reject_data )
2019-04-22 07:20:43 +00:00
follower = User . get_cached_by_id ( follower . id )
2018-05-25 12:51:04 +00:00
assert User . following? ( follower , followed ) == false
end
2018-08-23 00:55:41 +00:00
test " it rejects activities without a valid ID " do
user = insert ( :user )
data =
File . read! ( " test/fixtures/mastodon-follow-activity.json " )
|> Poison . decode! ( )
|> Map . put ( " object " , user . ap_id )
|> Map . put ( " id " , " " )
:error = Transmogrifier . handle_incoming ( data )
end
2018-12-23 13:28:17 +00:00
2020-04-29 05:13:10 +00:00
test " skip converting the content when it is nil " do
object_id = " https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe "
{ :ok , object } = Fetcher . fetch_and_contain_remote_object_from_id ( object_id )
result =
Pleroma.Web.ActivityPub.Transmogrifier . fix_object ( Map . merge ( object , %{ " content " = > nil } ) )
assert result [ " content " ] == nil
end
2020-04-28 06:32:43 +00:00
test " it converts content of object to html " do
object_id = " https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe "
{ :ok , %{ " content " = > content_markdown } } =
Fetcher . fetch_and_contain_remote_object_from_id ( object_id )
{ :ok , % Pleroma.Object { data : %{ " content " = > content } } = object } =
Fetcher . fetch_object_from_id ( object_id )
assert content_markdown ==
" Support this and our other Michigan!/usr/group videos and meetings. Learn more at http://mug.org/membership \n \n Twenty Years in Jail: FreeBSD's Jails, Then and Now \n \n Jails started as a limited virtualization system, but over the last two years they've... "
assert content ==
" <p>Support this and our other Michigan!/usr/group videos and meetings. Learn more at <a href= \" http://mug.org/membership \" >http://mug.org/membership</a></p><p>Twenty Years in Jail: FreeBSD’ s Jails, Then and Now</p><p>Jails started as a limited virtualization system, but over the last two years they’ ve…</p> "
2020-04-13 03:53:45 +00:00
assert object . data [ " mediaType " ] == " text/html "
end
2018-12-23 13:28:17 +00:00
test " it remaps video URLs as attachments if necessary " do
{ :ok , object } =
2019-04-17 14:03:35 +00:00
Fetcher . fetch_object_from_id (
2018-12-23 13:28:17 +00:00
" https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3 "
)
attachment = %{
" type " = > " Link " ,
" mediaType " = > " video/mp4 " ,
" url " = > [
%{
" href " = >
" https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4 " ,
2020-03-19 18:10:03 +00:00
" mediaType " = > " video/mp4 "
2018-12-23 13:28:17 +00:00
}
2020-03-19 18:10:03 +00:00
]
2018-12-23 13:28:17 +00:00
}
assert object . data [ " url " ] ==
" https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3 "
assert object . data [ " attachment " ] == [ attachment ]
end
2019-03-14 19:04:33 +00:00
test " it accepts Flag activities " do
user = insert ( :user )
other_user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " test post " } )
2019-07-08 16:53:02 +00:00
object = Object . normalize ( activity )
2019-03-14 19:04:33 +00:00
2019-10-23 19:27:22 +00:00
note_obj = %{
" type " = > " Note " ,
" id " = > activity . data [ " id " ] ,
" content " = > " test post " ,
" published " = > object . data [ " published " ] ,
" actor " = > AccountView . render ( " show.json " , %{ user : user } )
}
2019-03-14 19:04:33 +00:00
message = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
" cc " = > [ user . ap_id ] ,
2019-10-27 13:17:37 +00:00
" object " = > [ user . ap_id , activity . data [ " id " ] ] ,
2019-03-14 19:04:33 +00:00
" type " = > " Flag " ,
" content " = > " blocked AND reported!!! " ,
" actor " = > other_user . ap_id
}
assert { :ok , activity } = Transmogrifier . handle_incoming ( message )
2019-10-23 19:27:22 +00:00
assert activity . data [ " object " ] == [ user . ap_id , note_obj ]
2019-03-14 19:04:33 +00:00
assert activity . data [ " content " ] == " blocked AND reported!!! "
assert activity . data [ " actor " ] == other_user . ap_id
assert activity . data [ " cc " ] == [ user . ap_id ]
end
2019-10-23 00:43:31 +00:00
test " it correctly processes messages with non-array to field " do
user = insert ( :user )
message = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
" to " = > " https://www.w3.org/ns/activitystreams # Public " ,
" type " = > " Create " ,
" object " = > %{
" content " = > " blah blah blah " ,
" type " = > " Note " ,
" attributedTo " = > user . ap_id ,
" inReplyTo " = > nil
} ,
" actor " = > user . ap_id
}
assert { :ok , activity } = Transmogrifier . handle_incoming ( message )
assert [ " https://www.w3.org/ns/activitystreams # Public " ] == activity . data [ " to " ]
end
test " it correctly processes messages with non-array cc field " do
user = insert ( :user )
message = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
" to " = > user . follower_address ,
" cc " = > " https://www.w3.org/ns/activitystreams # Public " ,
" type " = > " Create " ,
" object " = > %{
" content " = > " blah blah blah " ,
" type " = > " Note " ,
" attributedTo " = > user . ap_id ,
" inReplyTo " = > nil
} ,
" actor " = > user . ap_id
}
assert { :ok , activity } = Transmogrifier . handle_incoming ( message )
assert [ " https://www.w3.org/ns/activitystreams # Public " ] == activity . data [ " cc " ]
assert [ user . follower_address ] == activity . data [ " to " ]
end
2019-10-30 11:21:49 +00:00
test " it accepts Move activities " do
old_user = insert ( :user )
new_user = insert ( :user )
message = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
" type " = > " Move " ,
" actor " = > old_user . ap_id ,
" object " = > old_user . ap_id ,
" target " = > new_user . ap_id
}
assert :error = Transmogrifier . handle_incoming ( message )
{ :ok , _new_user } = User . update_and_set_cache ( new_user , %{ also_known_as : [ old_user . ap_id ] } )
assert { :ok , % Activity { } = activity } = Transmogrifier . handle_incoming ( message )
assert activity . actor == old_user . ap_id
assert activity . data [ " actor " ] == old_user . ap_id
assert activity . data [ " object " ] == old_user . ap_id
assert activity . data [ " target " ] == new_user . ap_id
assert activity . data [ " type " ] == " Move "
end
2018-02-15 19:00:06 +00:00
end
2018-02-17 13:11:20 +00:00
2020-02-15 17:41:38 +00:00
describe " `handle_incoming/2`, Mastodon format `replies` handling " do
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :activitypub , :note_replies_output_limit ] , 5 )
setup do : clear_config ( [ :instance , :federation_incoming_replies_max_depth ] )
2020-02-15 17:41:38 +00:00
setup do
2020-01-25 07:47:30 +00:00
data =
2020-02-10 08:46:16 +00:00
" test/fixtures/mastodon-post-activity.json "
|> File . read! ( )
2020-01-25 07:47:30 +00:00
|> Poison . decode! ( )
2020-02-10 08:46:16 +00:00
items = get_in ( data , [ " object " , " replies " , " first " , " items " ] )
assert length ( items ) > 0
2020-01-25 07:47:30 +00:00
2020-02-15 17:41:38 +00:00
%{ data : data , items : items }
end
test " schedules background fetching of `replies` items if max thread depth limit allows " , %{
data : data ,
items : items
} do
Pleroma.Config . put ( [ :instance , :federation_incoming_replies_max_depth ] , 10 )
2020-01-25 07:47:30 +00:00
{ :ok , _activity } = Transmogrifier . handle_incoming ( data )
for id <- items do
2020-02-15 17:41:38 +00:00
job_args = %{ " op " = > " fetch_remote " , " id " = > id , " depth " = > 1 }
2020-01-25 07:47:30 +00:00
assert_enqueued ( worker : Pleroma.Workers.RemoteFetcherWorker , args : job_args )
end
end
2020-02-15 17:41:38 +00:00
test " does NOT schedule background fetching of `replies` beyond max thread depth limit allows " ,
%{ data : data } do
Pleroma.Config . put ( [ :instance , :federation_incoming_replies_max_depth ] , 0 )
{ :ok , _activity } = Transmogrifier . handle_incoming ( data )
assert all_enqueued ( worker : Pleroma.Workers.RemoteFetcherWorker ) == [ ]
end
end
describe " `handle_incoming/2`, Pleroma format `replies` handling " do
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :activitypub , :note_replies_output_limit ] , 5 )
setup do : clear_config ( [ :instance , :federation_incoming_replies_max_depth ] )
2020-02-15 17:41:38 +00:00
setup do
2020-02-10 08:46:16 +00:00
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " post1 " } )
2020-01-25 07:47:30 +00:00
2020-02-10 08:46:16 +00:00
{ :ok , reply1 } =
CommonAPI . post ( user , %{ " status " = > " reply1 " , " in_reply_to_status_id " = > activity . id } )
2020-01-25 07:47:30 +00:00
2020-02-10 08:46:16 +00:00
{ :ok , reply2 } =
CommonAPI . post ( user , %{ " status " = > " reply2 " , " in_reply_to_status_id " = > activity . id } )
replies_uris = Enum . map ( [ reply1 , reply2 ] , fn a -> a . object . data [ " id " ] end )
{ :ok , federation_output } = Transmogrifier . prepare_outgoing ( activity . data )
Repo . delete ( activity . object )
Repo . delete ( activity )
2020-02-15 17:41:38 +00:00
%{ federation_output : federation_output , replies_uris : replies_uris }
end
test " schedules background fetching of `replies` items if max thread depth limit allows " , %{
federation_output : federation_output ,
replies_uris : replies_uris
} do
Pleroma.Config . put ( [ :instance , :federation_incoming_replies_max_depth ] , 1 )
2020-02-10 08:46:16 +00:00
{ :ok , _activity } = Transmogrifier . handle_incoming ( federation_output )
for id <- replies_uris do
2020-02-15 17:41:38 +00:00
job_args = %{ " op " = > " fetch_remote " , " id " = > id , " depth " = > 1 }
2020-01-25 07:47:30 +00:00
assert_enqueued ( worker : Pleroma.Workers.RemoteFetcherWorker , args : job_args )
end
end
2020-02-15 17:41:38 +00:00
test " does NOT schedule background fetching of `replies` beyond max thread depth limit allows " ,
%{ federation_output : federation_output } do
Pleroma.Config . put ( [ :instance , :federation_incoming_replies_max_depth ] , 0 )
{ :ok , _activity } = Transmogrifier . handle_incoming ( federation_output )
assert all_enqueued ( worker : Pleroma.Workers.RemoteFetcherWorker ) == [ ]
end
2020-01-25 07:47:30 +00:00
end
2018-02-17 13:11:20 +00:00
describe " prepare outgoing " do
2019-10-02 10:14:08 +00:00
test " it inlines private announced objects " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hey " , " visibility " = > " private " } )
{ :ok , announce_activity , _ } = CommonAPI . repeat ( activity . id , user )
{ :ok , modified } = Transmogrifier . prepare_outgoing ( announce_activity . data )
assert modified [ " object " ] [ " content " ] == " hey "
assert modified [ " object " ] [ " actor " ] == modified [ " object " ] [ " attributedTo " ]
end
2018-02-17 13:11:20 +00:00
test " it turns mentions into tags " do
user = insert ( :user )
other_user = insert ( :user )
2018-03-30 13:01:53 +00:00
{ :ok , activity } =
CommonAPI . post ( user , %{ " status " = > " hey, @ #{ other_user . nickname } , how are ya? # 2hu " } )
2018-02-17 13:11:20 +00:00
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
object = modified [ " object " ]
2018-02-18 12:51:03 +00:00
expected_mention = %{
2018-02-17 13:11:20 +00:00
" href " = > other_user . ap_id ,
" name " = > " @ #{ other_user . nickname } " ,
2018-02-17 13:20:53 +00:00
" type " = > " Mention "
2018-02-17 13:11:20 +00:00
}
2018-02-19 09:39:03 +00:00
2018-02-18 12:51:03 +00:00
expected_tag = %{
2018-03-30 13:01:53 +00:00
" href " = > Pleroma.Web.Endpoint . url ( ) <> " /tags/2hu " ,
2018-02-18 12:51:03 +00:00
" type " = > " Hashtag " ,
" name " = > " # 2hu "
}
2018-02-17 13:11:20 +00:00
2018-02-17 13:20:53 +00:00
assert Enum . member? ( object [ " tag " ] , expected_tag )
2018-02-18 12:51:03 +00:00
assert Enum . member? ( object [ " tag " ] , expected_mention )
2018-02-17 13:11:20 +00:00
end
2018-02-18 13:07:13 +00:00
test " it adds the sensitive property " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " # nsfw hey " } )
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
assert modified [ " object " ] [ " sensitive " ]
end
2018-02-18 12:58:52 +00:00
test " it adds the json-ld context and the conversation property " do
2018-02-17 13:11:20 +00:00
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hey " } )
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
2018-11-08 15:39:38 +00:00
assert modified [ " @context " ] ==
Pleroma.Web.ActivityPub.Utils . make_json_ld_header ( ) [ " @context " ]
2018-02-18 12:58:52 +00:00
assert modified [ " object " ] [ " conversation " ] == modified [ " context " ]
2018-02-17 13:11:20 +00:00
end
test " it sets the 'attributedTo' property to the actor of the object if it doesn't have one " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " hey " } )
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
assert modified [ " object " ] [ " actor " ] == modified [ " object " ] [ " attributedTo " ]
end
2018-03-13 17:46:37 +00:00
2018-11-10 12:16:10 +00:00
test " it strips internal hashtag data " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " # 2hu " } )
expected_tag = %{
" href " = > Pleroma.Web.Endpoint . url ( ) <> " /tags/2hu " ,
" type " = > " Hashtag " ,
" name " = > " # 2hu "
}
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
assert modified [ " object " ] [ " tag " ] == [ expected_tag ]
end
test " it strips internal fields " do
user = insert ( :user )
2019-04-18 19:04:37 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " # 2hu :firefox: " } )
2018-11-10 12:16:10 +00:00
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
assert length ( modified [ " object " ] [ " tag " ] ) == 2
assert is_nil ( modified [ " object " ] [ " emoji " ] )
assert is_nil ( modified [ " object " ] [ " like_count " ] )
assert is_nil ( modified [ " object " ] [ " announcements " ] )
assert is_nil ( modified [ " object " ] [ " announcement_count " ] )
assert is_nil ( modified [ " object " ] [ " context_id " ] )
end
2019-01-12 16:52:30 +00:00
test " it strips internal fields of article " do
activity = insert ( :article_activity )
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
2018-11-10 12:16:10 +00:00
assert length ( modified [ " object " ] [ " tag " ] ) == 2
assert is_nil ( modified [ " object " ] [ " emoji " ] )
assert is_nil ( modified [ " object " ] [ " like_count " ] )
assert is_nil ( modified [ " object " ] [ " announcements " ] )
assert is_nil ( modified [ " object " ] [ " announcement_count " ] )
assert is_nil ( modified [ " object " ] [ " context_id " ] )
2019-08-10 18:47:40 +00:00
assert is_nil ( modified [ " object " ] [ " likes " ] )
2019-01-09 08:22:00 +00:00
end
2018-12-23 15:55:07 +00:00
test " the directMessage flag is present " do
user = insert ( :user )
other_user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " 2hu :moominmamma: " } )
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
assert modified [ " directMessage " ] == false
{ :ok , activity } =
2019-01-21 16:54:11 +00:00
CommonAPI . post ( user , %{ " status " = > " @ #{ other_user . nickname } :moominmamma: " } )
2018-12-23 15:55:07 +00:00
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
assert modified [ " directMessage " ] == false
{ :ok , activity } =
CommonAPI . post ( user , %{
2019-01-21 16:54:11 +00:00
" status " = > " @ #{ other_user . nickname } :moominmamma: " ,
2018-12-23 15:55:07 +00:00
" visibility " = > " direct "
} )
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
assert modified [ " directMessage " ] == true
end
2019-05-14 13:12:47 +00:00
test " it strips BCC field " do
user = insert ( :user )
{ :ok , list } = Pleroma.List . create ( " foo " , user )
{ :ok , activity } =
CommonAPI . post ( user , %{ " status " = > " foobar " , " visibility " = > " list: #{ list . id } " } )
{ :ok , modified } = Transmogrifier . prepare_outgoing ( activity . data )
assert is_nil ( modified [ " bcc " ] )
end
2019-09-28 11:57:24 +00:00
test " it can handle Listen activities " do
listen_activity = insert ( :listen )
{ :ok , modified } = Transmogrifier . prepare_outgoing ( listen_activity . data )
assert modified [ " type " ] == " Listen "
2019-09-28 12:12:35 +00:00
user = insert ( :user )
{ :ok , activity } = CommonAPI . listen ( user , %{ " title " = > " lain radio episode 1 " } )
2019-09-30 13:13:25 +00:00
{ :ok , _modified } = Transmogrifier . prepare_outgoing ( activity . data )
2019-09-28 11:57:24 +00:00
end
2018-02-17 13:11:20 +00:00
end
2018-02-21 21:21:40 +00:00
describe " user upgrade " do
test " it upgrades a user to activitypub " do
2018-03-30 13:01:53 +00:00
user =
insert ( :user , %{
nickname : " rye@niu.moe " ,
local : false ,
ap_id : " https://niu.moe/users/rye " ,
follower_address : User . ap_followers ( % User { nickname : " rye@niu.moe " } )
} )
2019-10-10 19:35:32 +00:00
user_two = insert ( :user )
2020-03-28 15:49:03 +00:00
Pleroma.FollowingRelationship . follow ( user_two , user , :follow_accept )
2018-02-21 21:21:40 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ " status " = > " test " } )
{ :ok , unrelated_activity } = CommonAPI . post ( user_two , %{ " status " = > " test " } )
2018-02-24 09:42:47 +00:00
assert " http://localhost:4001/users/rye@niu.moe/followers " in activity . recipients
2018-02-21 21:21:40 +00:00
2019-04-22 07:20:43 +00:00
user = User . get_cached_by_id ( user . id )
2019-10-16 18:59:21 +00:00
assert user . note_count == 1
2018-02-21 21:21:40 +00:00
{ :ok , user } = Transmogrifier . upgrade_user_from_ap_id ( " https://niu.moe/users/rye " )
2019-08-13 17:20:26 +00:00
ObanHelpers . perform_all ( )
2019-10-16 18:59:21 +00:00
assert user . ap_enabled
assert user . note_count == 1
2018-02-21 21:21:40 +00:00
assert user . follower_address == " https://niu.moe/users/rye/followers "
2019-07-10 13:01:32 +00:00
assert user . following_address == " https://niu.moe/users/rye/following "
2018-02-21 21:21:40 +00:00
2019-04-22 07:20:43 +00:00
user = User . get_cached_by_id ( user . id )
2019-10-16 18:59:21 +00:00
assert user . note_count == 1
2018-02-21 21:21:40 +00:00
2019-04-02 10:08:03 +00:00
activity = Activity . get_by_id ( activity . id )
2018-02-21 21:21:40 +00:00
assert user . follower_address in activity . recipients
2018-03-30 13:01:53 +00:00
assert %{
" url " = > [
%{
" href " = >
" https://cdn.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg "
}
]
} = user . avatar
assert %{
" url " = > [
%{
" href " = >
" https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png "
}
]
2019-10-16 18:59:21 +00:00
} = user . banner
2018-03-30 13:01:53 +00:00
2018-02-21 21:21:40 +00:00
refute " ... " in activity . recipients
2019-04-02 10:08:03 +00:00
unrelated_activity = Activity . get_by_id ( unrelated_activity . id )
2018-02-21 21:21:40 +00:00
refute user . follower_address in unrelated_activity . recipients
2019-04-22 07:20:43 +00:00
user_two = User . get_cached_by_id ( user_two . id )
2019-10-10 19:35:32 +00:00
assert User . following? ( user_two , user )
refute " ... " in User . following ( user_two )
2018-02-24 16:36:02 +00:00
end
end
2018-05-19 08:06:23 +00:00
describe " actor rewriting " do
test " it fixes the actor URL property to be a proper URI " do
data = %{
" url " = > %{ " href " = > " http://example.com " }
}
rewritten = Transmogrifier . maybe_fix_user_object ( data )
assert rewritten [ " url " ] == " http://example.com "
end
end
2018-09-01 23:33:10 +00:00
describe " actor origin containment " do
test " it rejects activities which reference objects with bogus origins " do
data = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
2018-11-17 18:16:55 +00:00
" id " = > " http://mastodon.example.org/users/admin/activities/1234 " ,
" actor " = > " http://mastodon.example.org/users/admin " ,
2018-09-01 23:33:10 +00:00
" to " = > [ " https://www.w3.org/ns/activitystreams # Public " ] ,
" object " = > " https://info.pleroma.site/activity.json " ,
" type " = > " Announce "
}
2019-10-28 16:51:58 +00:00
assert capture_log ( fn ->
:error = Transmogrifier . handle_incoming ( data )
end ) =~ " Object containment failed "
2018-09-01 23:33:10 +00:00
end
2018-11-17 18:12:11 +00:00
2018-11-17 18:24:58 +00:00
test " it rejects activities which reference objects that have an incorrect attribution (variant 1) " do
2018-11-17 18:12:11 +00:00
data = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
" id " = > " http://mastodon.example.org/users/admin/activities/1234 " ,
" actor " = > " http://mastodon.example.org/users/admin " ,
" to " = > [ " https://www.w3.org/ns/activitystreams # Public " ] ,
" object " = > " https://info.pleroma.site/activity2.json " ,
" type " = > " Announce "
}
2019-10-28 16:51:58 +00:00
assert capture_log ( fn ->
:error = Transmogrifier . handle_incoming ( data )
end ) =~ " Object containment failed "
2018-11-17 18:12:11 +00:00
end
2018-11-17 18:24:58 +00:00
test " it rejects activities which reference objects that have an incorrect attribution (variant 2) " do
data = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
" id " = > " http://mastodon.example.org/users/admin/activities/1234 " ,
" actor " = > " http://mastodon.example.org/users/admin " ,
" to " = > [ " https://www.w3.org/ns/activitystreams # Public " ] ,
" object " = > " https://info.pleroma.site/activity3.json " ,
" type " = > " Announce "
}
2019-10-28 16:51:58 +00:00
assert capture_log ( fn ->
:error = Transmogrifier . handle_incoming ( data )
end ) =~ " Object containment failed "
2018-11-17 18:24:58 +00:00
end
2018-09-01 23:33:10 +00:00
end
2018-11-17 20:07:49 +00:00
2019-02-14 00:59:18 +00:00
describe " reserialization " do
test " successfully reserializes a message with inReplyTo == nil " do
user = insert ( :user )
message = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
" to " = > [ " https://www.w3.org/ns/activitystreams # Public " ] ,
" cc " = > [ ] ,
" type " = > " Create " ,
" object " = > %{
" to " = > [ " https://www.w3.org/ns/activitystreams # Public " ] ,
" cc " = > [ ] ,
" type " = > " Note " ,
" content " = > " Hi " ,
" inReplyTo " = > nil ,
" attributedTo " = > user . ap_id
} ,
" actor " = > user . ap_id
}
{ :ok , activity } = Transmogrifier . handle_incoming ( message )
{ :ok , _ } = Transmogrifier . prepare_outgoing ( activity . data )
end
test " successfully reserializes a message with AS2 objects in IR " do
user = insert ( :user )
message = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
" to " = > [ " https://www.w3.org/ns/activitystreams # Public " ] ,
" cc " = > [ ] ,
" type " = > " Create " ,
" object " = > %{
" to " = > [ " https://www.w3.org/ns/activitystreams # Public " ] ,
" cc " = > [ ] ,
" type " = > " Note " ,
" content " = > " Hi " ,
" inReplyTo " = > nil ,
" attributedTo " = > user . ap_id ,
" tag " = > [
%{ " name " = > " # 2hu " , " href " = > " http://example.com/2hu " , " type " = > " Hashtag " } ,
%{ " name " = > " Bob " , " href " = > " http://example.com/bob " , " type " = > " Mention " }
]
} ,
" actor " = > user . ap_id
}
{ :ok , activity } = Transmogrifier . handle_incoming ( message )
{ :ok , _ } = Transmogrifier . prepare_outgoing ( activity . data )
end
end
2019-05-22 18:17:57 +00:00
test " Rewrites Answers to Notes " do
user = insert ( :user )
{ :ok , poll_activity } =
CommonAPI . post ( user , %{
" status " = > " suya... " ,
" poll " = > %{ " options " = > [ " suya " , " suya. " , " suya.. " ] , " expires_in " = > 10 }
} )
poll_object = Object . normalize ( poll_activity )
# TODO: Replace with CommonAPI vote creation when implemented
data =
File . read! ( " test/fixtures/mastodon-vote.json " )
|> Poison . decode! ( )
|> Kernel . put_in ( [ " to " ] , user . ap_id )
|> Kernel . put_in ( [ " object " , " inReplyTo " ] , poll_object . data [ " id " ] )
|> Kernel . put_in ( [ " object " , " to " ] , user . ap_id )
{ :ok , % Activity { local : false } = activity } = Transmogrifier . handle_incoming ( data )
{ :ok , data } = Transmogrifier . prepare_outgoing ( activity . data )
assert data [ " object " ] [ " type " ] == " Note "
end
2019-06-01 13:29:58 +00:00
2019-05-31 11:17:05 +00:00
describe " fix_explicit_addressing " do
2019-06-01 03:26:45 +00:00
setup do
2019-05-31 11:17:05 +00:00
user = insert ( :user )
2019-06-01 03:26:45 +00:00
[ user : user ]
end
2019-05-31 11:17:05 +00:00
2019-06-01 03:26:45 +00:00
test " moves non-explicitly mentioned actors to cc " , %{ user : user } do
2019-05-31 11:17:05 +00:00
explicitly_mentioned_actors = [
" https://pleroma.gold/users/user1 " ,
" https://pleroma.gold/user2 "
]
object = %{
" actor " = > user . ap_id ,
" to " = > explicitly_mentioned_actors ++ [ " https://social.beepboop.ga/users/dirb " ] ,
" cc " = > [ ] ,
" tag " = >
Enum . map ( explicitly_mentioned_actors , fn href ->
%{ " type " = > " Mention " , " href " = > href }
end )
}
fixed_object = Transmogrifier . fix_explicit_addressing ( object )
assert Enum . all? ( explicitly_mentioned_actors , & ( &1 in fixed_object [ " to " ] ) )
refute " https://social.beepboop.ga/users/dirb " in fixed_object [ " to " ]
assert " https://social.beepboop.ga/users/dirb " in fixed_object [ " cc " ]
end
2019-06-01 03:26:45 +00:00
test " does not move actor's follower collection to cc " , %{ user : user } do
2019-05-31 11:17:05 +00:00
object = %{
" actor " = > user . ap_id ,
" to " = > [ user . follower_address ] ,
" cc " = > [ ]
}
fixed_object = Transmogrifier . fix_explicit_addressing ( object )
assert user . follower_address in fixed_object [ " to " ]
refute user . follower_address in fixed_object [ " cc " ]
end
2019-06-01 03:26:45 +00:00
test " removes recipient's follower collection from cc " , %{ user : user } do
recipient = insert ( :user )
object = %{
" actor " = > user . ap_id ,
" to " = > [ recipient . ap_id , " https://www.w3.org/ns/activitystreams # Public " ] ,
" cc " = > [ user . follower_address , recipient . follower_address ]
}
fixed_object = Transmogrifier . fix_explicit_addressing ( object )
assert user . follower_address in fixed_object [ " cc " ]
refute recipient . follower_address in fixed_object [ " cc " ]
refute recipient . follower_address in fixed_object [ " to " ]
end
2019-05-31 11:17:05 +00:00
end
2019-09-10 13:43:10 +00:00
describe " fix_summary/1 " do
test " returns fixed object " do
assert Transmogrifier . fix_summary ( %{ " summary " = > nil } ) == %{ " summary " = > " " }
assert Transmogrifier . fix_summary ( %{ " summary " = > " ok " } ) == %{ " summary " = > " ok " }
assert Transmogrifier . fix_summary ( %{ } ) == %{ " summary " = > " " }
end
end
describe " fix_in_reply_to/2 " do
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :instance , :federation_incoming_replies_max_depth ] )
2019-09-10 13:43:10 +00:00
setup do
data = Poison . decode! ( File . read! ( " test/fixtures/mastodon-post-activity.json " ) )
[ data : data ]
end
test " returns not modified object when hasn't containts inReplyTo field " , %{ data : data } do
assert Transmogrifier . fix_in_reply_to ( data ) == data
end
test " returns object with inReplyToAtomUri when denied incoming reply " , %{ data : data } do
Pleroma.Config . put ( [ :instance , :federation_incoming_replies_max_depth ] , 0 )
object_with_reply =
Map . put ( data [ " object " ] , " inReplyTo " , " https://shitposter.club/notice/2827873 " )
modified_object = Transmogrifier . fix_in_reply_to ( object_with_reply )
assert modified_object [ " inReplyTo " ] == " https://shitposter.club/notice/2827873 "
assert modified_object [ " inReplyToAtomUri " ] == " https://shitposter.club/notice/2827873 "
object_with_reply =
Map . put ( data [ " object " ] , " inReplyTo " , %{ " id " = > " https://shitposter.club/notice/2827873 " } )
modified_object = Transmogrifier . fix_in_reply_to ( object_with_reply )
assert modified_object [ " inReplyTo " ] == %{ " id " = > " https://shitposter.club/notice/2827873 " }
assert modified_object [ " inReplyToAtomUri " ] == " https://shitposter.club/notice/2827873 "
object_with_reply =
Map . put ( data [ " object " ] , " inReplyTo " , [ " https://shitposter.club/notice/2827873 " ] )
modified_object = Transmogrifier . fix_in_reply_to ( object_with_reply )
assert modified_object [ " inReplyTo " ] == [ " https://shitposter.club/notice/2827873 " ]
assert modified_object [ " inReplyToAtomUri " ] == " https://shitposter.club/notice/2827873 "
object_with_reply = Map . put ( data [ " object " ] , " inReplyTo " , [ ] )
modified_object = Transmogrifier . fix_in_reply_to ( object_with_reply )
assert modified_object [ " inReplyTo " ] == [ ]
assert modified_object [ " inReplyToAtomUri " ] == " "
end
2019-11-28 09:44:48 +00:00
@tag capture_log : true
2019-09-10 13:43:10 +00:00
test " returns modified object when allowed incoming reply " , %{ data : data } do
object_with_reply =
Map . put (
data [ " object " ] ,
" inReplyTo " ,
" https://shitposter.club/notice/2827873 "
)
Pleroma.Config . put ( [ :instance , :federation_incoming_replies_max_depth ] , 5 )
modified_object = Transmogrifier . fix_in_reply_to ( object_with_reply )
assert modified_object [ " inReplyTo " ] ==
" tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment "
assert modified_object [ " inReplyToAtomUri " ] == " https://shitposter.club/notice/2827873 "
assert modified_object [ " conversation " ] ==
" tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26 "
assert modified_object [ " context " ] ==
" tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26 "
end
end
describe " fix_url/1 " do
test " fixes data for object when url is map " do
object = %{
" url " = > %{
" type " = > " Link " ,
" mimeType " = > " video/mp4 " ,
" href " = > " https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4 "
}
}
assert Transmogrifier . fix_url ( object ) == %{
" url " = > " https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4 "
}
end
test " fixes data for video object " do
object = %{
" type " = > " Video " ,
" url " = > [
%{
" type " = > " Link " ,
" mimeType " = > " video/mp4 " ,
" href " = > " https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4 "
} ,
%{
" type " = > " Link " ,
" mimeType " = > " video/mp4 " ,
" href " = > " https://peertube46fb-ad81-2d4c2d1630e3-240.mp4 "
} ,
%{
" type " = > " Link " ,
" mimeType " = > " text/html " ,
" href " = > " https://peertube.-2d4c2d1630e3 "
} ,
%{
" type " = > " Link " ,
" mimeType " = > " text/html " ,
" href " = > " https://peertube.-2d4c2d16377-42 "
}
]
}
assert Transmogrifier . fix_url ( object ) == %{
" attachment " = > [
%{
" href " = > " https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4 " ,
" mimeType " = > " video/mp4 " ,
" type " = > " Link "
}
] ,
" type " = > " Video " ,
" url " = > " https://peertube.-2d4c2d1630e3 "
}
end
test " fixes url for not Video object " do
object = %{
" type " = > " Text " ,
" url " = > [
%{
" type " = > " Link " ,
" mimeType " = > " text/html " ,
" href " = > " https://peertube.-2d4c2d1630e3 "
} ,
%{
" type " = > " Link " ,
" mimeType " = > " text/html " ,
" href " = > " https://peertube.-2d4c2d16377-42 "
}
]
}
assert Transmogrifier . fix_url ( object ) == %{
" type " = > " Text " ,
" url " = > " https://peertube.-2d4c2d1630e3 "
}
assert Transmogrifier . fix_url ( %{ " type " = > " Text " , " url " = > [ ] } ) == %{
" type " = > " Text " ,
" url " = > " "
}
end
test " retunrs not modified object " do
assert Transmogrifier . fix_url ( %{ " type " = > " Text " } ) == %{ " type " = > " Text " }
end
end
2019-09-11 04:23:33 +00:00
describe " get_obj_helper/2 " do
test " returns nil when cannot normalize object " do
2019-10-28 16:51:58 +00:00
assert capture_log ( fn ->
refute Transmogrifier . get_obj_helper ( " test-obj-id " )
end ) =~ " Unsupported URI scheme "
2019-09-11 04:23:33 +00:00
end
2019-11-28 09:44:48 +00:00
@tag capture_log : true
2019-09-11 04:23:33 +00:00
test " returns {:ok, %Object{}} for success case " do
assert { :ok , % Object { } } =
Transmogrifier . get_obj_helper ( " https://shitposter.club/notice/2827873 " )
end
end
describe " fix_attachments/1 " do
test " returns not modified object " do
data = Poison . decode! ( File . read! ( " test/fixtures/mastodon-post-activity.json " ) )
assert Transmogrifier . fix_attachments ( data ) == data
end
test " returns modified object when attachment is map " do
assert Transmogrifier . fix_attachments ( %{
" attachment " = > %{
" mediaType " = > " video/mp4 " ,
" url " = > " https://peertube.moe/stat-480.mp4 "
}
} ) == %{
" attachment " = > [
%{
" mediaType " = > " video/mp4 " ,
" url " = > [
2020-03-19 18:10:03 +00:00
%{ " href " = > " https://peertube.moe/stat-480.mp4 " , " mediaType " = > " video/mp4 " }
2019-09-11 04:23:33 +00:00
]
}
]
}
end
test " returns modified object when attachment is list " do
assert Transmogrifier . fix_attachments ( %{
" attachment " = > [
%{ " mediaType " = > " video/mp4 " , " url " = > " https://pe.er/stat-480.mp4 " } ,
%{ " mimeType " = > " video/mp4 " , " href " = > " https://pe.er/stat-480.mp4 " }
]
} ) == %{
" attachment " = > [
%{
" mediaType " = > " video/mp4 " ,
" url " = > [
2020-03-19 18:10:03 +00:00
%{ " href " = > " https://pe.er/stat-480.mp4 " , " mediaType " = > " video/mp4 " }
2019-09-11 04:23:33 +00:00
]
} ,
%{
" mediaType " = > " video/mp4 " ,
" url " = > [
2020-03-19 18:10:03 +00:00
%{ " href " = > " https://pe.er/stat-480.mp4 " , " mediaType " = > " video/mp4 " }
2019-09-11 04:23:33 +00:00
]
}
]
}
end
end
2019-09-11 20:19:06 +00:00
describe " fix_emoji/1 " do
test " returns not modified object when object not contains tags " do
data = Poison . decode! ( File . read! ( " test/fixtures/mastodon-post-activity.json " ) )
assert Transmogrifier . fix_emoji ( data ) == data
end
test " returns object with emoji when object contains list tags " do
assert Transmogrifier . fix_emoji ( %{
" tag " = > [
%{ " type " = > " Emoji " , " name " = > " :bib: " , " icon " = > %{ " url " = > " /test " } } ,
%{ " type " = > " Hashtag " }
]
} ) == %{
" emoji " = > %{ " bib " = > " /test " } ,
" tag " = > [
%{ " icon " = > %{ " url " = > " /test " } , " name " = > " :bib: " , " type " = > " Emoji " } ,
%{ " type " = > " Hashtag " }
]
}
end
test " returns object with emoji when object contains map tag " do
assert Transmogrifier . fix_emoji ( %{
" tag " = > %{ " type " = > " Emoji " , " name " = > " :bib: " , " icon " = > %{ " url " = > " /test " } }
} ) == %{
" emoji " = > %{ " bib " = > " /test " } ,
" tag " = > %{ " icon " = > %{ " url " = > " /test " } , " name " = > " :bib: " , " type " = > " Emoji " }
}
end
end
2020-01-22 18:10:17 +00:00
describe " set_replies/1 " do
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :activitypub , :note_replies_output_limit ] , 2 )
2020-01-22 18:10:17 +00:00
test " returns unmodified object if activity doesn't have self-replies " do
data = Poison . decode! ( File . read! ( " test/fixtures/mastodon-post-activity.json " ) )
assert Transmogrifier . set_replies ( data ) == data
end
test " sets `replies` collection with a limited number of self-replies " do
[ user , another_user ] = insert_list ( 2 , :user )
{ :ok , %{ id : id1 } = activity } = CommonAPI . post ( user , %{ " status " = > " 1 " } )
{ :ok , %{ id : id2 } = self_reply1 } =
CommonAPI . post ( user , %{ " status " = > " self-reply 1 " , " in_reply_to_status_id " = > id1 } )
{ :ok , self_reply2 } =
CommonAPI . post ( user , %{ " status " = > " self-reply 2 " , " in_reply_to_status_id " = > id1 } )
2020-02-08 16:58:02 +00:00
# Assuming to _not_ be present in `replies` due to :note_replies_output_limit is set to 2
2020-01-22 18:10:17 +00:00
{ :ok , _ } =
CommonAPI . post ( user , %{ " status " = > " self-reply 3 " , " in_reply_to_status_id " = > id1 } )
{ :ok , _ } =
CommonAPI . post ( user , %{
" status " = > " self-reply to self-reply " ,
" in_reply_to_status_id " = > id2
} )
{ :ok , _ } =
CommonAPI . post ( another_user , %{
" status " = > " another user's reply " ,
" in_reply_to_status_id " = > id1
} )
object = Object . normalize ( activity )
2020-02-09 07:17:21 +00:00
replies_uris = Enum . map ( [ self_reply1 , self_reply2 ] , fn a -> a . object . data [ " id " ] end )
2020-01-22 18:10:17 +00:00
2020-02-09 14:34:48 +00:00
assert %{ " type " = > " Collection " , " items " = > ^ replies_uris } =
Transmogrifier . set_replies ( object . data ) [ " replies " ]
2020-01-22 18:10:17 +00:00
end
end
2020-04-03 11:03:32 +00:00
test " take_emoji_tags/1 " do
user = insert ( :user , %{ emoji : %{ " firefox " = > " https://example.org/firefox.png " } } )
assert Transmogrifier . take_emoji_tags ( user ) == [
%{
" icon " = > %{ " type " = > " Image " , " url " = > " https://example.org/firefox.png " } ,
" id " = > " https://example.org/firefox.png " ,
" name " = > " :firefox: " ,
" type " = > " Emoji " ,
" updated " = > " 1970-01-01T00:00:00Z "
}
]
end
2018-02-15 19:00:06 +00:00
end