2018-12-23 20:11:29 +00:00
# Pleroma: A lightweight social networking server
2022-02-26 06:11:42 +00:00
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
2018-12-23 20:11:29 +00:00
# SPDX-License-Identifier: AGPL-3.0-only
2019-02-17 16:47:24 +00:00
defmodule Pleroma.Web.CommonAPITest do
2020-08-22 17:46:01 +00:00
use Oban.Testing , repo : Pleroma.Repo
2018-05-23 15:25:24 +00:00
use Pleroma.DataCase
2020-08-22 17:46:01 +00:00
2018-12-14 05:56:49 +00:00
alias Pleroma.Activity
2020-04-09 11:20:16 +00:00
alias Pleroma.Chat
2019-08-02 13:05:27 +00:00
alias Pleroma.Conversation.Participation
2020-06-05 14:47:02 +00:00
alias Pleroma.Notification
2019-04-17 09:22:32 +00:00
alias Pleroma.Object
2020-08-28 15:17:44 +00:00
alias Pleroma.Repo
2019-04-17 11:52:01 +00:00
alias Pleroma.User
2019-06-05 13:43:54 +00:00
alias Pleroma.Web.ActivityPub.ActivityPub
2020-04-30 19:23:18 +00:00
alias Pleroma.Web.ActivityPub.Transmogrifier
2019-08-05 13:33:22 +00:00
alias Pleroma.Web.ActivityPub.Visibility
2019-10-23 19:27:22 +00:00
alias Pleroma.Web.AdminAPI.AccountView
2018-05-23 15:25:24 +00:00
alias Pleroma.Web.CommonAPI
2021-07-18 01:35:35 +00:00
alias Pleroma.Workers.PollWorker
2018-05-23 15:25:24 +00:00
import Pleroma.Factory
2020-04-30 19:23:18 +00:00
import Mock
2020-08-28 15:17:44 +00:00
import Ecto.Query , only : [ from : 2 ]
2018-05-23 15:25:24 +00:00
2019-10-05 12:53:50 +00:00
require Pleroma.Constants
2021-03-22 17:07:07 +00:00
setup_all do
Tesla.Mock . mock_global ( fn env -> apply ( HttpRequestMock , :request , [ env ] ) end )
:ok
end
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :instance , :safe_dm_mentions ] )
setup do : clear_config ( [ :instance , :limit ] )
setup do : clear_config ( [ :instance , :max_pinned_statuses ] )
2019-08-19 15:34:29 +00:00
2020-09-24 09:12:03 +00:00
describe " posting polls " do
test " it posts a poll " do
user = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( user , %{
status : " who is the best " ,
poll : %{ expires_in : 600 , options : [ " reimu " , " marisa " ] }
} )
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2020-09-24 09:12:03 +00:00
assert object . data [ " type " ] == " Question "
assert object . data [ " oneOf " ] |> length ( ) == 2
2021-07-18 01:35:35 +00:00
assert_enqueued (
worker : PollWorker ,
args : %{ op : " poll_end " , activity_id : activity . id } ,
scheduled_at : NaiveDateTime . from_iso8601! ( object . data [ " closed " ] )
)
2020-09-24 09:12:03 +00:00
end
end
2020-06-25 10:03:14 +00:00
describe " blocking " do
setup do
blocker = insert ( :user )
blocked = insert ( :user )
User . follow ( blocker , blocked )
User . follow ( blocked , blocker )
%{ blocker : blocker , blocked : blocked }
end
test " it blocks and federates " , %{ blocker : blocker , blocked : blocked } do
clear_config ( [ :instance , :federating ] , true )
with_mock Pleroma.Web.Federator ,
publish : fn _ -> nil end do
assert { :ok , block } = CommonAPI . block ( blocker , blocked )
assert block . local
assert User . blocks? ( blocker , blocked )
refute User . following? ( blocker , blocked )
refute User . following? ( blocked , blocker )
assert called ( Pleroma.Web.Federator . publish ( block ) )
end
end
test " it blocks and does not federate if outgoing blocks are disabled " , %{
blocker : blocker ,
blocked : blocked
} do
clear_config ( [ :instance , :federating ] , true )
clear_config ( [ :activitypub , :outgoing_blocks ] , false )
with_mock Pleroma.Web.Federator ,
publish : fn _ -> nil end do
assert { :ok , block } = CommonAPI . block ( blocker , blocked )
assert block . local
assert User . blocks? ( blocker , blocked )
refute User . following? ( blocker , blocked )
refute User . following? ( blocked , blocker )
refute called ( Pleroma.Web.Federator . publish ( block ) )
end
end
end
2020-04-09 11:20:16 +00:00
describe " posting chat messages " do
2020-04-20 10:08:47 +00:00
setup do : clear_config ( [ :instance , :chat_limit ] )
2020-10-22 10:22:08 +00:00
test " it posts a self-chat " do
author = insert ( :user )
recipient = author
{ :ok , activity } =
CommonAPI . post_chat_message (
author ,
recipient ,
" remember to buy milk when milk truk arive "
)
assert activity . data [ " type " ] == " Create "
end
2020-05-13 13:31:28 +00:00
test " it posts a chat message without content but with an attachment " do
author = insert ( :user )
recipient = insert ( :user )
file = % Plug.Upload {
2020-10-13 15:37:24 +00:00
content_type : " image/jpeg " ,
2020-05-13 13:31:28 +00:00
path : Path . absname ( " test/fixtures/image.jpg " ) ,
filename : " an_image.jpg "
}
{ :ok , upload } = ActivityPub . upload ( file , actor : author . ap_id )
2020-06-05 14:47:02 +00:00
with_mocks ( [
{
Pleroma.Web.Streamer ,
[ ] ,
[
stream : fn _ , _ ->
nil
end
]
} ,
{
Pleroma.Web.Push ,
[ ] ,
[
send : fn _ -> nil end
]
}
] ) do
{ :ok , activity } =
CommonAPI . post_chat_message (
author ,
recipient ,
nil ,
media_id : upload . id
)
notification =
Notification . for_user_and_activity ( recipient , activity )
|> Repo . preload ( :activity )
assert called ( Pleroma.Web.Push . send ( notification ) )
assert called ( Pleroma.Web.Streamer . stream ( [ " user " , " user:notification " ] , notification ) )
2020-06-07 12:52:56 +00:00
assert called ( Pleroma.Web.Streamer . stream ( [ " user " , " user:pleroma_chat " ] , :_ ) )
2020-06-05 14:47:02 +00:00
assert activity
end
2020-05-13 13:31:28 +00:00
end
2020-06-01 13:14:22 +00:00
test " it adds html newlines " do
author = insert ( :user )
recipient = insert ( :user )
other_user = insert ( :user )
{ :ok , activity } =
CommonAPI . post_chat_message (
author ,
recipient ,
" uguu \n uguuu "
)
assert other_user . ap_id not in activity . recipients
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2020-06-01 13:14:22 +00:00
assert object . data [ " content " ] == " uguu<br/>uguuu "
end
2020-05-30 10:30:31 +00:00
test " it linkifies " do
author = insert ( :user )
recipient = insert ( :user )
other_user = insert ( :user )
{ :ok , activity } =
CommonAPI . post_chat_message (
author ,
recipient ,
" https://example.org is the site of @ #{ other_user . nickname } # 2hu "
)
assert other_user . ap_id not in activity . recipients
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2020-05-30 10:30:31 +00:00
assert object . data [ " content " ] ==
2021-10-06 06:08:21 +00:00
" <a href= \" https://example.org \" rel= \" ugc \" >https://example.org</a> is the site of <span class= \" h-card \" ><a class= \" u-url mention \" data-user= \" #{ other_user . id } \" href= \" #{ other_user . ap_id } \" rel= \" ugc \" >@<span> #{ other_user . nickname } </span></a></span> <a class= \" hashtag \" data-tag= \" 2hu \" href= \" http://localhost:4001/tag/2hu \" > # 2hu</a> "
2020-05-30 10:30:31 +00:00
end
2020-04-09 11:20:16 +00:00
test " it posts a chat message " do
author = insert ( :user )
recipient = insert ( :user )
2020-04-16 10:56:29 +00:00
{ :ok , activity } =
CommonAPI . post_chat_message (
author ,
recipient ,
2020-04-20 12:08:54 +00:00
" a test message <script>alert('uuu')</script> :firefox: "
2020-04-16 10:56:29 +00:00
)
2020-04-09 11:20:16 +00:00
assert activity . data [ " type " ] == " Create "
assert activity . local
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2020-04-09 11:20:16 +00:00
assert object . data [ " type " ] == " ChatMessage "
assert object . data [ " to " ] == [ recipient . ap_id ]
2020-04-16 10:56:29 +00:00
assert object . data [ " content " ] ==
2020-04-20 12:08:54 +00:00
" a test message <script>alert(& # 39;uuu& # 39;)</script> :firefox: "
assert object . data [ " emoji " ] == %{
" firefox " = > " http://localhost:4001/emoji/Firefox.gif "
}
2020-04-09 11:20:16 +00:00
assert Chat . get ( author . id , recipient . ap_id )
assert Chat . get ( recipient . id , author . ap_id )
2020-05-08 16:26:35 +00:00
assert :ok == Pleroma.Web.Federator . perform ( :publish , activity )
2020-04-09 11:20:16 +00:00
end
2020-04-20 10:08:47 +00:00
test " it reject messages over the local limit " do
2021-01-26 17:58:43 +00:00
clear_config ( [ :instance , :chat_limit ] , 2 )
2020-04-20 10:08:47 +00:00
author = insert ( :user )
recipient = insert ( :user )
{ :error , message } =
CommonAPI . post_chat_message (
author ,
recipient ,
" 123 "
)
assert message == :content_too_long
end
2020-09-14 12:07:22 +00:00
test " it reject messages via MRF " do
clear_config ( [ :mrf_keyword , :reject ] , [ " GNO " ] )
clear_config ( [ :mrf , :policies ] , [ Pleroma.Web.ActivityPub.MRF.KeywordPolicy ] )
author = insert ( :user )
recipient = insert ( :user )
assert { :reject , " [KeywordPolicy] Matches with rejected keyword " } ==
CommonAPI . post_chat_message ( author , recipient , " GNO/Linux " )
end
2020-04-09 11:20:16 +00:00
end
2020-05-16 10:28:24 +00:00
describe " unblocking " do
test " it works even without an existing block activity " do
blocked = insert ( :user )
blocker = insert ( :user )
User . block ( blocker , blocked )
assert User . blocks? ( blocker , blocked )
assert { :ok , :no_activity } == CommonAPI . unblock ( blocker , blocked )
refute User . blocks? ( blocker , blocked )
end
end
2020-04-30 19:23:18 +00:00
describe " deletion " do
2020-05-11 13:06:23 +00:00
test " it works with pruned objects " do
user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , post } = CommonAPI . post ( user , %{ status : " namu amida butsu " } )
2020-05-11 13:06:23 +00:00
2020-05-21 11:16:21 +00:00
clear_config ( [ :instance , :federating ] , true )
2021-01-04 12:38:31 +00:00
Object . normalize ( post , fetch : false )
2020-05-11 13:06:23 +00:00
|> Object . prune ( )
with_mock Pleroma.Web.Federator ,
publish : fn _ -> nil end do
assert { :ok , delete } = CommonAPI . delete ( post . id , user )
assert delete . local
assert called ( Pleroma.Web.Federator . publish ( delete ) )
end
refute Activity . get_by_id ( post . id )
end
2020-04-30 19:23:18 +00:00
test " it allows users to delete their posts " do
user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , post } = CommonAPI . post ( user , %{ status : " namu amida butsu " } )
2020-04-30 19:23:18 +00:00
2020-05-21 11:16:21 +00:00
clear_config ( [ :instance , :federating ] , true )
2020-04-30 19:23:18 +00:00
with_mock Pleroma.Web.Federator ,
publish : fn _ -> nil end do
assert { :ok , delete } = CommonAPI . delete ( post . id , user )
assert delete . local
assert called ( Pleroma.Web.Federator . publish ( delete ) )
end
refute Activity . get_by_id ( post . id )
end
test " it does not allow a user to delete their posts " do
user = insert ( :user )
other_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , post } = CommonAPI . post ( user , %{ status : " namu amida butsu " } )
2020-04-30 19:23:18 +00:00
assert { :error , " Could not delete " } = CommonAPI . delete ( post . id , other_user )
assert Activity . get_by_id ( post . id )
end
test " it allows moderators to delete other user's posts " do
user = insert ( :user )
moderator = insert ( :user , is_moderator : true )
2020-05-12 19:59:26 +00:00
{ :ok , post } = CommonAPI . post ( user , %{ status : " namu amida butsu " } )
2020-04-30 19:23:18 +00:00
assert { :ok , delete } = CommonAPI . delete ( post . id , moderator )
assert delete . local
refute Activity . get_by_id ( post . id )
end
test " it allows admins to delete other user's posts " do
user = insert ( :user )
moderator = insert ( :user , is_admin : true )
2020-05-12 19:59:26 +00:00
{ :ok , post } = CommonAPI . post ( user , %{ status : " namu amida butsu " } )
2020-04-30 19:23:18 +00:00
assert { :ok , delete } = CommonAPI . delete ( post . id , moderator )
assert delete . local
refute Activity . get_by_id ( post . id )
end
test " superusers deleting non-local posts won't federate the delete " do
# This is the user of the ingested activity
_user =
insert ( :user ,
local : false ,
ap_id : " http://mastodon.example.org/users/admin " ,
last_refreshed_at : NaiveDateTime . utc_now ( )
)
moderator = insert ( :user , is_admin : true )
data =
File . read! ( " test/fixtures/mastodon-post-activity.json " )
|> Jason . decode! ( )
{ :ok , post } = Transmogrifier . handle_incoming ( data )
with_mock Pleroma.Web.Federator ,
publish : fn _ -> nil end do
assert { :ok , delete } = CommonAPI . delete ( post . id , moderator )
assert delete . local
refute called ( Pleroma.Web.Federator . publish ( :_ ) )
end
refute Activity . get_by_id ( post . id )
end
end
2020-04-22 16:40:53 +00:00
test " favoriting race condition " do
user = insert ( :user )
users_serial = insert_list ( 10 , :user )
users = insert_list ( 10 , :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " . " } )
2020-04-22 16:40:53 +00:00
users_serial
|> Enum . map ( fn user ->
CommonAPI . favorite ( user , activity . id )
end )
object = Object . get_by_ap_id ( activity . data [ " object " ] )
assert object . data [ " like_count " ] == 10
users
|> Enum . map ( fn user ->
Task . async ( fn ->
CommonAPI . favorite ( user , activity . id )
end )
end )
|> Enum . map ( & Task . await / 1 )
object = Object . get_by_ap_id ( activity . data [ " object " ] )
assert object . data [ " like_count " ] == 20
end
2020-04-24 12:37:53 +00:00
test " repeating race condition " do
user = insert ( :user )
users_serial = insert_list ( 10 , :user )
users = insert_list ( 10 , :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " . " } )
2020-04-24 12:37:53 +00:00
users_serial
|> Enum . map ( fn user ->
CommonAPI . repeat ( activity . id , user )
end )
object = Object . get_by_ap_id ( activity . data [ " object " ] )
assert object . data [ " announcement_count " ] == 10
users
|> Enum . map ( fn user ->
Task . async ( fn ->
CommonAPI . repeat ( activity . id , user )
end )
end )
|> Enum . map ( & Task . await / 1 )
object = Object . get_by_ap_id ( activity . data [ " object " ] )
assert object . data [ " announcement_count " ] == 20
end
2019-08-05 13:33:22 +00:00
test " when replying to a conversation / participation, it will set the correct context id even if no explicit reply_to is given " do
user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " . " , visibility : " direct " } )
2019-08-05 13:33:22 +00:00
[ participation ] = Participation . for_user ( user )
{ :ok , convo_reply } =
2020-05-12 19:59:26 +00:00
CommonAPI . post ( user , %{ status : " . " , in_reply_to_conversation_id : participation . id } )
2019-08-05 13:33:22 +00:00
assert Visibility . is_direct? ( convo_reply )
assert activity . data [ " context " ] == convo_reply . data [ " context " ]
end
2019-08-02 13:05:27 +00:00
test " when replying to a conversation / participation, it only mentions the recipients explicitly declared in the participation " do
har = insert ( :user )
jafnhar = insert ( :user )
tridi = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( har , %{
2020-05-12 19:59:26 +00:00
status : " @ #{ jafnhar . nickname } hey " ,
visibility : " direct "
2019-08-02 13:05:27 +00:00
} )
assert har . ap_id in activity . recipients
assert jafnhar . ap_id in activity . recipients
[ participation ] = Participation . for_user ( har )
{ :ok , activity } =
CommonAPI . post ( har , %{
2020-05-12 19:59:26 +00:00
status : " I don't really like @ #{ tridi . nickname } " ,
visibility : " direct " ,
in_reply_to_status_id : activity . id ,
in_reply_to_conversation_id : participation . id
2019-08-02 13:05:27 +00:00
} )
assert har . ap_id in activity . recipients
assert jafnhar . ap_id in activity . recipients
refute tridi . ap_id in activity . recipients
end
2019-03-20 20:09:36 +00:00
test " with the safe_dm_mention option set, it does not mention people beyond the initial tags " do
har = insert ( :user )
jafnhar = insert ( :user )
tridi = insert ( :user )
2020-02-13 18:55:47 +00:00
2021-01-26 17:58:43 +00:00
clear_config ( [ :instance , :safe_dm_mentions ] , true )
2019-03-20 20:09:36 +00:00
{ :ok , activity } =
CommonAPI . post ( har , %{
2020-05-12 19:59:26 +00:00
status : " @ #{ jafnhar . nickname } hey, i never want to see @ #{ tridi . nickname } again " ,
visibility : " direct "
2019-03-20 20:09:36 +00:00
} )
refute tridi . ap_id in activity . recipients
assert jafnhar . ap_id in activity . recipients
end
2018-05-23 15:25:24 +00:00
test " it de-duplicates tags " do
user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " # 2hu # 2HU " } )
2018-05-23 15:25:24 +00:00
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2018-11-25 22:31:07 +00:00
2020-12-21 19:54:26 +00:00
assert Object . tags ( object ) == [ " 2hu " ]
2018-05-23 15:25:24 +00:00
end
2018-08-12 19:24:10 +00:00
2019-01-20 10:48:53 +00:00
test " it adds emoji in the object " do
user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " :firefox: " } )
2019-01-20 10:48:53 +00:00
2021-01-04 12:38:31 +00:00
assert Object . normalize ( activity , fetch : false ) . data [ " emoji " ] [ " firefox " ]
2019-01-20 10:48:53 +00:00
end
2018-09-02 00:14:25 +00:00
describe " posting " do
2019-02-06 17:05:34 +00:00
test " it adds an emoji on an external site " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ status : " hey :external_emoji: " } )
assert %{ " external_emoji " = > url } = Object . normalize ( activity ) . data [ " emoji " ]
assert url == " https://example.com/emoji.png "
{ :ok , activity } = CommonAPI . post ( user , %{ status : " hey :blank: " } )
assert %{ " blank " = > url } = Object . normalize ( activity ) . data [ " emoji " ]
2021-05-31 20:09:11 +00:00
assert url == " #{ Pleroma.Web.Endpoint . url ( ) } /emoji/blank.png "
2019-02-06 17:05:34 +00:00
end
2021-03-22 17:07:07 +00:00
test " it copies emoji from the subject of the parent post " do
% Object { } =
object =
Object . normalize ( " https://patch.cx/objects/a399c28e-c821-4820-bc3e-4afeb044c16f " ,
fetch : true
)
activity = Activity . get_create_by_object_ap_id ( object . data [ " id " ] )
user = insert ( :user )
{ :ok , reply_activity } =
CommonAPI . post ( user , %{
in_reply_to_id : activity . id ,
status : " :joker_disapprove: " ,
spoiler_text : " :joker_smile: "
} )
2021-04-05 16:57:14 +00:00
assert Object . normalize ( reply_activity ) . data [ " emoji " ] [ " joker_smile " ]
refute Object . normalize ( reply_activity ) . data [ " emoji " ] [ " joker_disapprove " ]
2019-02-06 17:05:34 +00:00
end
2020-08-04 12:08:12 +00:00
test " deactivated users can't post " do
2020-10-12 22:42:27 +00:00
user = insert ( :user , is_active : false )
2020-08-04 12:08:12 +00:00
assert { :error , _ } = CommonAPI . post ( user , %{ status : " ye " } )
end
2019-06-03 16:17:08 +00:00
test " it supports explicit addressing " do
user = insert ( :user )
user_two = insert ( :user )
user_three = insert ( :user )
user_four = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( user , %{
2020-05-12 19:59:26 +00:00
status :
2019-06-03 16:17:08 +00:00
" Hey, I think @ #{ user_three . nickname } is ugly. @ #{ user_four . nickname } is alright though. " ,
2020-05-12 19:59:26 +00:00
to : [ user_two . nickname , user_four . nickname , " nonexistent " ]
2019-06-03 16:17:08 +00:00
} )
assert user . ap_id in activity . recipients
assert user_two . ap_id in activity . recipients
assert user_four . ap_id in activity . recipients
refute user_three . ap_id in activity . recipients
end
2018-09-02 00:14:25 +00:00
test " it filters out obviously bad tags when accepting a post as HTML " do
user = insert ( :user )
2018-10-05 21:11:22 +00:00
post = " <p><b>2hu</b></p><script>alert('xss')</script> "
2018-09-02 00:14:25 +00:00
{ :ok , activity } =
CommonAPI . post ( user , %{
2020-05-12 19:59:26 +00:00
status : post ,
content_type : " text/html "
2018-09-02 00:14:25 +00:00
} )
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2018-11-25 22:31:07 +00:00
2019-10-28 22:18:08 +00:00
assert object . data [ " content " ] == " <p><b>2hu</b></p>alert(& # 39;xss& # 39;) "
2022-06-04 17:15:07 +00:00
assert object . data [ " source " ] [ " content " ] == post
2018-09-02 00:14:25 +00:00
end
test " it filters out obviously bad tags when accepting a post as Markdown " do
user = insert ( :user )
2018-10-05 21:11:22 +00:00
post = " <p><b>2hu</b></p><script>alert('xss')</script> "
2018-09-02 00:14:25 +00:00
{ :ok , activity } =
CommonAPI . post ( user , %{
2020-05-12 19:59:26 +00:00
status : post ,
content_type : " text/markdown "
2018-09-02 00:14:25 +00:00
} )
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2018-11-25 22:31:07 +00:00
2020-10-13 19:27:50 +00:00
assert object . data [ " content " ] == " <p><b>2hu</b></p> "
2022-06-04 17:15:07 +00:00
assert object . data [ " source " ] [ " content " ] == post
2018-09-02 00:14:25 +00:00
end
2019-05-14 13:12:47 +00:00
2019-05-15 14:30:08 +00:00
test " it does not allow replies to direct messages that are not direct messages themselves " do
user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " suya.. " , visibility : " direct " } )
2019-05-15 14:30:08 +00:00
assert { :ok , _ } =
CommonAPI . post ( user , %{
2020-05-12 19:59:26 +00:00
status : " suya.. " ,
visibility : " direct " ,
in_reply_to_status_id : activity . id
2019-05-15 14:30:08 +00:00
} )
Enum . each ( [ " public " , " private " , " unlisted " ] , fn visibility ->
2019-06-26 10:59:27 +00:00
assert { :error , " The message visibility must be direct " } =
2019-05-15 14:30:08 +00:00
CommonAPI . post ( user , %{
2020-05-12 19:59:26 +00:00
status : " suya.. " ,
visibility : visibility ,
in_reply_to_status_id : activity . id
2019-05-15 14:30:08 +00:00
} )
end )
end
2019-05-16 10:54:24 +00:00
2020-05-20 11:38:47 +00:00
test " replying with a direct message will NOT auto-add the author of the reply to the recipient list " do
user = insert ( :user )
other_user = insert ( :user )
third_user = insert ( :user )
{ :ok , post } = CommonAPI . post ( user , %{ status : " I'm stupid " } )
{ :ok , open_answer } =
CommonAPI . post ( other_user , %{ status : " No ur smart " , in_reply_to_status_id : post . id } )
# The OP is implicitly added
assert user . ap_id in open_answer . recipients
{ :ok , secret_answer } =
CommonAPI . post ( other_user , %{
status : " lol, that guy really is stupid, right, @ #{ third_user . nickname } ? " ,
in_reply_to_status_id : post . id ,
visibility : " direct "
} )
assert third_user . ap_id in secret_answer . recipients
# The OP is not added
refute user . ap_id in secret_answer . recipients
end
2019-05-14 13:12:47 +00:00
test " it allows to address a list " do
user = insert ( :user )
{ :ok , list } = Pleroma.List . create ( " foo " , user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " foobar " , visibility : " list: #{ list . id } " } )
2019-05-14 13:12:47 +00:00
2019-05-17 12:56:37 +00:00
assert activity . data [ " bcc " ] == [ list . ap_id ]
assert activity . recipients == [ list . ap_id , user . ap_id ]
2019-07-11 09:36:08 +00:00
assert activity . data [ " listMessage " ] == list . ap_id
2019-05-14 13:12:47 +00:00
end
2019-07-15 19:47:23 +00:00
test " it returns error when status is empty and no attachments " do
user = insert ( :user )
assert { :error , " Cannot post an empty status without attachments " } =
2020-05-12 19:59:26 +00:00
CommonAPI . post ( user , %{ status : " " } )
2019-07-15 19:47:23 +00:00
end
2020-03-10 18:08:00 +00:00
test " it validates character limits are correctly enforced " do
2021-01-26 17:58:43 +00:00
clear_config ( [ :instance , :limit ] , 5 )
2019-07-15 19:47:23 +00:00
user = insert ( :user )
assert { :error , " The status is over the character limit " } =
2020-05-12 19:59:26 +00:00
CommonAPI . post ( user , %{ status : " foobar " } )
2020-03-10 18:08:00 +00:00
2020-10-15 12:54:59 +00:00
assert { :ok , _activity } = CommonAPI . post ( user , %{ status : " 12345 " } )
2019-07-15 19:47:23 +00:00
end
2019-07-22 14:46:20 +00:00
2022-02-06 16:41:15 +00:00
test " it validates media attachment limits are correctly enforced " do
clear_config ( [ :instance , :max_media_attachments ] , 4 )
user = insert ( :user )
file = % Plug.Upload {
content_type : " image/jpeg " ,
path : Path . absname ( " test/fixtures/image.jpg " ) ,
filename : " an_image.jpg "
}
{ :ok , upload } = ActivityPub . upload ( file , actor : user . ap_id )
assert { :error , " Too many attachments " } =
CommonAPI . post ( user , %{
status : " " ,
media_ids : List . duplicate ( upload . id , 5 )
} )
assert { :ok , _activity } =
CommonAPI . post ( user , %{
status : " " ,
media_ids : [ upload . id ]
} )
end
2019-07-22 14:46:20 +00:00
test " it can handle activities that expire " do
user = insert ( :user )
2020-08-22 17:46:01 +00:00
expires_at = DateTime . add ( DateTime . utc_now ( ) , 1_000_000 )
2019-07-22 14:46:20 +00:00
2020-05-12 19:59:26 +00:00
assert { :ok , activity } = CommonAPI . post ( user , %{ status : " chai " , expires_in : 1_000_000 } )
2019-07-22 14:46:20 +00:00
2020-08-22 17:46:01 +00:00
assert_enqueued (
worker : Pleroma.Workers.PurgeExpiredActivity ,
args : %{ activity_id : activity . id } ,
scheduled_at : expires_at
)
2019-07-22 14:46:20 +00:00
end
2018-09-02 00:14:25 +00:00
end
2018-12-14 05:56:49 +00:00
describe " reactions " do
2019-08-27 22:56:28 +00:00
test " reacting to a status with an emoji " do
user = insert ( :user )
other_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " } )
2019-08-27 22:56:28 +00:00
2020-05-05 10:28:28 +00:00
{ :ok , reaction } = CommonAPI . react_with_emoji ( activity . id , user , " 👍 " )
2019-08-27 22:56:28 +00:00
assert reaction . data [ " actor " ] == user . ap_id
assert reaction . data [ " content " ] == " 👍 "
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " } )
2020-01-30 15:07:37 +00:00
{ :error , _ } = CommonAPI . react_with_emoji ( activity . id , user , " . " )
2019-08-27 22:56:28 +00:00
end
2019-09-30 14:38:19 +00:00
test " unreacting to a status with an emoji " do
user = insert ( :user )
other_user = insert ( :user )
2020-07-24 12:54:13 +00:00
clear_config ( [ :instance , :federating ] , true )
with_mock Pleroma.Web.Federator ,
publish : fn _ -> nil end do
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " } )
{ :ok , reaction } = CommonAPI . react_with_emoji ( activity . id , user , " 👍 " )
{ :ok , unreaction } = CommonAPI . unreact_with_emoji ( activity . id , user , " 👍 " )
2019-09-30 14:38:19 +00:00
2020-07-24 12:54:13 +00:00
assert unreaction . data [ " type " ] == " Undo "
assert unreaction . data [ " object " ] == reaction . data [ " id " ]
assert unreaction . local
2019-10-02 13:38:57 +00:00
2020-07-24 12:54:13 +00:00
# On federation, it contains the undone (and deleted) object
unreaction_with_object = %{
unreaction
| data : Map . put ( unreaction . data , " object " , reaction . data )
}
assert called ( Pleroma.Web.Federator . publish ( unreaction_with_object ) )
end
2019-09-30 14:38:19 +00:00
end
2018-12-14 05:56:49 +00:00
test " repeating a status " do
user = insert ( :user )
other_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " } )
2018-12-14 05:56:49 +00:00
2020-05-20 13:44:37 +00:00
{ :ok , % Activity { } = announce_activity } = CommonAPI . repeat ( activity . id , user )
assert Visibility . is_public? ( announce_activity )
2018-12-14 05:56:49 +00:00
end
2020-04-23 11:33:30 +00:00
test " can't repeat a repeat " do
user = insert ( :user )
other_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " } )
2020-04-23 11:33:30 +00:00
2020-05-20 13:44:37 +00:00
{ :ok , % Activity { } = announce } = CommonAPI . repeat ( activity . id , other_user )
2020-04-23 11:33:30 +00:00
2020-05-20 13:44:37 +00:00
refute match? ( { :ok , % Activity { } } , CommonAPI . repeat ( announce . id , user ) )
2020-04-23 11:33:30 +00:00
end
2019-10-01 17:08:25 +00:00
test " repeating a status privately " do
user = insert ( :user )
other_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " } )
2019-10-01 17:08:25 +00:00
2020-05-20 13:44:37 +00:00
{ :ok , % Activity { } = announce_activity } =
2020-05-12 19:59:26 +00:00
CommonAPI . repeat ( activity . id , user , %{ visibility : " private " } )
2019-10-01 17:08:25 +00:00
assert Visibility . is_private? ( announce_activity )
2020-05-21 11:16:21 +00:00
refute Visibility . visible_for_user? ( announce_activity , nil )
2019-10-01 17:08:25 +00:00
end
2021-01-18 16:15:57 +00:00
test " author can repeat own private statuses " do
2021-01-18 17:01:00 +00:00
author = insert ( :user )
follower = insert ( :user )
CommonAPI . follow ( follower , author )
2021-01-18 16:15:57 +00:00
2021-01-18 17:01:00 +00:00
{ :ok , activity } = CommonAPI . post ( author , %{ status : " cofe " , visibility : " private " } )
2021-01-18 16:15:57 +00:00
2021-01-18 17:01:00 +00:00
{ :ok , % Activity { } = announce_activity } = CommonAPI . repeat ( activity . id , author )
2021-01-18 16:15:57 +00:00
assert Visibility . is_private? ( announce_activity )
refute Visibility . visible_for_user? ( announce_activity , nil )
2021-01-18 17:01:00 +00:00
assert Visibility . visible_for_user? ( activity , follower )
assert { :error , :not_found } = CommonAPI . repeat ( activity . id , follower )
2021-01-18 16:15:57 +00:00
end
2018-12-14 05:56:49 +00:00
test " favoriting a status " do
user = insert ( :user )
other_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , post_activity } = CommonAPI . post ( other_user , %{ status : " cofe " } )
2018-12-14 05:56:49 +00:00
2019-10-16 14:16:39 +00:00
{ :ok , % Activity { data : data } } = CommonAPI . favorite ( user , post_activity . id )
assert data [ " type " ] == " Like "
assert data [ " actor " ] == user . ap_id
assert data [ " object " ] == post_activity . data [ " object " ]
2018-12-14 05:56:49 +00:00
end
2020-01-20 13:27:59 +00:00
test " retweeting a status twice returns the status " do
2018-12-14 05:56:49 +00:00
user = insert ( :user )
other_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " } )
2020-05-20 13:44:37 +00:00
{ :ok , % Activity { } = announce } = CommonAPI . repeat ( activity . id , user )
{ :ok , ^ announce } = CommonAPI . repeat ( activity . id , user )
2018-12-14 05:56:49 +00:00
end
2020-03-19 17:00:55 +00:00
test " favoriting a status twice returns ok, but without the like activity " do
2018-12-14 05:56:49 +00:00
user = insert ( :user )
other_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " } )
2019-10-16 14:16:39 +00:00
{ :ok , % Activity { } } = CommonAPI . favorite ( user , activity . id )
2020-03-19 17:00:55 +00:00
assert { :ok , :already_liked } = CommonAPI . favorite ( user , activity . id )
2018-12-14 05:56:49 +00:00
end
end
2019-01-07 13:45:33 +00:00
2019-01-08 08:25:50 +00:00
describe " pinned statuses " do
2019-01-09 12:54:37 +00:00
setup do
2021-01-26 17:58:43 +00:00
clear_config ( [ :instance , :max_pinned_statuses ] , 1 )
2019-01-07 13:45:33 +00:00
2019-01-09 12:54:37 +00:00
user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " HI!!! " } )
2019-01-07 13:45:33 +00:00
2019-01-09 12:54:37 +00:00
[ user : user , activity : activity ]
2019-01-07 13:45:33 +00:00
end
2021-02-03 13:09:28 +00:00
test " activity not found error " , %{ user : user } do
assert { :error , :not_found } = CommonAPI . pin ( " id " , user )
end
2019-01-09 12:54:37 +00:00
test " pin status " , %{ user : user , activity : activity } do
assert { :ok , ^ activity } = CommonAPI . pin ( activity . id , user )
2019-01-11 05:31:31 +00:00
2021-02-03 13:09:28 +00:00
%{ data : %{ " id " = > object_id } } = Object . normalize ( activity )
2019-01-11 05:31:31 +00:00
user = refresh_record ( user )
2021-02-03 13:09:28 +00:00
assert user . pinned_objects |> Map . keys ( ) == [ object_id ]
2019-01-09 10:40:15 +00:00
end
2020-02-02 11:55:06 +00:00
test " pin poll " , %{ user : user } do
{ :ok , activity } =
CommonAPI . post ( user , %{
2020-05-12 19:59:26 +00:00
status : " How is fediverse today? " ,
poll : %{ options : [ " Absolutely outstanding " , " Not good " ] , expires_in : 20 }
2020-02-02 11:55:06 +00:00
} )
assert { :ok , ^ activity } = CommonAPI . pin ( activity . id , user )
2021-02-03 13:09:28 +00:00
%{ data : %{ " id " = > object_id } } = Object . normalize ( activity )
2020-02-02 11:55:06 +00:00
user = refresh_record ( user )
2021-02-03 13:09:28 +00:00
assert user . pinned_objects |> Map . keys ( ) == [ object_id ]
2020-02-02 11:55:06 +00:00
end
2019-06-29 19:24:03 +00:00
test " unlisted statuses can be pinned " , %{ user : user } do
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " HI!!! " , visibility : " unlisted " } )
2019-06-29 19:24:03 +00:00
assert { :ok , ^ activity } = CommonAPI . pin ( activity . id , user )
end
2019-01-09 12:54:37 +00:00
test " only self-authored can be pinned " , %{ activity : activity } do
2019-01-07 13:45:33 +00:00
user = insert ( :user )
2021-02-03 13:09:28 +00:00
assert { :error , :ownership_error } = CommonAPI . pin ( activity . id , user )
2019-01-09 12:54:37 +00:00
end
test " max pinned statuses " , %{ user : user , activity : activity_one } do
2020-05-12 19:59:26 +00:00
{ :ok , activity_two } = CommonAPI . post ( user , %{ status : " HI!!! " } )
2019-01-07 13:45:33 +00:00
assert { :ok , ^ activity_one } = CommonAPI . pin ( activity_one . id , user )
2019-01-08 09:01:35 +00:00
user = refresh_record ( user )
2019-01-07 13:45:33 +00:00
2021-02-03 13:09:28 +00:00
assert { :error , :pinned_statuses_limit_reached } = CommonAPI . pin ( activity_two . id , user )
end
test " only public can be pinned " , %{ user : user } do
{ :ok , activity } = CommonAPI . post ( user , %{ status : " private status " , visibility : " private " } )
{ :error , :visibility_error } = CommonAPI . pin ( activity . id , user )
2019-01-07 13:45:33 +00:00
end
2019-01-09 12:54:37 +00:00
test " unpin status " , %{ user : user , activity : activity } do
2019-01-07 13:45:33 +00:00
{ :ok , activity } = CommonAPI . pin ( activity . id , user )
2019-01-11 05:31:31 +00:00
user = refresh_record ( user )
2020-04-23 11:33:30 +00:00
id = activity . id
assert match? ( { :ok , %{ id : ^ id } } , CommonAPI . unpin ( activity . id , user ) )
2019-01-11 05:31:31 +00:00
user = refresh_record ( user )
2021-02-03 13:09:28 +00:00
assert user . pinned_objects == %{ }
2019-01-11 05:31:31 +00:00
end
2019-01-11 05:47:44 +00:00
test " should unpin when deleting a status " , %{ user : user , activity : activity } do
2019-01-11 05:31:31 +00:00
{ :ok , activity } = CommonAPI . pin ( activity . id , user )
user = refresh_record ( user )
assert { :ok , _ } = CommonAPI . delete ( activity . id , user )
user = refresh_record ( user )
2021-02-03 13:09:28 +00:00
assert user . pinned_objects == %{ }
end
test " ephemeral activity won't be deleted if was pinned " , %{ user : user } do
{ :ok , activity } = CommonAPI . post ( user , %{ status : " Hello! " , expires_in : 601 } )
assert Pleroma.Workers.PurgeExpiredActivity . get_expiration ( activity . id )
{ :ok , _activity } = CommonAPI . pin ( activity . id , user )
refute Pleroma.Workers.PurgeExpiredActivity . get_expiration ( activity . id )
user = refresh_record ( user )
{ :ok , _ } = CommonAPI . unpin ( activity . id , user )
# recreates expiration job on unpin
assert Pleroma.Workers.PurgeExpiredActivity . get_expiration ( activity . id )
end
test " ephemeral activity deletion job won't be deleted on pinning error " , %{
user : user ,
activity : activity
} do
clear_config ( [ :instance , :max_pinned_statuses ] , 1 )
{ :ok , _activity } = CommonAPI . pin ( activity . id , user )
{ :ok , activity2 } = CommonAPI . post ( user , %{ status : " another status " , expires_in : 601 } )
assert Pleroma.Workers.PurgeExpiredActivity . get_expiration ( activity2 . id )
user = refresh_record ( user )
{ :error , :pinned_statuses_limit_reached } = CommonAPI . pin ( activity2 . id , user )
assert Pleroma.Workers.PurgeExpiredActivity . get_expiration ( activity2 . id )
2019-01-07 13:45:33 +00:00
end
end
2019-02-11 10:59:51 +00:00
describe " mute tests " do
setup do
user = insert ( :user )
activity = insert ( :note_activity )
[ user : user , activity : activity ]
end
2020-08-28 15:17:44 +00:00
test " marks notifications as read after mute " do
author = insert ( :user )
activity = insert ( :note_activity , user : author )
friend1 = insert ( :user )
friend2 = insert ( :user )
{ :ok , reply_activity } =
CommonAPI . post (
friend2 ,
%{
status : " @ #{ author . nickname } @ #{ friend1 . nickname } test reply " ,
in_reply_to_status_id : activity . id
}
)
{ :ok , favorite_activity } = CommonAPI . favorite ( friend2 , activity . id )
{ :ok , repeat_activity } = CommonAPI . repeat ( activity . id , friend1 )
assert Repo . aggregate (
from ( n in Notification , where : n . seen == false and n . user_id == ^ friend1 . id ) ,
:count
) == 1
unread_notifications =
Repo . all ( from ( n in Notification , where : n . seen == false , where : n . user_id == ^ author . id ) )
assert Enum . any? ( unread_notifications , fn n ->
n . type == " favourite " && n . activity_id == favorite_activity . id
end )
assert Enum . any? ( unread_notifications , fn n ->
n . type == " reblog " && n . activity_id == repeat_activity . id
end )
assert Enum . any? ( unread_notifications , fn n ->
n . type == " mention " && n . activity_id == reply_activity . id
end )
{ :ok , _ } = CommonAPI . add_mute ( author , activity )
assert CommonAPI . thread_muted? ( author , activity )
assert Repo . aggregate (
from ( n in Notification , where : n . seen == false and n . user_id == ^ friend1 . id ) ,
:count
) == 1
read_notifications =
Repo . all ( from ( n in Notification , where : n . seen == true , where : n . user_id == ^ author . id ) )
assert Enum . any? ( read_notifications , fn n ->
n . type == " favourite " && n . activity_id == favorite_activity . id
end )
assert Enum . any? ( read_notifications , fn n ->
n . type == " reblog " && n . activity_id == repeat_activity . id
end )
assert Enum . any? ( read_notifications , fn n ->
n . type == " mention " && n . activity_id == reply_activity . id
end )
end
2019-02-11 10:59:51 +00:00
test " add mute " , %{ user : user , activity : activity } do
{ :ok , _ } = CommonAPI . add_mute ( user , activity )
assert CommonAPI . thread_muted? ( user , activity )
end
2020-09-08 12:13:50 +00:00
test " add expiring mute " , %{ user : user , activity : activity } do
{ :ok , _ } = CommonAPI . add_mute ( user , activity , %{ expires_in : 60 } )
assert CommonAPI . thread_muted? ( user , activity )
worker = Pleroma.Workers.MuteExpireWorker
args = %{ " op " = > " unmute_conversation " , " user_id " = > user . id , " activity_id " = > activity . id }
assert_enqueued (
worker : worker ,
args : args
)
assert :ok = perform_job ( worker , args )
refute CommonAPI . thread_muted? ( user , activity )
end
2019-02-11 10:59:51 +00:00
test " remove mute " , %{ user : user , activity : activity } do
CommonAPI . add_mute ( user , activity )
{ :ok , _ } = CommonAPI . remove_mute ( user , activity )
refute CommonAPI . thread_muted? ( user , activity )
end
2020-09-20 17:51:20 +00:00
test " remove mute by ids " , %{ user : user , activity : activity } do
CommonAPI . add_mute ( user , activity )
{ :ok , _ } = CommonAPI . remove_mute ( user . id , activity . id )
refute CommonAPI . thread_muted? ( user , activity )
end
2019-02-11 10:59:51 +00:00
test " check that mutes can't be duplicate " , %{ user : user , activity : activity } do
CommonAPI . add_mute ( user , activity )
{ :error , _ } = CommonAPI . add_mute ( user , activity )
end
end
2019-02-20 16:51:25 +00:00
describe " reports " do
test " creates a report " do
reporter = insert ( :user )
target_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( target_user , %{ status : " foobar " } )
2019-02-20 16:51:25 +00:00
reporter_ap_id = reporter . ap_id
target_ap_id = target_user . ap_id
activity_ap_id = activity . data [ " id " ]
comment = " foobar "
report_data = %{
2020-04-28 12:50:37 +00:00
account_id : target_user . id ,
comment : comment ,
status_ids : [ activity . id ]
2019-02-20 16:51:25 +00:00
}
2019-10-23 19:27:22 +00:00
note_obj = %{
" type " = > " Note " ,
" id " = > activity_ap_id ,
" content " = > " foobar " ,
" published " = > activity . object . data [ " published " ] ,
" actor " = > AccountView . render ( " show.json " , %{ user : target_user } )
}
2019-02-20 16:51:25 +00:00
assert { :ok , flag_activity } = CommonAPI . report ( reporter , report_data )
assert % Activity {
actor : ^ reporter_ap_id ,
data : %{
" type " = > " Flag " ,
" content " = > ^ comment ,
2019-10-23 19:27:22 +00:00
" object " = > [ ^ target_ap_id , ^ note_obj ] ,
2019-05-16 19:09:18 +00:00
" state " = > " open "
2019-02-20 16:51:25 +00:00
}
} = flag_activity
end
2019-05-16 19:09:18 +00:00
test " updates report state " do
[ reporter , target_user ] = insert_pair ( :user )
activity = insert ( :note_activity , user : target_user )
{ :ok , % Activity { id : report_id } } =
CommonAPI . report ( reporter , %{
2020-04-28 12:50:37 +00:00
account_id : target_user . id ,
comment : " I feel offended " ,
status_ids : [ activity . id ]
2019-05-16 19:09:18 +00:00
} )
{ :ok , report } = CommonAPI . update_report_state ( report_id , " resolved " )
assert report . data [ " state " ] == " resolved "
2019-10-27 13:05:32 +00:00
[ reported_user , activity_id ] = report . data [ " object " ]
assert reported_user == target_user . ap_id
assert activity_id == activity . data [ " id " ]
2019-05-16 19:09:18 +00:00
end
test " does not update report state when state is unsupported " do
[ reporter , target_user ] = insert_pair ( :user )
activity = insert ( :note_activity , user : target_user )
{ :ok , % Activity { id : report_id } } =
CommonAPI . report ( reporter , %{
2020-04-28 12:50:37 +00:00
account_id : target_user . id ,
comment : " I feel offended " ,
status_ids : [ activity . id ]
2019-05-16 19:09:18 +00:00
} )
assert CommonAPI . update_report_state ( report_id , " test " ) == { :error , " Unsupported state " }
end
2019-10-04 16:00:58 +00:00
test " updates state of multiple reports " do
[ reporter , target_user ] = insert_pair ( :user )
activity = insert ( :note_activity , user : target_user )
{ :ok , % Activity { id : first_report_id } } =
CommonAPI . report ( reporter , %{
2020-04-28 12:50:37 +00:00
account_id : target_user . id ,
comment : " I feel offended " ,
status_ids : [ activity . id ]
2019-10-04 16:00:58 +00:00
} )
{ :ok , % Activity { id : second_report_id } } =
CommonAPI . report ( reporter , %{
2020-04-28 12:50:37 +00:00
account_id : target_user . id ,
comment : " I feel very offended! " ,
status_ids : [ activity . id ]
2019-10-04 16:00:58 +00:00
} )
{ :ok , report_ids } =
CommonAPI . update_report_state ( [ first_report_id , second_report_id ] , " resolved " )
first_report = Activity . get_by_id ( first_report_id )
second_report = Activity . get_by_id ( second_report_id )
assert report_ids -- [ first_report_id , second_report_id ] == [ ]
assert first_report . data [ " state " ] == " resolved "
assert second_report . data [ " state " ] == " resolved "
end
2019-02-20 16:51:25 +00:00
end
2019-03-15 13:06:58 +00:00
describe " reblog muting " do
setup do
muter = insert ( :user )
muted = insert ( :user )
[ muter : muter , muted : muted ]
end
test " add a reblog mute " , %{ muter : muter , muted : muted } do
2019-11-19 20:22:10 +00:00
{ :ok , _reblog_mute } = CommonAPI . hide_reblogs ( muter , muted )
2019-03-15 13:06:58 +00:00
2019-05-16 10:35:07 +00:00
assert User . showing_reblogs? ( muter , muted ) == false
2019-03-15 13:06:58 +00:00
end
test " remove a reblog mute " , %{ muter : muter , muted : muted } do
2019-11-19 20:22:10 +00:00
{ :ok , _reblog_mute } = CommonAPI . hide_reblogs ( muter , muted )
{ :ok , _reblog_mute } = CommonAPI . show_reblogs ( muter , muted )
2019-03-15 13:06:58 +00:00
2019-05-16 10:35:07 +00:00
assert User . showing_reblogs? ( muter , muted ) == true
2019-03-15 13:06:58 +00:00
end
end
2019-06-05 13:43:54 +00:00
2020-07-08 15:07:24 +00:00
describe " follow/2 " do
test " directly follows a non-locked local user " do
[ follower , followed ] = insert_pair ( :user )
{ :ok , follower , followed , _ } = CommonAPI . follow ( follower , followed )
assert User . following? ( follower , followed )
end
end
2019-07-14 19:25:03 +00:00
describe " unfollow/2 " do
test " also unsubscribes a user " do
[ follower , followed ] = insert_pair ( :user )
{ :ok , follower , followed , _ } = CommonAPI . follow ( follower , followed )
2019-11-20 12:46:11 +00:00
{ :ok , _subscription } = User . subscribe ( follower , followed )
2019-07-14 19:25:03 +00:00
assert User . subscribed_to? ( follower , followed )
{ :ok , follower } = CommonAPI . unfollow ( follower , followed )
refute User . subscribed_to? ( follower , followed )
end
2020-02-04 16:35:32 +00:00
2022-01-12 20:39:14 +00:00
test " also unpins a user " do
[ follower , followed ] = insert_pair ( :user )
{ :ok , follower , followed , _ } = CommonAPI . follow ( follower , followed )
{ :ok , _endorsement } = User . endorse ( follower , followed )
assert User . endorses? ( follower , followed )
{ :ok , follower } = CommonAPI . unfollow ( follower , followed )
refute User . endorses? ( follower , followed )
end
2020-02-06 12:47:15 +00:00
test " cancels a pending follow for a local user " do
2020-02-04 16:35:32 +00:00
follower = insert ( :user )
2020-10-13 14:31:13 +00:00
followed = insert ( :user , is_locked : true )
2020-02-04 16:35:32 +00:00
2020-02-06 12:47:15 +00:00
assert { :ok , follower , followed , %{ id : activity_id , data : %{ " state " = > " pending " } } } =
CommonAPI . follow ( follower , followed )
2020-03-28 15:49:03 +00:00
assert User . get_follow_state ( follower , followed ) == :follow_pending
2020-02-06 12:47:15 +00:00
assert { :ok , follower } = CommonAPI . unfollow ( follower , followed )
2020-02-07 12:17:34 +00:00
assert User . get_follow_state ( follower , followed ) == nil
2020-02-06 12:47:15 +00:00
assert %{ id : ^ activity_id , data : %{ " state " = > " cancelled " } } =
Pleroma.Web.ActivityPub.Utils . fetch_latest_follow ( follower , followed )
assert %{
data : %{
" type " = > " Undo " ,
" object " = > %{ " type " = > " Follow " , " state " = > " cancelled " }
}
} = Pleroma.Web.ActivityPub.Utils . fetch_latest_undo ( follower )
end
test " cancels a pending follow for a remote user " do
follower = insert ( :user )
2020-10-13 14:31:13 +00:00
followed = insert ( :user , is_locked : true , local : false , ap_enabled : true )
2020-02-06 12:47:15 +00:00
2020-02-04 16:35:32 +00:00
assert { :ok , follower , followed , %{ id : activity_id , data : %{ " state " = > " pending " } } } =
CommonAPI . follow ( follower , followed )
2020-03-28 15:49:03 +00:00
assert User . get_follow_state ( follower , followed ) == :follow_pending
2020-02-04 16:35:32 +00:00
assert { :ok , follower } = CommonAPI . unfollow ( follower , followed )
2020-02-07 12:17:34 +00:00
assert User . get_follow_state ( follower , followed ) == nil
2020-02-04 16:35:32 +00:00
assert %{ id : ^ activity_id , data : %{ " state " = > " cancelled " } } =
Pleroma.Web.ActivityPub.Utils . fetch_latest_follow ( follower , followed )
assert %{
data : %{
" type " = > " Undo " ,
" object " = > %{ " type " = > " Follow " , " state " = > " cancelled " }
}
} = Pleroma.Web.ActivityPub.Utils . fetch_latest_undo ( follower )
end
2019-07-14 19:25:03 +00:00
end
2019-06-05 13:43:54 +00:00
describe " accept_follow_request/2 " do
test " after acceptance, it sets all existing pending follow request states to 'accept' " do
2020-10-13 14:31:13 +00:00
user = insert ( :user , is_locked : true )
2019-06-05 13:43:54 +00:00
follower = insert ( :user )
follower_two = insert ( :user )
2020-07-08 15:07:24 +00:00
{ :ok , _ , _ , follow_activity } = CommonAPI . follow ( follower , user )
{ :ok , _ , _ , follow_activity_two } = CommonAPI . follow ( follower , user )
{ :ok , _ , _ , follow_activity_three } = CommonAPI . follow ( follower_two , user )
2019-06-05 13:43:54 +00:00
assert follow_activity . data [ " state " ] == " pending "
assert follow_activity_two . data [ " state " ] == " pending "
assert follow_activity_three . data [ " state " ] == " pending "
{ :ok , _follower } = CommonAPI . accept_follow_request ( follower , user )
assert Repo . get ( Activity , follow_activity . id ) . data [ " state " ] == " accept "
assert Repo . get ( Activity , follow_activity_two . id ) . data [ " state " ] == " accept "
assert Repo . get ( Activity , follow_activity_three . id ) . data [ " state " ] == " pending "
end
test " after rejection, it sets all existing pending follow request states to 'reject' " do
2020-10-13 14:31:13 +00:00
user = insert ( :user , is_locked : true )
2019-06-05 13:43:54 +00:00
follower = insert ( :user )
follower_two = insert ( :user )
2020-07-08 15:07:24 +00:00
{ :ok , _ , _ , follow_activity } = CommonAPI . follow ( follower , user )
{ :ok , _ , _ , follow_activity_two } = CommonAPI . follow ( follower , user )
{ :ok , _ , _ , follow_activity_three } = CommonAPI . follow ( follower_two , user )
2019-06-05 13:43:54 +00:00
assert follow_activity . data [ " state " ] == " pending "
assert follow_activity_two . data [ " state " ] == " pending "
assert follow_activity_three . data [ " state " ] == " pending "
{ :ok , _follower } = CommonAPI . reject_follow_request ( follower , user )
assert Repo . get ( Activity , follow_activity . id ) . data [ " state " ] == " reject "
assert Repo . get ( Activity , follow_activity_two . id ) . data [ " state " ] == " reject "
assert Repo . get ( Activity , follow_activity_three . id ) . data [ " state " ] == " pending "
end
2020-04-27 14:41:38 +00:00
test " doesn't create a following relationship if the corresponding follow request doesn't exist " do
2020-10-13 14:31:13 +00:00
user = insert ( :user , is_locked : true )
2020-04-27 14:41:38 +00:00
not_follower = insert ( :user )
CommonAPI . accept_follow_request ( not_follower , user )
assert Pleroma.FollowingRelationship . following? ( not_follower , user ) == false
end
2019-06-05 13:43:54 +00:00
end
2019-07-15 19:47:23 +00:00
describe " vote/3 " do
test " does not allow to vote twice " do
user = insert ( :user )
other_user = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( user , %{
2020-05-12 19:59:26 +00:00
status : " Am I cute? " ,
poll : %{ options : [ " Yes " , " No " ] , expires_in : 20 }
2019-07-15 19:47:23 +00:00
} )
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2019-07-15 19:47:23 +00:00
{ :ok , _ , object } = CommonAPI . vote ( other_user , object , [ 0 ] )
assert { :error , " Already voted " } == CommonAPI . vote ( other_user , object , [ 1 ] )
end
end
2019-09-28 00:24:32 +00:00
describe " listen/2 " do
test " returns a valid activity " do
user = insert ( :user )
{ :ok , activity } =
CommonAPI . listen ( user , %{
2020-05-19 11:53:18 +00:00
title : " lain radio episode 1 " ,
album : " lain radio " ,
artist : " lain " ,
length : 180_000
2019-09-28 00:24:32 +00:00
} )
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2019-09-28 00:24:32 +00:00
assert object . data [ " title " ] == " lain radio episode 1 "
assert Visibility . get_visibility ( activity ) == " public "
end
test " respects visibility=private " do
user = insert ( :user )
{ :ok , activity } =
CommonAPI . listen ( user , %{
2020-05-19 11:53:18 +00:00
title : " lain radio episode 1 " ,
album : " lain radio " ,
artist : " lain " ,
length : 180_000 ,
visibility : " private "
2019-09-28 00:24:32 +00:00
} )
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2019-09-28 00:24:32 +00:00
assert object . data [ " title " ] == " lain radio episode 1 "
assert Visibility . get_visibility ( activity ) == " private "
end
end
2020-08-31 21:48:24 +00:00
describe " get_user/1 " do
test " gets user by ap_id " do
user = insert ( :user )
assert CommonAPI . get_user ( user . ap_id ) == user
end
test " gets user by guessed nickname " do
user = insert ( :user , ap_id : " " , nickname : " mario@mushroom.kingdom " )
assert CommonAPI . get_user ( " https://mushroom.kingdom/users/mario " ) == user
end
test " fallback " do
assert % User {
name : " " ,
ap_id : " " ,
nickname : " erroruser@example.com "
} = CommonAPI . get_user ( " " )
end
end
2020-10-02 17:00:50 +00:00
2020-11-11 14:47:57 +00:00
describe " with `local` visibility " do
2020-10-02 17:00:50 +00:00
setup do : clear_config ( [ :instance , :federating ] , true )
test " post " do
user = insert ( :user )
with_mock Pleroma.Web.Federator , publish : fn _ -> :ok end do
2020-11-11 14:47:57 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " # 2hu # 2HU " , visibility : " local " } )
2020-10-02 17:00:50 +00:00
2020-11-11 14:47:57 +00:00
assert Visibility . is_local_public? ( activity )
2020-10-02 17:00:50 +00:00
assert_not_called ( Pleroma.Web.Federator . publish ( activity ) )
end
end
test " delete " do
user = insert ( :user )
{ :ok , % Activity { id : activity_id } } =
2020-11-11 14:47:57 +00:00
CommonAPI . post ( user , %{ status : " # 2hu # 2HU " , visibility : " local " } )
2020-10-02 17:00:50 +00:00
with_mock Pleroma.Web.Federator , publish : fn _ -> :ok end do
assert { :ok , % Activity { data : %{ " deleted_activity_id " = > ^ activity_id } } = activity } =
CommonAPI . delete ( activity_id , user )
2020-11-11 14:47:57 +00:00
assert Visibility . is_local_public? ( activity )
2020-10-02 17:00:50 +00:00
assert_not_called ( Pleroma.Web.Federator . publish ( activity ) )
end
end
test " repeat " do
user = insert ( :user )
other_user = insert ( :user )
{ :ok , % Activity { id : activity_id } } =
2020-11-11 14:47:57 +00:00
CommonAPI . post ( other_user , %{ status : " cofe " , visibility : " local " } )
2020-10-02 17:00:50 +00:00
with_mock Pleroma.Web.Federator , publish : fn _ -> :ok end do
assert { :ok , % Activity { data : %{ " type " = > " Announce " } } = activity } =
CommonAPI . repeat ( activity_id , user )
2020-11-11 14:47:57 +00:00
assert Visibility . is_local_public? ( activity )
2020-10-02 17:00:50 +00:00
refute called ( Pleroma.Web.Federator . publish ( activity ) )
end
end
test " unrepeat " do
user = insert ( :user )
other_user = insert ( :user )
{ :ok , % Activity { id : activity_id } } =
2020-11-11 14:47:57 +00:00
CommonAPI . post ( other_user , %{ status : " cofe " , visibility : " local " } )
2020-10-02 17:00:50 +00:00
assert { :ok , _ } = CommonAPI . repeat ( activity_id , user )
with_mock Pleroma.Web.Federator , publish : fn _ -> :ok end do
assert { :ok , % Activity { data : %{ " type " = > " Undo " } } = activity } =
CommonAPI . unrepeat ( activity_id , user )
2020-11-11 14:47:57 +00:00
assert Visibility . is_local_public? ( activity )
2020-10-02 17:00:50 +00:00
refute called ( Pleroma.Web.Federator . publish ( activity ) )
end
end
test " favorite " do
user = insert ( :user )
other_user = insert ( :user )
2020-11-11 14:47:57 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " , visibility : " local " } )
2020-10-02 17:00:50 +00:00
with_mock Pleroma.Web.Federator , publish : fn _ -> :ok end do
assert { :ok , % Activity { data : %{ " type " = > " Like " } } = activity } =
CommonAPI . favorite ( user , activity . id )
2020-11-11 14:47:57 +00:00
assert Visibility . is_local_public? ( activity )
2020-10-02 17:00:50 +00:00
refute called ( Pleroma.Web.Federator . publish ( activity ) )
end
end
test " unfavorite " do
user = insert ( :user )
other_user = insert ( :user )
2020-11-11 14:47:57 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " , visibility : " local " } )
2020-10-02 17:00:50 +00:00
{ :ok , % Activity { } } = CommonAPI . favorite ( user , activity . id )
with_mock Pleroma.Web.Federator , publish : fn _ -> :ok end do
assert { :ok , activity } = CommonAPI . unfavorite ( activity . id , user )
2020-11-11 14:47:57 +00:00
assert Visibility . is_local_public? ( activity )
2020-10-02 17:00:50 +00:00
refute called ( Pleroma.Web.Federator . publish ( activity ) )
end
end
test " react_with_emoji " do
user = insert ( :user )
other_user = insert ( :user )
2020-11-11 14:47:57 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " , visibility : " local " } )
2020-10-02 17:00:50 +00:00
with_mock Pleroma.Web.Federator , publish : fn _ -> :ok end do
assert { :ok , % Activity { data : %{ " type " = > " EmojiReact " } } = activity } =
CommonAPI . react_with_emoji ( activity . id , user , " 👍 " )
2020-11-11 14:47:57 +00:00
assert Visibility . is_local_public? ( activity )
2020-10-02 17:00:50 +00:00
refute called ( Pleroma.Web.Federator . publish ( activity ) )
end
end
test " unreact_with_emoji " do
user = insert ( :user )
other_user = insert ( :user )
2020-11-11 14:47:57 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " cofe " , visibility : " local " } )
2020-10-02 17:00:50 +00:00
{ :ok , _reaction } = CommonAPI . react_with_emoji ( activity . id , user , " 👍 " )
with_mock Pleroma.Web.Federator , publish : fn _ -> :ok end do
assert { :ok , % Activity { data : %{ " type " = > " Undo " } } = activity } =
CommonAPI . unreact_with_emoji ( activity . id , user , " 👍 " )
2020-11-11 14:47:57 +00:00
assert Visibility . is_local_public? ( activity )
2020-10-02 17:00:50 +00:00
refute called ( Pleroma.Web.Federator . publish ( activity ) )
end
end
end
2022-05-31 18:29:12 +00:00
describe " update/3 " do
test " updates a post " do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ status : " foo1 " , spoiler_text : " title 1 " } )
{ :ok , updated } = CommonAPI . update ( user , activity , %{ status : " updated 2 " } )
updated_object = Object . normalize ( updated )
assert updated_object . data [ " content " ] == " updated 2 "
assert Map . get ( updated_object . data , " summary " , " " ) == " "
assert Map . has_key? ( updated_object . data , " updated " )
end
test " does not change visibility " do
user = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( user , %{ status : " foo1 " , spoiler_text : " title 1 " , visibility : " private " } )
{ :ok , updated } = CommonAPI . update ( user , activity , %{ status : " updated 2 " } )
updated_object = Object . normalize ( updated )
assert updated_object . data [ " content " ] == " updated 2 "
assert Map . get ( updated_object . data , " summary " , " " ) == " "
assert Visibility . get_visibility ( updated_object ) == " private "
assert Visibility . get_visibility ( updated ) == " private "
end
2022-06-25 13:23:09 +00:00
test " updates a post with emoji " do
[ { emoji1 , _ } , { emoji2 , _ } | _ ] = Pleroma.Emoji . get_all ( )
user = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( user , %{ status : " foo1 " , spoiler_text : " title 1 : #{ emoji1 } : " } )
{ :ok , updated } = CommonAPI . update ( user , activity , %{ status : " updated 2 : #{ emoji2 } : " } )
updated_object = Object . normalize ( updated )
assert updated_object . data [ " content " ] == " updated 2 : #{ emoji2 } : "
assert %{ ^ emoji2 = > _ } = updated_object . data [ " emoji " ]
end
2022-06-25 15:20:46 +00:00
test " updates a post with emoji and federate properly " do
[ { emoji1 , _ } , { emoji2 , _ } | _ ] = Pleroma.Emoji . get_all ( )
user = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( user , %{ status : " foo1 " , spoiler_text : " title 1 : #{ emoji1 } : " } )
clear_config ( [ :instance , :federating ] , true )
with_mock Pleroma.Web.Federator ,
2022-07-07 19:11:29 +00:00
publish : fn _p -> nil end do
2022-06-25 15:20:46 +00:00
{ :ok , updated } = CommonAPI . update ( user , activity , %{ status : " updated 2 : #{ emoji2 } : " } )
assert updated . data [ " object " ] [ " content " ] == " updated 2 : #{ emoji2 } : "
assert %{ ^ emoji2 = > _ } = updated . data [ " object " ] [ " emoji " ]
assert called ( Pleroma.Web.Federator . publish ( updated ) )
end
end
2022-07-09 22:00:42 +00:00
test " editing a post that copied a remote title with remote emoji should keep that emoji " do
remote_emoji_uri = " https://remote.org/emoji.png "
note =
insert (
:note ,
data : %{
" summary " = > " :remoteemoji: " ,
" emoji " = > %{
" remoteemoji " = > remote_emoji_uri
} ,
" tag " = > [
%{
" type " = > " Emoji " ,
" name " = > " remoteemoji " ,
" icon " = > %{ " url " = > remote_emoji_uri }
}
]
}
)
note_activity = insert ( :note_activity , note : note )
user = insert ( :user )
{ :ok , reply } =
CommonAPI . post ( user , %{
status : " reply " ,
spoiler_text : " :remoteemoji: " ,
in_reply_to_id : note_activity . id
} )
assert reply . object . data [ " emoji " ] [ " remoteemoji " ] == remote_emoji_uri
{ :ok , edit } =
CommonAPI . update ( user , reply , %{ status : " reply mew mew " , spoiler_text : " :remoteemoji: " } )
edited_note = Pleroma.Object . normalize ( edit )
assert edited_note . data [ " emoji " ] [ " remoteemoji " ] == remote_emoji_uri
end
2022-07-23 19:56:36 +00:00
test " respects MRF " do
user = insert ( :user )
clear_config ( [ :mrf , :policies ] , [ Pleroma.Web.ActivityPub.MRF.KeywordPolicy ] )
clear_config ( [ :mrf_keyword , :replace ] , [ { " updated " , " mewmew " } ] )
{ :ok , activity } = CommonAPI . post ( user , %{ status : " foo1 " , spoiler_text : " updated 1 " } )
assert Object . normalize ( activity ) . data [ " summary " ] == " mewmew 1 "
{ :ok , updated } = CommonAPI . update ( user , activity , %{ status : " updated 2 " } )
updated_object = Object . normalize ( updated )
assert updated_object . data [ " content " ] == " mewmew 2 "
assert Map . get ( updated_object . data , " summary " , " " ) == " "
assert Map . has_key? ( updated_object . data , " updated " )
end
2022-05-31 18:29:12 +00:00
end
2018-05-23 15:25:24 +00:00
end