2019-09-26 06:38:45 +00:00
# Pleroma: A lightweight social networking server
2023-01-02 20:38:50 +00:00
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
2019-09-26 06:38:45 +00:00
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
2022-06-13 09:00:49 +00:00
use Pleroma.Web.ConnCase , async : false
2020-08-22 17:46:01 +00:00
use Oban.Testing , repo : Pleroma.Repo
2019-09-26 06:38:45 +00:00
alias Pleroma.Activity
2019-10-09 03:51:14 +00:00
alias Pleroma.Conversation.Participation
2022-10-14 16:32:13 +00:00
alias Pleroma.ModerationLog
2019-09-26 06:38:45 +00:00
alias Pleroma.Object
2019-09-27 06:35:45 +00:00
alias Pleroma.Repo
alias Pleroma.ScheduledActivity
2019-10-14 06:09:32 +00:00
alias Pleroma.Tests.ObanHelpers
2019-09-26 06:38:45 +00:00
alias Pleroma.User
2019-09-27 06:35:45 +00:00
alias Pleroma.Web.ActivityPub.ActivityPub
2021-05-31 18:39:15 +00:00
alias Pleroma.Web.ActivityPub.Utils
2019-09-26 06:38:45 +00:00
alias Pleroma.Web.CommonAPI
2021-07-18 01:35:35 +00:00
alias Pleroma.Workers.ScheduledActivityWorker
2019-09-26 06:38:45 +00:00
import Pleroma.Factory
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :instance , :federating ] )
setup do : clear_config ( [ :instance , :allow_relay ] )
setup do : clear_config ( [ :rich_media , :enabled ] )
2020-07-15 13:25:33 +00:00
setup do : clear_config ( [ :mrf , :policies ] )
setup do : clear_config ( [ :mrf_keyword , :reject ] )
2019-10-14 06:31:08 +00:00
2019-09-26 06:38:45 +00:00
describe " posting statuses " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " write:statuses " ] )
2019-09-26 06:38:45 +00:00
2019-10-19 23:23:13 +00:00
test " posting a status does not increment reblog_count when relaying " , %{ conn : conn } do
2021-01-26 17:58:43 +00:00
clear_config ( [ :instance , :federating ] , true )
2020-08-22 17:46:01 +00:00
Config . get ( [ :instance , :allow_relay ] , true )
2019-10-14 06:09:32 +00:00
response =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-10-14 06:09:32 +00:00
|> post ( " api/v1/statuses " , %{
" content_type " = > " text/plain " ,
" source " = > " Pleroma FE " ,
" status " = > " Hello world " ,
" visibility " = > " public "
} )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-10-14 06:09:32 +00:00
assert response [ " reblogs_count " ] == 0
ObanHelpers . perform_all ( )
response =
conn
|> get ( " api/v1/statuses/ #{ response [ " id " ] } " , %{ } )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-10-14 06:09:32 +00:00
assert response [ " reblogs_count " ] == 0
end
2019-09-26 06:38:45 +00:00
test " posting a status " , %{ conn : conn } do
idempotency_key = " Pikachu rocks! "
conn_one =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> put_req_header ( " idempotency-key " , idempotency_key )
|> post ( " /api/v1/statuses " , %{
" status " = > " cofe " ,
" spoiler_text " = > " 2hu " ,
2020-05-18 16:58:59 +00:00
" sensitive " = > " 0 "
2019-09-26 06:38:45 +00:00
} )
assert %{ " content " = > " cofe " , " id " = > id , " spoiler_text " = > " 2hu " , " sensitive " = > false } =
2020-05-12 19:59:26 +00:00
json_response_and_validate_schema ( conn_one , 200 )
2019-09-26 06:38:45 +00:00
assert Activity . get_by_id ( id )
conn_two =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> put_req_header ( " idempotency-key " , idempotency_key )
|> post ( " /api/v1/statuses " , %{
" status " = > " cofe " ,
" spoiler_text " = > " 2hu " ,
2020-05-18 16:58:59 +00:00
" sensitive " = > 0
2019-09-26 06:38:45 +00:00
} )
2021-02-16 23:45:01 +00:00
# Idempotency plug response means detection fail
2019-09-26 06:38:45 +00:00
assert %{ " id " = > second_id } = json_response ( conn_two , 200 )
assert id == second_id
conn_three =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> post ( " /api/v1/statuses " , %{
" status " = > " cofe " ,
" spoiler_text " = > " 2hu " ,
2020-05-18 16:58:59 +00:00
" sensitive " = > " False "
2019-09-26 06:38:45 +00:00
} )
2020-05-12 19:59:26 +00:00
assert %{ " id " = > third_id } = json_response_and_validate_schema ( conn_three , 200 )
2019-09-26 06:38:45 +00:00
refute id == third_id
# An activity that will expire:
# 2 hours
2020-08-22 17:46:01 +00:00
expires_in = 2 * 60 * 60
expires_at = DateTime . add ( DateTime . utc_now ( ) , expires_in )
2019-09-26 06:38:45 +00:00
conn_four =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> post ( " api/v1/statuses " , %{
" status " = > " oolong " ,
" expires_in " = > expires_in
} )
2020-09-04 08:40:32 +00:00
assert %{ " id " = > fourth_id } = json_response_and_validate_schema ( conn_four , 200 )
2020-05-12 19:59:26 +00:00
2020-08-22 17:46:01 +00:00
assert Activity . get_by_id ( fourth_id )
2019-09-26 06:38:45 +00:00
2020-08-22 17:46:01 +00:00
assert_enqueued (
worker : Pleroma.Workers.PurgeExpiredActivity ,
args : %{ activity_id : fourth_id } ,
scheduled_at : expires_at
)
2019-09-26 06:38:45 +00:00
end
2022-01-23 04:35:08 +00:00
test " posting a quote post " , %{ conn : conn } do
user = insert ( :user )
2022-01-23 19:55:25 +00:00
{ :ok , %{ id : activity_id } = activity } = CommonAPI . post ( user , %{ status : " yolo " } )
%{ data : %{ " id " = > quote_url } } = Object . normalize ( activity )
2022-01-23 04:35:08 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
" status " = > " indeed " ,
" quote_id " = > activity_id
} )
2022-01-23 19:55:25 +00:00
assert %{
" id " = > id ,
" pleroma " = > %{ " quote " = > %{ " id " = > ^ activity_id } , " quote_url " = > ^ quote_url }
} = json_response_and_validate_schema ( conn , 200 )
2022-01-23 04:35:08 +00:00
assert Activity . get_by_id ( id )
end
2020-02-12 15:43:07 +00:00
test " it fails to create a status if `expires_in` is less or equal than an hour " , %{
conn : conn
} do
2020-09-07 17:57:38 +00:00
# 1 minute
expires_in = 1 * 60
2020-02-12 15:43:07 +00:00
assert %{ " error " = > " Expiry date is too soon " } =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2020-02-12 15:43:07 +00:00
|> post ( " api/v1/statuses " , %{
" status " = > " oolong " ,
" expires_in " = > expires_in
} )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 422 )
2020-02-12 15:43:07 +00:00
2020-09-07 17:57:38 +00:00
# 5 minutes
expires_in = 5 * 60
2020-02-12 15:43:07 +00:00
assert %{ " error " = > " Expiry date is too soon " } =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2020-02-12 15:43:07 +00:00
|> post ( " api/v1/statuses " , %{
" status " = > " oolong " ,
" expires_in " = > expires_in
} )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 422 )
2020-02-12 15:43:07 +00:00
end
2020-07-15 13:25:33 +00:00
test " Get MRF reason when posting a status is rejected by one " , %{ conn : conn } do
2021-01-26 17:58:43 +00:00
clear_config ( [ :mrf_keyword , :reject ] , [ " GNO " ] )
clear_config ( [ :mrf , :policies ] , [ Pleroma.Web.ActivityPub.MRF.KeywordPolicy ] )
2020-07-15 13:25:33 +00:00
assert %{ " error " = > " [KeywordPolicy] Matches with rejected keyword " } =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " api/v1/statuses " , %{ " status " = > " GNO/Linux " } )
|> json_response_and_validate_schema ( 422 )
end
2019-12-15 19:32:42 +00:00
test " posting an undefined status with an attachment " , %{ user : user , conn : conn } do
2019-09-27 22:56:20 +00:00
file = % Plug.Upload {
2020-10-13 15:37:24 +00:00
content_type : " image/jpeg " ,
2019-09-27 22:56:20 +00:00
path : Path . absname ( " test/fixtures/image.jpg " ) ,
filename : " an_image.jpg "
}
{ :ok , upload } = ActivityPub . upload ( file , actor : user . ap_id )
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-27 23:21:28 +00:00
" media_ids " = > [ to_string ( upload . id ) ]
2019-09-27 22:56:20 +00:00
} )
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( conn , 200 )
2019-09-27 22:56:20 +00:00
end
2019-12-15 19:32:42 +00:00
test " replying to a status " , %{ user : user , conn : conn } do
2020-05-12 19:59:26 +00:00
{ :ok , replied_to } = CommonAPI . post ( user , %{ status : " cofe " } )
2019-09-26 06:38:45 +00:00
conn =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> post ( " /api/v1/statuses " , %{ " status " = > " xD " , " in_reply_to_id " = > replied_to . id } )
2020-05-12 19:59:26 +00:00
assert %{ " content " = > " xD " , " id " = > id } = json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
activity = Activity . get_by_id ( id )
assert activity . data [ " context " ] == replied_to . data [ " context " ]
assert Activity . get_in_reply_to_activity ( activity ) . id == replied_to . id
end
2019-12-15 19:32:42 +00:00
test " replying to a direct message with visibility other than direct " , %{
user : user ,
conn : conn
} do
2020-05-12 19:59:26 +00:00
{ :ok , replied_to } = CommonAPI . post ( user , %{ status : " suya.. " , visibility : " direct " } )
2019-09-26 06:38:45 +00:00
Enum . each ( [ " public " , " private " , " unlisted " ] , fn visibility ->
conn =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> post ( " /api/v1/statuses " , %{
" status " = > " @ #{ user . nickname } hey " ,
" in_reply_to_id " = > replied_to . id ,
" visibility " = > visibility
} )
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( conn , 422 ) == %{
" error " = > " The message visibility must be direct "
}
2019-09-26 06:38:45 +00:00
end )
end
test " posting a status with an invalid in_reply_to_id " , %{ conn : conn } do
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{ " status " = > " xD " , " in_reply_to_id " = > " " } )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert %{ " content " = > " xD " , " id " = > id } = json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
assert Activity . get_by_id ( id )
end
test " posting a sensitive status " , %{ conn : conn } do
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{ " status " = > " cofe " , " sensitive " = > true } )
assert %{ " content " = > " cofe " , " id " = > id , " sensitive " = > true } =
json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
assert Activity . get_by_id ( id )
end
test " posting a fake status " , %{ conn : conn } do
real_conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-26 06:38:45 +00:00
" status " = >
" \" Tenshi Eating a Corndog \" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it "
} )
2020-05-12 19:59:26 +00:00
real_status = json_response_and_validate_schema ( real_conn , 200 )
2019-09-26 06:38:45 +00:00
assert real_status
assert Object . get_by_ap_id ( real_status [ " uri " ] )
real_status =
real_status
|> Map . put ( " id " , nil )
|> Map . put ( " url " , nil )
|> Map . put ( " uri " , nil )
|> Map . put ( " created_at " , nil )
2022-08-07 18:39:35 +00:00
|> Kernel . put_in ( [ " pleroma " , " context " ] , nil )
2019-09-26 06:38:45 +00:00
|> Kernel . put_in ( [ " pleroma " , " conversation_id " ] , nil )
fake_conn =
2020-05-12 19:59:26 +00:00
conn
2021-01-22 20:37:49 +00:00
|> assign ( :user , refresh_record ( conn . assigns . user ) )
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-26 06:38:45 +00:00
" status " = >
" \" Tenshi Eating a Corndog \" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it " ,
" preview " = > true
} )
2020-05-12 19:59:26 +00:00
fake_status = json_response_and_validate_schema ( fake_conn , 200 )
2019-09-26 06:38:45 +00:00
assert fake_status
refute Object . get_by_ap_id ( fake_status [ " uri " ] )
fake_status =
fake_status
|> Map . put ( " id " , nil )
|> Map . put ( " url " , nil )
|> Map . put ( " uri " , nil )
|> Map . put ( " created_at " , nil )
2022-08-07 18:39:35 +00:00
|> Kernel . put_in ( [ " pleroma " , " context " ] , nil )
2019-09-26 06:38:45 +00:00
|> Kernel . put_in ( [ " pleroma " , " conversation_id " ] , nil )
assert real_status == fake_status
end
2020-09-05 09:37:27 +00:00
test " fake statuses' preview card is not cached " , %{ conn : conn } do
clear_config ( [ :rich_media , :enabled ] , true )
Tesla.Mock . mock ( fn
%{
method : :get ,
url : " https://example.com/twitter-card "
} ->
% Tesla.Env { status : 200 , body : File . read! ( " test/fixtures/rich_media/twitter_card.html " ) }
env ->
apply ( HttpRequestMock , :request , [ env ] )
end )
conn1 =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
" status " = > " https://example.com/ogp " ,
" preview " = > true
} )
conn2 =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
" status " = > " https://example.com/twitter-card " ,
" preview " = > true
} )
assert %{ " card " = > %{ " title " = > " The Rock " } } = json_response_and_validate_schema ( conn1 , 200 )
assert %{ " card " = > %{ " title " = > " Small Island Developing States Photo Submission " } } =
json_response_and_validate_schema ( conn2 , 200 )
end
2019-09-26 06:38:45 +00:00
test " posting a status with OGP link preview " , %{ conn : conn } do
2020-09-10 07:54:57 +00:00
Tesla.Mock . mock_global ( fn env -> apply ( HttpRequestMock , :request , [ env ] ) end )
2020-09-05 09:37:27 +00:00
clear_config ( [ :rich_media , :enabled ] , true )
2019-09-26 06:38:45 +00:00
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-26 06:38:45 +00:00
" status " = > " https://example.com/ogp "
} )
2020-05-12 19:59:26 +00:00
assert %{ " id " = > id , " card " = > %{ " title " = > " The Rock " } } =
json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
assert Activity . get_by_id ( id )
end
test " posting a direct status " , %{ conn : conn } do
user2 = insert ( :user )
content = " direct cofe @ #{ user2 . nickname } "
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " api/v1/statuses " , %{ " status " = > content , " visibility " = > " direct " } )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert %{ " id " = > id } = response = json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
assert response [ " visibility " ] == " direct "
assert response [ " pleroma " ] [ " direct_conversation_id " ]
assert activity = Activity . get_by_id ( id )
assert activity . recipients == [ user2 . ap_id , conn . assigns [ :user ] . ap_id ]
assert activity . data [ " to " ] == [ user2 . ap_id ]
assert activity . data [ " cc " ] == [ ]
end
2021-02-11 21:07:21 +00:00
2021-02-18 23:23:17 +00:00
test " discloses application metadata when enabled " do
user = insert ( :user , disclose_client : true )
%{ user : _user , token : token , conn : conn } = oauth_access ( [ " write:statuses " ] , user : user )
2021-02-11 21:53:10 +00:00
% Pleroma.Web.OAuth.Token {
app : % Pleroma.Web.OAuth.App {
2021-02-28 16:41:25 +00:00
client_name : app_name ,
website : app_website
2021-02-11 21:53:10 +00:00
}
} = token
2021-02-11 21:07:21 +00:00
result =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
" status " = > " cofe is my copilot "
} )
2021-03-02 18:29:16 +00:00
assert %{
" content " = > " cofe is my copilot "
} = json_response_and_validate_schema ( result , 200 )
activity = result . assigns . activity . id
result =
conn
|> get ( " api/v1/statuses/ #{ activity } " )
2021-02-11 21:07:21 +00:00
assert %{
" content " = > " cofe is my copilot " ,
" application " = > %{
2021-02-28 16:41:25 +00:00
" name " = > ^ app_name ,
" website " = > ^ app_website
2021-02-11 21:07:21 +00:00
}
} = json_response_and_validate_schema ( result , 200 )
end
2021-02-18 23:23:17 +00:00
test " hides application metadata when disabled " do
user = insert ( :user , disclose_client : false )
%{ user : _user , token : _token , conn : conn } = oauth_access ( [ " write:statuses " ] , user : user )
result =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
" status " = > " club mate is my wingman "
} )
2021-03-02 18:33:32 +00:00
assert %{ " content " = > " club mate is my wingman " } =
json_response_and_validate_schema ( result , 200 )
activity = result . assigns . activity . id
result =
conn
|> get ( " api/v1/statuses/ #{ activity } " )
2021-02-18 23:23:17 +00:00
assert %{
" content " = > " club mate is my wingman " ,
" application " = > nil
} = json_response_and_validate_schema ( result , 200 )
end
2019-09-26 06:38:45 +00:00
end
2019-09-27 06:35:45 +00:00
describe " posting scheduled statuses " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " write:statuses " ] )
2019-09-27 06:35:45 +00:00
test " creates a scheduled activity " , %{ conn : conn } do
2020-05-12 19:59:26 +00:00
scheduled_at =
NaiveDateTime . add ( NaiveDateTime . utc_now ( ) , :timer . minutes ( 120 ) , :millisecond )
|> NaiveDateTime . to_iso8601 ( )
|> Kernel . <> ( " Z " )
2019-09-27 06:35:45 +00:00
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-27 06:35:45 +00:00
" status " = > " scheduled " ,
" scheduled_at " = > scheduled_at
} )
2020-05-12 19:59:26 +00:00
assert %{ " scheduled_at " = > expected_scheduled_at } =
json_response_and_validate_schema ( conn , 200 )
2019-09-27 06:35:45 +00:00
assert expected_scheduled_at == CommonAPI.Utils . to_masto_date ( scheduled_at )
assert [ ] == Repo . all ( Activity )
end
2021-02-11 10:01:48 +00:00
test " with expiration " do
%{ conn : conn } = oauth_access ( [ " write:statuses " , " read:statuses " ] )
scheduled_at =
NaiveDateTime . add ( NaiveDateTime . utc_now ( ) , :timer . minutes ( 6 ) , :millisecond )
|> NaiveDateTime . to_iso8601 ( )
|> Kernel . <> ( " Z " )
assert %{ " id " = > status_id , " params " = > %{ " expires_in " = > 300 } } =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
" status " = > " scheduled " ,
" scheduled_at " = > scheduled_at ,
" expires_in " = > 300
} )
|> json_response_and_validate_schema ( 200 )
assert %{ " id " = > ^ status_id , " params " = > %{ " expires_in " = > 300 } } =
conn
|> put_req_header ( " content-type " , " application/json " )
|> get ( " /api/v1/scheduled_statuses/ #{ status_id } " )
|> json_response_and_validate_schema ( 200 )
end
2020-04-22 12:26:19 +00:00
test " ignores nil values " , %{ conn : conn } do
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2020-04-22 12:26:19 +00:00
" status " = > " not scheduled " ,
" scheduled_at " = > nil
} )
2020-05-12 19:59:26 +00:00
assert result = json_response_and_validate_schema ( conn , 200 )
2020-04-22 12:26:19 +00:00
assert Activity . get_by_id ( result [ " id " ] )
end
2019-12-15 19:32:42 +00:00
test " creates a scheduled activity with a media attachment " , %{ user : user , conn : conn } do
2020-05-12 19:59:26 +00:00
scheduled_at =
NaiveDateTime . utc_now ( )
|> NaiveDateTime . add ( :timer . minutes ( 120 ) , :millisecond )
|> NaiveDateTime . to_iso8601 ( )
|> Kernel . <> ( " Z " )
2019-09-27 06:35:45 +00:00
file = % Plug.Upload {
2020-10-13 15:37:24 +00:00
content_type : " image/jpeg " ,
2019-09-27 06:35:45 +00:00
path : Path . absname ( " test/fixtures/image.jpg " ) ,
filename : " an_image.jpg "
}
{ :ok , upload } = ActivityPub . upload ( file , actor : user . ap_id )
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-27 06:35:45 +00:00
" media_ids " = > [ to_string ( upload . id ) ] ,
" status " = > " scheduled " ,
" scheduled_at " = > scheduled_at
} )
2020-05-12 19:59:26 +00:00
assert %{ " media_attachments " = > [ media_attachment ] } =
json_response_and_validate_schema ( conn , 200 )
2019-09-27 06:35:45 +00:00
assert %{ " type " = > " image " } = media_attachment
end
test " skips the scheduling and creates the activity if scheduled_at is earlier than 5 minutes from now " ,
%{ conn : conn } do
scheduled_at =
NaiveDateTime . add ( NaiveDateTime . utc_now ( ) , :timer . minutes ( 5 ) - 1 , :millisecond )
2020-05-12 19:59:26 +00:00
|> NaiveDateTime . to_iso8601 ( )
|> Kernel . <> ( " Z " )
2019-09-27 06:35:45 +00:00
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-27 06:35:45 +00:00
" status " = > " not scheduled " ,
" scheduled_at " = > scheduled_at
} )
2020-05-12 19:59:26 +00:00
assert %{ " content " = > " not scheduled " } = json_response_and_validate_schema ( conn , 200 )
2019-09-27 06:35:45 +00:00
assert [ ] == Repo . all ( ScheduledActivity )
end
2019-12-15 19:32:42 +00:00
test " returns error when daily user limit is exceeded " , %{ user : user , conn : conn } do
2019-09-27 06:35:45 +00:00
today =
NaiveDateTime . utc_now ( )
|> NaiveDateTime . add ( :timer . minutes ( 6 ) , :millisecond )
|> NaiveDateTime . to_iso8601 ( )
2020-05-12 19:59:26 +00:00
# TODO
|> Kernel . <> ( " Z " )
2019-09-27 06:35:45 +00:00
attrs = %{ params : %{ } , scheduled_at : today }
{ :ok , _ } = ScheduledActivity . create ( user , attrs )
{ :ok , _ } = ScheduledActivity . create ( user , attrs )
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{ " status " = > " scheduled " , " scheduled_at " = > today } )
2019-09-27 06:35:45 +00:00
2020-05-12 19:59:26 +00:00
assert %{ " error " = > " daily limit exceeded " } == json_response_and_validate_schema ( conn , 422 )
2019-09-27 06:35:45 +00:00
end
2019-12-15 19:32:42 +00:00
test " returns error when total user limit is exceeded " , %{ user : user , conn : conn } do
2019-09-27 06:35:45 +00:00
today =
NaiveDateTime . utc_now ( )
|> NaiveDateTime . add ( :timer . minutes ( 6 ) , :millisecond )
|> NaiveDateTime . to_iso8601 ( )
2020-05-12 19:59:26 +00:00
|> Kernel . <> ( " Z " )
2019-09-27 06:35:45 +00:00
tomorrow =
NaiveDateTime . utc_now ( )
|> NaiveDateTime . add ( :timer . hours ( 36 ) , :millisecond )
|> NaiveDateTime . to_iso8601 ( )
2020-05-12 19:59:26 +00:00
|> Kernel . <> ( " Z " )
2019-09-27 06:35:45 +00:00
attrs = %{ params : %{ } , scheduled_at : today }
{ :ok , _ } = ScheduledActivity . create ( user , attrs )
{ :ok , _ } = ScheduledActivity . create ( user , attrs )
{ :ok , _ } = ScheduledActivity . create ( user , %{ params : %{ } , scheduled_at : tomorrow } )
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{ " status " = > " scheduled " , " scheduled_at " = > tomorrow } )
2019-09-27 06:35:45 +00:00
2020-05-12 19:59:26 +00:00
assert %{ " error " = > " total limit exceeded " } == json_response_and_validate_schema ( conn , 422 )
2019-09-27 06:35:45 +00:00
end
end
2019-09-26 06:38:45 +00:00
describe " posting polls " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " write:statuses " ] )
2019-09-26 06:38:45 +00:00
test " posting a poll " , %{ conn : conn } do
time = NaiveDateTime . utc_now ( )
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-26 06:38:45 +00:00
" status " = > " Who is the # bestgrill? " ,
2020-05-12 19:59:26 +00:00
" poll " = > %{
" options " = > [ " Rei " , " Asuka " , " Misato " ] ,
" expires_in " = > 420
}
2019-09-26 06:38:45 +00:00
} )
2020-05-12 19:59:26 +00:00
response = json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
assert Enum . all? ( response [ " poll " ] [ " options " ] , fn %{ " title " = > title } ->
title in [ " Rei " , " Asuka " , " Misato " ]
end )
assert NaiveDateTime . diff ( NaiveDateTime . from_iso8601! ( response [ " poll " ] [ " expires_at " ] ) , time ) in 420 . . 430
2021-02-01 15:22:26 +00:00
assert response [ " poll " ] [ " expired " ] == false
2020-02-07 15:57:46 +00:00
question = Object . get_by_id ( response [ " poll " ] [ " id " ] )
# closed contains utc timezone
assert question . data [ " closed " ] =~ " Z "
2019-09-26 06:38:45 +00:00
end
test " option limit is enforced " , %{ conn : conn } do
limit = Config . get ( [ :instance , :poll_limits , :max_options ] )
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-26 06:38:45 +00:00
" status " = > " desu~ " ,
2023-03-26 15:11:26 +00:00
" poll " = > %{
" options " = > Enum . map ( 0 . . limit , fn num -> " desu #{ num } " end ) ,
" expires_in " = > 1
}
2019-09-26 06:38:45 +00:00
} )
2020-05-12 19:59:26 +00:00
%{ " error " = > error } = json_response_and_validate_schema ( conn , 422 )
2019-09-26 06:38:45 +00:00
assert error == " Poll can't contain more than #{ limit } options "
end
test " option character limit is enforced " , %{ conn : conn } do
limit = Config . get ( [ :instance , :poll_limits , :max_option_chars ] )
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-26 06:38:45 +00:00
" status " = > " ... " ,
" poll " = > %{
2023-03-26 15:11:26 +00:00
" options " = > [ String . duplicate ( " . " , limit + 1 ) , " lol " ] ,
2019-09-26 06:38:45 +00:00
" expires_in " = > 1
}
} )
2020-05-12 19:59:26 +00:00
%{ " error " = > error } = json_response_and_validate_schema ( conn , 422 )
2019-09-26 06:38:45 +00:00
assert error == " Poll options cannot be longer than #{ limit } characters each "
end
test " minimal date limit is enforced " , %{ conn : conn } do
limit = Config . get ( [ :instance , :poll_limits , :min_expiration ] )
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-26 06:38:45 +00:00
" status " = > " imagine arbitrary limits " ,
" poll " = > %{
" options " = > [ " this post was made by pleroma gang " ] ,
" expires_in " = > limit - 1
}
} )
2020-05-12 19:59:26 +00:00
%{ " error " = > error } = json_response_and_validate_schema ( conn , 422 )
2019-09-26 06:38:45 +00:00
assert error == " Expiration date is too soon "
end
test " maximum date limit is enforced " , %{ conn : conn } do
limit = Config . get ( [ :instance , :poll_limits , :max_expiration ] )
conn =
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
2019-09-26 06:38:45 +00:00
" status " = > " imagine arbitrary limits " ,
" poll " = > %{
" options " = > [ " this post was made by pleroma gang " ] ,
" expires_in " = > limit + 1
}
} )
2020-05-12 19:59:26 +00:00
%{ " error " = > error } = json_response_and_validate_schema ( conn , 422 )
2019-09-26 06:38:45 +00:00
assert error == " Expiration date is too far in the future "
end
2021-02-01 15:22:26 +00:00
test " scheduled poll " , %{ conn : conn } do
clear_config ( [ ScheduledActivity , :enabled ] , true )
scheduled_at =
NaiveDateTime . add ( NaiveDateTime . utc_now ( ) , :timer . minutes ( 6 ) , :millisecond )
|> NaiveDateTime . to_iso8601 ( )
|> Kernel . <> ( " Z " )
%{ " id " = > scheduled_id } =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
" status " = > " very cool poll " ,
" poll " = > %{
" options " = > ~w( a b c ) ,
" expires_in " = > 420
} ,
" scheduled_at " = > scheduled_at
} )
|> json_response_and_validate_schema ( 200 )
assert { :ok , %{ id : activity_id } } =
2021-07-18 01:35:35 +00:00
perform_job ( ScheduledActivityWorker , %{
2021-02-01 15:22:26 +00:00
activity_id : scheduled_id
} )
2021-07-18 01:35:35 +00:00
refute_enqueued ( worker : ScheduledActivityWorker )
2021-02-01 15:22:26 +00:00
object =
Activity
|> Repo . get ( activity_id )
|> Object . normalize ( )
assert object . data [ " content " ] == " very cool poll "
assert object . data [ " type " ] == " Question "
assert length ( object . data [ " oneOf " ] ) == 3
end
2023-03-26 03:20:07 +00:00
test " cannot have only one option " , %{ conn : conn } do
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
" status " = > " desu~ " ,
" poll " = > %{ " options " = > [ " mew " ] , " expires_in " = > 1 }
} )
%{ " error " = > error } = json_response_and_validate_schema ( conn , 422 )
assert error == " Poll must contain at least 2 options "
end
test " cannot have only duplicated options " , %{ conn : conn } do
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
" status " = > " desu~ " ,
" poll " = > %{ " options " = > [ " mew " , " mew " ] , " expires_in " = > 1 }
} )
%{ " error " = > error } = json_response_and_validate_schema ( conn , 422 )
assert error == " Poll must contain at least 2 options "
end
2019-09-26 06:38:45 +00:00
end
2019-12-15 19:32:42 +00:00
test " get a status " do
%{ conn : conn } = oauth_access ( [ " read:statuses " ] )
2019-09-26 06:38:45 +00:00
activity = insert ( :note_activity )
2019-12-15 19:32:42 +00:00
conn = get ( conn , " /api/v1/statuses/ #{ activity . id } " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert %{ " id " = > id } = json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
assert id == to_string ( activity . id )
end
2020-03-20 10:04:37 +00:00
defp local_and_remote_activities do
local = insert ( :note_activity )
remote = insert ( :note_activity , local : false )
{ :ok , local : local , remote : remote }
end
2022-12-07 17:37:50 +00:00
defp local_and_remote_context_activities do
local_user_1 = insert ( :user )
local_user_2 = insert ( :user )
remote_user = insert ( :user , local : false )
{ :ok , %{ id : id1 , data : %{ " context " = > context } } } =
CommonAPI . post ( local_user_1 , %{ status : " post " } )
{ :ok , %{ id : id2 } = post } =
CommonAPI . post ( local_user_2 , %{ status : " local reply " , in_reply_to_status_id : id1 } )
params = %{
" @context " = > " https://www.w3.org/ns/activitystreams " ,
" actor " = > remote_user . ap_id ,
" type " = > " Create " ,
" context " = > context ,
" id " = > " #{ remote_user . ap_id } /activities/1 " ,
" inReplyTo " = > post . data [ " id " ] ,
" object " = > %{
" type " = > " Note " ,
" content " = > " remote reply " ,
" context " = > context ,
" id " = > " #{ remote_user . ap_id } /objects/1 " ,
" attributedTo " = > remote_user . ap_id ,
" to " = > [
local_user_1 . ap_id ,
local_user_2 . ap_id ,
" https://www.w3.org/ns/activitystreams # Public "
]
} ,
" to " = > [
local_user_1 . ap_id ,
local_user_2 . ap_id ,
" https://www.w3.org/ns/activitystreams # Public "
]
}
{ :ok , job } = Pleroma.Web.Federator . incoming_ap_doc ( params )
{ :ok , remote_activity } = ObanHelpers . perform ( job )
%{ locals : [ id1 , id2 ] , remote : remote_activity . id , context : context }
end
2020-03-20 10:04:37 +00:00
describe " status with restrict unauthenticated activities for local and remote " do
setup do : local_and_remote_activities ( )
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :local ] , true )
2020-03-20 10:04:37 +00:00
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :remote ] , true )
2020-03-20 10:04:37 +00:00
test " if user is unauthenticated " , %{ conn : conn , local : local , remote : remote } do
res_conn = get ( conn , " /api/v1/statuses/ #{ local . id } " )
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( res_conn , :not_found ) == %{
2020-03-20 10:04:37 +00:00
" error " = > " Record not found "
}
res_conn = get ( conn , " /api/v1/statuses/ #{ remote . id } " )
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( res_conn , :not_found ) == %{
2020-03-20 10:04:37 +00:00
" error " = > " Record not found "
}
end
test " if user is authenticated " , %{ local : local , remote : remote } do
%{ conn : conn } = oauth_access ( [ " read " ] )
res_conn = get ( conn , " /api/v1/statuses/ #{ local . id } " )
2020-05-12 19:59:26 +00:00
assert %{ " id " = > _ } = json_response_and_validate_schema ( res_conn , 200 )
2020-03-20 10:04:37 +00:00
res_conn = get ( conn , " /api/v1/statuses/ #{ remote . id } " )
2020-05-12 19:59:26 +00:00
assert %{ " id " = > _ } = json_response_and_validate_schema ( res_conn , 200 )
2020-03-20 10:04:37 +00:00
end
end
describe " status with restrict unauthenticated activities for local " do
setup do : local_and_remote_activities ( )
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :local ] , true )
2020-03-20 10:04:37 +00:00
test " if user is unauthenticated " , %{ conn : conn , local : local , remote : remote } do
res_conn = get ( conn , " /api/v1/statuses/ #{ local . id } " )
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( res_conn , :not_found ) == %{
2020-03-20 10:04:37 +00:00
" error " = > " Record not found "
}
res_conn = get ( conn , " /api/v1/statuses/ #{ remote . id } " )
2020-05-12 19:59:26 +00:00
assert %{ " id " = > _ } = json_response_and_validate_schema ( res_conn , 200 )
2020-03-20 10:04:37 +00:00
end
test " if user is authenticated " , %{ local : local , remote : remote } do
%{ conn : conn } = oauth_access ( [ " read " ] )
res_conn = get ( conn , " /api/v1/statuses/ #{ local . id } " )
2020-05-12 19:59:26 +00:00
assert %{ " id " = > _ } = json_response_and_validate_schema ( res_conn , 200 )
2020-03-20 10:04:37 +00:00
res_conn = get ( conn , " /api/v1/statuses/ #{ remote . id } " )
2020-05-12 19:59:26 +00:00
assert %{ " id " = > _ } = json_response_and_validate_schema ( res_conn , 200 )
2020-03-20 10:04:37 +00:00
end
end
describe " status with restrict unauthenticated activities for remote " do
setup do : local_and_remote_activities ( )
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :remote ] , true )
2020-03-20 10:04:37 +00:00
test " if user is unauthenticated " , %{ conn : conn , local : local , remote : remote } do
res_conn = get ( conn , " /api/v1/statuses/ #{ local . id } " )
2020-05-12 19:59:26 +00:00
assert %{ " id " = > _ } = json_response_and_validate_schema ( res_conn , 200 )
2020-03-20 10:04:37 +00:00
res_conn = get ( conn , " /api/v1/statuses/ #{ remote . id } " )
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( res_conn , :not_found ) == %{
2020-03-20 10:04:37 +00:00
" error " = > " Record not found "
}
end
test " if user is authenticated " , %{ local : local , remote : remote } do
%{ conn : conn } = oauth_access ( [ " read " ] )
res_conn = get ( conn , " /api/v1/statuses/ #{ local . id } " )
2020-05-12 19:59:26 +00:00
assert %{ " id " = > _ } = json_response_and_validate_schema ( res_conn , 200 )
2020-03-20 10:04:37 +00:00
res_conn = get ( conn , " /api/v1/statuses/ #{ remote . id } " )
2020-05-12 19:59:26 +00:00
assert %{ " id " = > _ } = json_response_and_validate_schema ( res_conn , 200 )
2020-03-20 10:04:37 +00:00
end
end
2020-03-04 17:09:06 +00:00
test " getting a status that doesn't exist returns 404 " do
%{ conn : conn } = oauth_access ( [ " read:statuses " ] )
activity = insert ( :note_activity )
conn = get ( conn , " /api/v1/statuses/ #{ String . downcase ( activity . id ) } " )
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( conn , 404 ) == %{ " error " = > " Record not found " }
2020-03-04 17:09:06 +00:00
end
2019-12-15 19:32:42 +00:00
test " get a direct status " do
%{ user : user , conn : conn } = oauth_access ( [ " read:statuses " ] )
2019-10-09 03:51:14 +00:00
other_user = insert ( :user )
{ :ok , activity } =
2020-05-12 19:59:26 +00:00
CommonAPI . post ( user , %{ status : " @ #{ other_user . nickname } " , visibility : " direct " } )
2019-10-09 03:51:14 +00:00
conn =
conn
|> assign ( :user , user )
|> get ( " /api/v1/statuses/ #{ activity . id } " )
[ participation ] = Participation . for_user ( user )
2020-05-12 19:59:26 +00:00
res = json_response_and_validate_schema ( conn , 200 )
2019-10-09 03:51:14 +00:00
assert res [ " pleroma " ] [ " direct_conversation_id " ] == participation . id
end
2019-12-15 19:32:42 +00:00
test " get statuses by IDs " do
%{ conn : conn } = oauth_access ( [ " read:statuses " ] )
2019-09-26 06:38:45 +00:00
%{ id : id1 } = insert ( :note_activity )
%{ id : id2 } = insert ( :note_activity )
query_string = " ids[]= #{ id1 } &ids[]= #{ id2 } "
conn = get ( conn , " /api/v1/statuses/? #{ query_string } " )
2020-05-12 19:59:26 +00:00
assert [ %{ " id " = > ^ id1 } , %{ " id " = > ^ id2 } ] =
Enum . sort_by ( json_response_and_validate_schema ( conn , :ok ) , & &1 [ " id " ] )
2019-09-26 06:38:45 +00:00
end
2020-03-20 10:04:37 +00:00
describe " getting statuses by ids with restricted unauthenticated for local and remote " do
setup do : local_and_remote_activities ( )
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :local ] , true )
2020-03-20 10:04:37 +00:00
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :remote ] , true )
2020-03-20 10:04:37 +00:00
test " if user is unauthenticated " , %{ conn : conn , local : local , remote : remote } do
2020-05-12 19:59:26 +00:00
res_conn = get ( conn , " /api/v1/statuses?ids[]= #{ local . id } &ids[]= #{ remote . id } " )
2020-03-20 10:04:37 +00:00
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( res_conn , 200 ) == [ ]
2020-03-20 10:04:37 +00:00
end
test " if user is authenticated " , %{ local : local , remote : remote } do
%{ conn : conn } = oauth_access ( [ " read " ] )
2020-05-12 19:59:26 +00:00
res_conn = get ( conn , " /api/v1/statuses?ids[]= #{ local . id } &ids[]= #{ remote . id } " )
2020-03-20 10:04:37 +00:00
2020-05-12 19:59:26 +00:00
assert length ( json_response_and_validate_schema ( res_conn , 200 ) ) == 2
2020-03-20 10:04:37 +00:00
end
end
describe " getting statuses by ids with restricted unauthenticated for local " do
setup do : local_and_remote_activities ( )
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :local ] , true )
2020-03-20 10:04:37 +00:00
test " if user is unauthenticated " , %{ conn : conn , local : local , remote : remote } do
2020-05-12 19:59:26 +00:00
res_conn = get ( conn , " /api/v1/statuses?ids[]= #{ local . id } &ids[]= #{ remote . id } " )
2020-03-20 10:04:37 +00:00
remote_id = remote . id
2020-05-12 19:59:26 +00:00
assert [ %{ " id " = > ^ remote_id } ] = json_response_and_validate_schema ( res_conn , 200 )
2020-03-20 10:04:37 +00:00
end
test " if user is authenticated " , %{ local : local , remote : remote } do
%{ conn : conn } = oauth_access ( [ " read " ] )
2020-05-12 19:59:26 +00:00
res_conn = get ( conn , " /api/v1/statuses?ids[]= #{ local . id } &ids[]= #{ remote . id } " )
2020-03-20 10:04:37 +00:00
2020-05-12 19:59:26 +00:00
assert length ( json_response_and_validate_schema ( res_conn , 200 ) ) == 2
2020-03-20 10:04:37 +00:00
end
end
describe " getting statuses by ids with restricted unauthenticated for remote " do
setup do : local_and_remote_activities ( )
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :remote ] , true )
2020-03-20 10:04:37 +00:00
test " if user is unauthenticated " , %{ conn : conn , local : local , remote : remote } do
2020-05-12 19:59:26 +00:00
res_conn = get ( conn , " /api/v1/statuses?ids[]= #{ local . id } &ids[]= #{ remote . id } " )
2020-03-20 10:04:37 +00:00
local_id = local . id
2020-05-12 19:59:26 +00:00
assert [ %{ " id " = > ^ local_id } ] = json_response_and_validate_schema ( res_conn , 200 )
2020-03-20 10:04:37 +00:00
end
test " if user is authenticated " , %{ local : local , remote : remote } do
%{ conn : conn } = oauth_access ( [ " read " ] )
2020-05-12 19:59:26 +00:00
res_conn = get ( conn , " /api/v1/statuses?ids[]= #{ local . id } &ids[]= #{ remote . id } " )
2020-03-20 10:04:37 +00:00
2020-05-12 19:59:26 +00:00
assert length ( json_response_and_validate_schema ( res_conn , 200 ) ) == 2
2020-03-20 10:04:37 +00:00
end
end
2022-12-07 17:37:50 +00:00
describe " getting status contexts restricted unauthenticated for local and remote " do
setup do : local_and_remote_context_activities ( )
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :local ] , true )
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :remote ] , true )
test " if user is unauthenticated " , %{ conn : conn , locals : [ post_id , _ ] } do
res_conn = get ( conn , " /api/v1/statuses/ #{ post_id } /context " )
assert json_response_and_validate_schema ( res_conn , 200 ) == %{
" ancestors " = > [ ] ,
" descendants " = > [ ]
}
end
test " if user is unauthenticated reply " , %{ conn : conn , locals : [ _ , reply_id ] } do
res_conn = get ( conn , " /api/v1/statuses/ #{ reply_id } /context " )
assert json_response_and_validate_schema ( res_conn , 200 ) == %{
" ancestors " = > [ ] ,
" descendants " = > [ ]
}
end
test " if user is authenticated " , %{ locals : [ post_id , reply_id ] , remote : remote_reply_id } do
%{ conn : conn } = oauth_access ( [ " read " ] )
res_conn = get ( conn , " /api/v1/statuses/ #{ post_id } /context " )
%{ " ancestors " = > [ ] , " descendants " = > descendants } =
json_response_and_validate_schema ( res_conn , 200 )
descendant_ids =
descendants
|> Enum . map ( & &1 [ " id " ] )
assert reply_id in descendant_ids
assert remote_reply_id in descendant_ids
end
test " if user is authenticated reply " , %{ locals : [ post_id , reply_id ] , remote : remote_reply_id } do
%{ conn : conn } = oauth_access ( [ " read " ] )
res_conn = get ( conn , " /api/v1/statuses/ #{ reply_id } /context " )
%{ " ancestors " = > ancestors , " descendants " = > descendants } =
json_response_and_validate_schema ( res_conn , 200 )
ancestor_ids =
ancestors
|> Enum . map ( & &1 [ " id " ] )
descendant_ids =
descendants
|> Enum . map ( & &1 [ " id " ] )
assert post_id in ancestor_ids
assert remote_reply_id in descendant_ids
end
end
describe " getting status contexts restricted unauthenticated for local " do
setup do : local_and_remote_context_activities ( )
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :local ] , true )
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :remote ] , false )
test " if user is unauthenticated " , %{
conn : conn ,
locals : [ post_id , reply_id ] ,
remote : remote_reply_id
} do
res_conn = get ( conn , " /api/v1/statuses/ #{ post_id } /context " )
%{ " ancestors " = > [ ] , " descendants " = > descendants } =
json_response_and_validate_schema ( res_conn , 200 )
descendant_ids =
descendants
|> Enum . map ( & &1 [ " id " ] )
assert reply_id not in descendant_ids
assert remote_reply_id in descendant_ids
end
test " if user is unauthenticated reply " , %{
conn : conn ,
locals : [ post_id , reply_id ] ,
remote : remote_reply_id
} do
res_conn = get ( conn , " /api/v1/statuses/ #{ reply_id } /context " )
%{ " ancestors " = > ancestors , " descendants " = > descendants } =
json_response_and_validate_schema ( res_conn , 200 )
ancestor_ids =
ancestors
|> Enum . map ( & &1 [ " id " ] )
descendant_ids =
descendants
|> Enum . map ( & &1 [ " id " ] )
assert post_id not in ancestor_ids
assert remote_reply_id in descendant_ids
end
test " if user is authenticated " , %{ locals : [ post_id , reply_id ] , remote : remote_reply_id } do
%{ conn : conn } = oauth_access ( [ " read " ] )
res_conn = get ( conn , " /api/v1/statuses/ #{ post_id } /context " )
%{ " ancestors " = > [ ] , " descendants " = > descendants } =
json_response_and_validate_schema ( res_conn , 200 )
descendant_ids =
descendants
|> Enum . map ( & &1 [ " id " ] )
assert reply_id in descendant_ids
assert remote_reply_id in descendant_ids
end
test " if user is authenticated reply " , %{ locals : [ post_id , reply_id ] , remote : remote_reply_id } do
%{ conn : conn } = oauth_access ( [ " read " ] )
res_conn = get ( conn , " /api/v1/statuses/ #{ reply_id } /context " )
%{ " ancestors " = > ancestors , " descendants " = > descendants } =
json_response_and_validate_schema ( res_conn , 200 )
ancestor_ids =
ancestors
|> Enum . map ( & &1 [ " id " ] )
descendant_ids =
descendants
|> Enum . map ( & &1 [ " id " ] )
assert post_id in ancestor_ids
assert remote_reply_id in descendant_ids
end
end
describe " getting status contexts restricted unauthenticated for remote " do
setup do : local_and_remote_context_activities ( )
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :local ] , false )
setup do : clear_config ( [ :restrict_unauthenticated , :activities , :remote ] , true )
test " if user is unauthenticated " , %{
conn : conn ,
locals : [ post_id , reply_id ] ,
remote : remote_reply_id
} do
res_conn = get ( conn , " /api/v1/statuses/ #{ post_id } /context " )
%{ " ancestors " = > [ ] , " descendants " = > descendants } =
json_response_and_validate_schema ( res_conn , 200 )
descendant_ids =
descendants
|> Enum . map ( & &1 [ " id " ] )
assert reply_id in descendant_ids
assert remote_reply_id not in descendant_ids
end
test " if user is unauthenticated reply " , %{
conn : conn ,
locals : [ post_id , reply_id ] ,
remote : remote_reply_id
} do
res_conn = get ( conn , " /api/v1/statuses/ #{ reply_id } /context " )
%{ " ancestors " = > ancestors , " descendants " = > descendants } =
json_response_and_validate_schema ( res_conn , 200 )
ancestor_ids =
ancestors
|> Enum . map ( & &1 [ " id " ] )
descendant_ids =
descendants
|> Enum . map ( & &1 [ " id " ] )
assert post_id in ancestor_ids
assert remote_reply_id not in descendant_ids
end
test " if user is authenticated " , %{ locals : [ post_id , reply_id ] , remote : remote_reply_id } do
%{ conn : conn } = oauth_access ( [ " read " ] )
res_conn = get ( conn , " /api/v1/statuses/ #{ post_id } /context " )
%{ " ancestors " = > [ ] , " descendants " = > descendants } =
json_response_and_validate_schema ( res_conn , 200 )
reply_ids =
descendants
|> Enum . map ( & &1 [ " id " ] )
assert reply_id in reply_ids
assert remote_reply_id in reply_ids
end
test " if user is authenticated reply " , %{ locals : [ post_id , reply_id ] , remote : remote_reply_id } do
%{ conn : conn } = oauth_access ( [ " read " ] )
res_conn = get ( conn , " /api/v1/statuses/ #{ reply_id } /context " )
%{ " ancestors " = > ancestors , " descendants " = > descendants } =
json_response_and_validate_schema ( res_conn , 200 )
ancestor_ids =
ancestors
|> Enum . map ( & &1 [ " id " ] )
descendant_ids =
descendants
|> Enum . map ( & &1 [ " id " ] )
assert post_id in ancestor_ids
assert remote_reply_id in descendant_ids
end
end
2019-09-26 06:38:45 +00:00
describe " deleting a status " do
2019-12-15 19:32:42 +00:00
test " when you created it " do
%{ user : author , conn : conn } = oauth_access ( [ " write:statuses " ] )
activity = insert ( :note_activity , user : author )
2021-01-04 12:38:31 +00:00
object = Object . normalize ( activity , fetch : false )
2019-09-26 06:38:45 +00:00
2020-06-26 05:16:24 +00:00
content = object . data [ " content " ]
source = object . data [ " source " ]
result =
2019-09-26 06:38:45 +00:00
conn
|> assign ( :user , author )
|> delete ( " /api/v1/statuses/ #{ activity . id } " )
2020-06-26 05:16:24 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
2020-06-26 05:16:24 +00:00
assert match? ( %{ " content " = > ^ content , " text " = > ^ source } , result )
2019-09-26 06:38:45 +00:00
refute Activity . get_by_id ( activity . id )
end
2020-03-04 17:09:06 +00:00
test " when it doesn't exist " do
%{ user : author , conn : conn } = oauth_access ( [ " write:statuses " ] )
activity = insert ( :note_activity , user : author )
conn =
conn
|> assign ( :user , author )
|> delete ( " /api/v1/statuses/ #{ String . downcase ( activity . id ) } " )
2020-05-12 19:59:26 +00:00
assert %{ " error " = > " Record not found " } == json_response_and_validate_schema ( conn , 404 )
2020-03-04 17:09:06 +00:00
end
2019-12-15 19:32:42 +00:00
test " when you didn't create it " do
%{ conn : conn } = oauth_access ( [ " write:statuses " ] )
2019-09-26 06:38:45 +00:00
activity = insert ( :note_activity )
2019-12-15 19:32:42 +00:00
conn = delete ( conn , " /api/v1/statuses/ #{ activity . id } " )
2019-09-26 06:38:45 +00:00
2020-06-26 05:16:24 +00:00
assert %{ " error " = > " Record not found " } == json_response_and_validate_schema ( conn , 404 )
2019-09-26 06:38:45 +00:00
assert Activity . get_by_id ( activity . id ) == activity
end
2022-06-13 09:00:49 +00:00
test " when you're privileged to " , %{ conn : conn } do
2022-07-01 07:54:05 +00:00
clear_config ( [ :instance , :moderator_privileges ] , [ :messages_delete ] )
2022-06-13 09:00:49 +00:00
activity = insert ( :note_activity )
2022-10-14 16:32:13 +00:00
user = insert ( :user , is_moderator : true )
2023-05-25 22:40:38 +00:00
res_conn =
conn
|> assign ( :user , user )
|> assign ( :token , insert ( :oauth_token , user : user , scopes : [ " write:statuses " ] ) )
|> delete ( " /api/v1/statuses/ #{ activity . id } " )
assert %{ } = json_response_and_validate_schema ( res_conn , 200 )
assert ModerationLog |> Repo . one ( ) |> ModerationLog . get_log_entry_message ( ) ==
" @ #{ user . nickname } deleted status # #{ activity . id } "
refute Activity . get_by_id ( activity . id )
end
test " when you're privileged and the user is banned " , %{ conn : conn } do
clear_config ( [ :instance , :moderator_privileges ] , [ :messages_delete ] )
posting_user = insert ( :user , is_active : false )
refute posting_user . is_active
activity = insert ( :note_activity , user : posting_user )
user = insert ( :user , is_moderator : true )
2019-09-26 06:38:45 +00:00
res_conn =
conn
2022-10-14 16:32:13 +00:00
|> assign ( :user , user )
|> assign ( :token , insert ( :oauth_token , user : user , scopes : [ " write:statuses " ] ) )
2022-06-13 09:00:49 +00:00
|> delete ( " /api/v1/statuses/ #{ activity . id } " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert %{ } = json_response_and_validate_schema ( res_conn , 200 )
2019-09-26 06:38:45 +00:00
2022-10-14 16:32:13 +00:00
assert ModerationLog |> Repo . one ( ) |> ModerationLog . get_log_entry_message ( ) ==
" @ #{ user . nickname } deleted status # #{ activity . id } "
2022-06-13 09:00:49 +00:00
refute Activity . get_by_id ( activity . id )
2019-09-26 06:38:45 +00:00
end
end
describe " reblogging " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " write:statuses " ] )
2019-09-26 06:38:45 +00:00
test " reblogs and returns the reblogged status " , %{ conn : conn } do
activity = insert ( :note_activity )
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity . id } /reblog " )
2019-09-26 06:38:45 +00:00
assert %{
" reblog " = > %{ " id " = > id , " reblogged " = > true , " reblogs_count " = > 1 } ,
" reblogged " = > true
2020-05-12 19:59:26 +00:00
} = json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
assert to_string ( activity . id ) == id
end
2020-03-04 17:09:06 +00:00
test " returns 404 if the reblogged status doesn't exist " , %{ conn : conn } do
activity = insert ( :note_activity )
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ String . downcase ( activity . id ) } /reblog " )
2020-03-04 17:09:06 +00:00
2020-05-12 19:59:26 +00:00
assert %{ " error " = > " Record not found " } = json_response_and_validate_schema ( conn , 404 )
2020-03-04 17:09:06 +00:00
end
2019-10-01 17:08:25 +00:00
test " reblogs privately and returns the reblogged status " , %{ conn : conn } do
activity = insert ( :note_activity )
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post (
" /api/v1/statuses/ #{ activity . id } /reblog " ,
%{ " visibility " = > " private " }
)
2019-10-01 17:08:25 +00:00
assert %{
2019-10-01 19:40:35 +00:00
" reblog " = > %{ " id " = > id , " reblogged " = > true , " reblogs_count " = > 1 } ,
2019-10-01 17:08:25 +00:00
" reblogged " = > true ,
" visibility " = > " private "
2020-05-12 19:59:26 +00:00
} = json_response_and_validate_schema ( conn , 200 )
2019-10-01 17:08:25 +00:00
assert to_string ( activity . id ) == id
end
2019-12-15 19:32:42 +00:00
test " reblogged status for another user " do
2019-09-26 06:38:45 +00:00
activity = insert ( :note_activity )
user1 = insert ( :user )
user2 = insert ( :user )
user3 = insert ( :user )
2019-10-16 14:16:39 +00:00
{ :ok , _ } = CommonAPI . favorite ( user2 , activity . id )
2019-09-26 06:38:45 +00:00
{ :ok , _bookmark } = Pleroma.Bookmark . create ( user2 . id , activity . id )
2020-05-21 11:16:21 +00:00
{ :ok , reblog_activity1 } = CommonAPI . repeat ( activity . id , user1 )
{ :ok , _ } = CommonAPI . repeat ( activity . id , user2 )
2019-09-26 06:38:45 +00:00
conn_res =
2019-12-15 19:32:42 +00:00
build_conn ( )
2019-09-26 06:38:45 +00:00
|> assign ( :user , user3 )
2019-12-15 19:32:42 +00:00
|> assign ( :token , insert ( :oauth_token , user : user3 , scopes : [ " read:statuses " ] ) )
2019-09-26 06:38:45 +00:00
|> get ( " /api/v1/statuses/ #{ reblog_activity1 . id } " )
assert %{
2020-10-15 12:54:59 +00:00
" reblog " = > %{ " id " = > _id , " reblogged " = > false , " reblogs_count " = > 2 } ,
2019-09-26 06:38:45 +00:00
" reblogged " = > false ,
" favourited " = > false ,
" bookmarked " = > false
2020-05-12 19:59:26 +00:00
} = json_response_and_validate_schema ( conn_res , 200 )
2019-09-26 06:38:45 +00:00
conn_res =
2019-12-15 19:32:42 +00:00
build_conn ( )
2019-09-26 06:38:45 +00:00
|> assign ( :user , user2 )
2019-12-15 19:32:42 +00:00
|> assign ( :token , insert ( :oauth_token , user : user2 , scopes : [ " read:statuses " ] ) )
2019-09-26 06:38:45 +00:00
|> get ( " /api/v1/statuses/ #{ reblog_activity1 . id } " )
assert %{
" reblog " = > %{ " id " = > id , " reblogged " = > true , " reblogs_count " = > 2 } ,
" reblogged " = > true ,
" favourited " = > true ,
" bookmarked " = > true
2020-05-12 19:59:26 +00:00
} = json_response_and_validate_schema ( conn_res , 200 )
2019-09-26 06:38:45 +00:00
assert to_string ( activity . id ) == id
end
2021-01-18 16:15:57 +00:00
test " author can reblog own private status " , %{ conn : conn , user : user } do
{ :ok , activity } = CommonAPI . post ( user , %{ status : " cofe " , visibility : " private " } )
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity . id } /reblog " )
assert %{
" reblog " = > %{ " id " = > id , " reblogged " = > true , " reblogs_count " = > 1 } ,
" reblogged " = > true ,
" visibility " = > " private "
} = json_response_and_validate_schema ( conn , 200 )
assert to_string ( activity . id ) == id
end
2019-09-26 06:38:45 +00:00
end
describe " unreblogging " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " write:statuses " ] )
test " unreblogs and returns the unreblogged status " , %{ user : user , conn : conn } do
2019-09-26 06:38:45 +00:00
activity = insert ( :note_activity )
2020-05-21 11:16:21 +00:00
{ :ok , _ } = CommonAPI . repeat ( activity . id , user )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity . id } /unreblog " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert %{ " id " = > id , " reblogged " = > false , " reblogs_count " = > 0 } =
json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
assert to_string ( activity . id ) == id
end
2020-03-04 17:09:06 +00:00
test " returns 404 error when activity does not exist " , %{ conn : conn } do
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/foo/unreblog " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( conn , 404 ) == %{ " error " = > " Record not found " }
2019-09-26 06:38:45 +00:00
end
end
describe " favoriting " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " write:favourites " ] )
2019-09-26 06:38:45 +00:00
test " favs a status and returns it " , %{ conn : conn } do
activity = insert ( :note_activity )
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity . id } /favourite " )
2019-09-26 06:38:45 +00:00
assert %{ " id " = > id , " favourites_count " = > 1 , " favourited " = > true } =
2020-05-12 19:59:26 +00:00
json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
assert to_string ( activity . id ) == id
end
2020-01-20 13:27:59 +00:00
test " favoriting twice will just return 200 " , %{ conn : conn } do
activity = insert ( :note_activity )
2020-05-12 19:59:26 +00:00
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity . id } /favourite " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity . id } /favourite " )
|> json_response_and_validate_schema ( 200 )
2020-01-20 13:27:59 +00:00
end
2020-03-04 17:09:06 +00:00
test " returns 404 error for a wrong id " , %{ conn : conn } do
2020-03-19 17:00:55 +00:00
conn =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2020-03-19 17:00:55 +00:00
|> post ( " /api/v1/statuses/1/favourite " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( conn , 404 ) == %{ " error " = > " Record not found " }
2019-09-26 06:38:45 +00:00
end
end
describe " unfavoriting " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " write:favourites " ] )
test " unfavorites a status and returns it " , %{ user : user , conn : conn } do
2019-09-26 06:38:45 +00:00
activity = insert ( :note_activity )
2019-10-16 14:16:39 +00:00
{ :ok , _ } = CommonAPI . favorite ( user , activity . id )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity . id } /unfavourite " )
2019-09-26 06:38:45 +00:00
assert %{ " id " = > id , " favourites_count " = > 0 , " favourited " = > false } =
2020-05-12 19:59:26 +00:00
json_response_and_validate_schema ( conn , 200 )
2019-09-26 06:38:45 +00:00
assert to_string ( activity . id ) == id
end
2020-03-04 17:09:06 +00:00
test " returns 404 error for a wrong id " , %{ conn : conn } do
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/1/unfavourite " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( conn , 404 ) == %{ " error " = > " Record not found " }
2019-09-26 06:38:45 +00:00
end
end
describe " pinned statuses " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " write:accounts " ] )
setup %{ user : user } do
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " HI!!! " } )
2019-09-26 06:38:45 +00:00
2019-12-15 19:32:42 +00:00
%{ activity : activity }
2019-09-26 06:38:45 +00:00
end
2020-03-20 15:33:00 +00:00
setup do : clear_config ( [ :instance , :max_pinned_statuses ] , 1 )
2019-09-26 06:38:45 +00:00
test " pin status " , %{ conn : conn , user : user , activity : activity } do
2021-03-02 14:24:06 +00:00
id = activity . id
2019-09-26 06:38:45 +00:00
2021-03-02 14:24:06 +00:00
assert %{ " id " = > ^ id , " pinned " = > true } =
2019-09-26 06:38:45 +00:00
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> post ( " /api/v1/statuses/ #{ activity . id } /pin " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
2021-03-02 14:24:06 +00:00
assert [ %{ " id " = > ^ id , " pinned " = > true } ] =
2019-09-26 06:38:45 +00:00
conn
|> get ( " /api/v1/accounts/ #{ user . id } /statuses?pinned=true " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
end
2021-02-03 13:09:28 +00:00
test " non authenticated user " , %{ activity : activity } do
assert build_conn ( )
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity . id } /pin " )
|> json_response ( 403 ) == %{ " error " = > " Invalid credentials. " }
end
2019-09-26 06:38:45 +00:00
test " /pin: returns 400 error when activity is not public " , %{ conn : conn , user : user } do
2020-05-12 19:59:26 +00:00
{ :ok , dm } = CommonAPI . post ( user , %{ status : " test " , visibility : " direct " } )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ dm . id } /pin " )
2019-09-26 06:38:45 +00:00
2021-02-03 13:09:28 +00:00
assert json_response_and_validate_schema ( conn , 422 ) == %{
" error " = > " Non-public status cannot be pinned "
}
end
test " pin by another user " , %{ activity : activity } do
%{ conn : conn } = oauth_access ( [ " write:accounts " ] )
assert conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity . id } /pin " )
|> json_response ( 422 ) == %{ " error " = > " Someone else's status cannot be pinned " }
2019-09-26 06:38:45 +00:00
end
test " unpin status " , %{ conn : conn , user : user , activity : activity } do
{ :ok , _ } = CommonAPI . pin ( activity . id , user )
2019-12-15 19:32:42 +00:00
user = refresh_record ( user )
2019-09-26 06:38:45 +00:00
id_str = to_string ( activity . id )
assert %{ " id " = > ^ id_str , " pinned " = > false } =
conn
|> assign ( :user , user )
|> post ( " /api/v1/statuses/ #{ activity . id } /unpin " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
assert [ ] =
conn
|> get ( " /api/v1/accounts/ #{ user . id } /statuses?pinned=true " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
end
2021-02-03 13:09:28 +00:00
test " /unpin: returns 404 error when activity doesn't exist " , %{ conn : conn } do
assert conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/1/unpin " )
|> json_response_and_validate_schema ( 404 ) == %{ " error " = > " Record not found " }
2019-09-26 06:38:45 +00:00
end
test " max pinned statuses " , %{ conn : conn , user : user , activity : activity_one } do
2020-05-12 19:59:26 +00:00
{ :ok , activity_two } = CommonAPI . post ( user , %{ status : " HI!!! " } )
2019-09-26 06:38:45 +00:00
id_str_one = to_string ( activity_one . id )
assert %{ " id " = > ^ id_str_one , " pinned " = > true } =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> post ( " /api/v1/statuses/ #{ id_str_one } /pin " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
user = refresh_record ( user )
assert %{ " error " = > " You have already pinned the maximum number of statuses " } =
conn
|> assign ( :user , user )
|> post ( " /api/v1/statuses/ #{ activity_two . id } /pin " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 400 )
2019-09-26 06:38:45 +00:00
end
2020-09-04 08:40:32 +00:00
test " on pin removes deletion job, on unpin reschedule deletion " do
%{ conn : conn } = oauth_access ( [ " write:accounts " , " write:statuses " ] )
expires_in = 2 * 60 * 60
expires_at = DateTime . add ( DateTime . utc_now ( ) , expires_in )
assert %{ " id " = > id } =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " api/v1/statuses " , %{
" status " = > " oolong " ,
" expires_in " = > expires_in
} )
|> json_response_and_validate_schema ( 200 )
assert_enqueued (
worker : Pleroma.Workers.PurgeExpiredActivity ,
args : %{ activity_id : id } ,
scheduled_at : expires_at
)
assert %{ " id " = > ^ id , " pinned " = > true } =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ id } /pin " )
|> json_response_and_validate_schema ( 200 )
refute_enqueued (
worker : Pleroma.Workers.PurgeExpiredActivity ,
args : %{ activity_id : id } ,
scheduled_at : expires_at
)
assert %{ " id " = > ^ id , " pinned " = > false } =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ id } /unpin " )
|> json_response_and_validate_schema ( 200 )
assert_enqueued (
worker : Pleroma.Workers.PurgeExpiredActivity ,
args : %{ activity_id : id } ,
scheduled_at : expires_at
)
end
2019-09-26 06:38:45 +00:00
end
describe " cards " do
setup do
2021-01-26 17:58:43 +00:00
clear_config ( [ :rich_media , :enabled ] , true )
2019-09-26 06:38:45 +00:00
2019-12-15 19:32:42 +00:00
oauth_access ( [ " read:statuses " ] )
2019-09-26 06:38:45 +00:00
end
test " returns rich-media card " , %{ conn : conn , user : user } do
2020-09-10 07:54:57 +00:00
Tesla.Mock . mock_global ( fn env -> apply ( HttpRequestMock , :request , [ env ] ) end )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " https://example.com/ogp " } )
2019-09-26 06:38:45 +00:00
card_data = %{
" image " = > " http://ia.media-imdb.com/images/rock.jpg " ,
" provider_name " = > " example.com " ,
" provider_url " = > " https://example.com " ,
" title " = > " The Rock " ,
" type " = > " link " ,
" url " = > " https://example.com/ogp " ,
" description " = >
" Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer. " ,
" pleroma " = > %{
" opengraph " = > %{
" image " = > " http://ia.media-imdb.com/images/rock.jpg " ,
" title " = > " The Rock " ,
" type " = > " video.movie " ,
" url " = > " https://example.com/ogp " ,
" description " = >
" Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer. "
}
}
}
response =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } /card " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
assert response == card_data
# works with private posts
{ :ok , activity } =
2020-05-12 19:59:26 +00:00
CommonAPI . post ( user , %{ status : " https://example.com/ogp " , visibility : " direct " } )
2019-09-26 06:38:45 +00:00
response_two =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } /card " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
assert response_two == card_data
end
test " replaces missing description with an empty string " , %{ conn : conn , user : user } do
2020-09-10 07:54:57 +00:00
Tesla.Mock . mock_global ( fn env -> apply ( HttpRequestMock , :request , [ env ] ) end )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " https://example.com/ogp-missing-data " } )
2019-09-26 06:38:45 +00:00
response =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } /card " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-09-26 06:38:45 +00:00
assert response == %{
" type " = > " link " ,
" title " = > " Pleroma " ,
" description " = > " " ,
" image " = > nil ,
" provider_name " = > " example.com " ,
" provider_url " = > " https://example.com " ,
" url " = > " https://example.com/ogp-missing-data " ,
" pleroma " = > %{
" opengraph " = > %{
" title " = > " Pleroma " ,
" type " = > " website " ,
" url " = > " https://example.com/ogp-missing-data "
}
}
}
end
end
test " bookmarks " do
2020-05-01 15:45:24 +00:00
bookmarks_uri = " /api/v1/bookmarks "
2020-04-01 16:49:09 +00:00
2019-12-15 19:32:42 +00:00
%{ conn : conn } = oauth_access ( [ " write:bookmarks " , " read:bookmarks " ] )
author = insert ( :user )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
{ :ok , activity1 } = CommonAPI . post ( author , %{ status : " heweoo? " } )
{ :ok , activity2 } = CommonAPI . post ( author , %{ status : " heweoo! " } )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
response1 =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity1 . id } /bookmark " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( response1 , 200 ) [ " bookmarked " ] == true
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
response2 =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity2 . id } /bookmark " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( response2 , 200 ) [ " bookmarked " ] == true
2019-09-26 06:38:45 +00:00
2020-04-01 16:49:09 +00:00
bookmarks = get ( conn , bookmarks_uri )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert [
json_response_and_validate_schema ( response2 , 200 ) ,
json_response_and_validate_schema ( response1 , 200 )
] ==
json_response_and_validate_schema ( bookmarks , 200 )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
response1 =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity1 . id } /unbookmark " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( response1 , 200 ) [ " bookmarked " ] == false
2019-09-26 06:38:45 +00:00
2020-04-01 16:49:09 +00:00
bookmarks = get ( conn , bookmarks_uri )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert [ json_response_and_validate_schema ( response2 , 200 ) ] ==
json_response_and_validate_schema ( bookmarks , 200 )
2019-09-26 06:38:45 +00:00
end
describe " conversation muting " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " write:mutes " ] )
2019-09-26 06:38:45 +00:00
setup do
post_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( post_user , %{ status : " HIE " } )
2019-12-15 19:32:42 +00:00
%{ activity : activity }
2019-09-26 06:38:45 +00:00
end
2019-12-15 19:32:42 +00:00
test " mute conversation " , %{ conn : conn , activity : activity } do
2019-09-26 06:38:45 +00:00
id_str = to_string ( activity . id )
assert %{ " id " = > ^ id_str , " muted " = > true } =
conn
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> post ( " /api/v1/statuses/ #{ activity . id } /mute " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
end
test " cannot mute already muted conversation " , %{ conn : conn , user : user , activity : activity } do
{ :ok , _ } = CommonAPI . add_mute ( user , activity )
2020-05-12 19:59:26 +00:00
conn =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses/ #{ activity . id } /mute " )
2019-09-26 06:38:45 +00:00
2020-05-12 19:59:26 +00:00
assert json_response_and_validate_schema ( conn , 400 ) == %{
" error " = > " conversation is already muted "
}
2019-09-26 06:38:45 +00:00
end
test " unmute conversation " , %{ conn : conn , user : user , activity : activity } do
{ :ok , _ } = CommonAPI . add_mute ( user , activity )
id_str = to_string ( activity . id )
assert %{ " id " = > ^ id_str , " muted " = > false } =
conn
2019-12-15 19:32:42 +00:00
# |> assign(:user, user)
2019-09-26 06:38:45 +00:00
|> post ( " /api/v1/statuses/ #{ activity . id } /unmute " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
end
end
test " Repeated posts that are replies incorrectly have in_reply_to_id null " , %{ conn : conn } do
user1 = insert ( :user )
user2 = insert ( :user )
user3 = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , replied_to } = CommonAPI . post ( user1 , %{ status : " cofe " } )
2019-09-26 06:38:45 +00:00
# Reply to status from another user
conn1 =
conn
|> assign ( :user , user2 )
2019-12-15 19:32:42 +00:00
|> assign ( :token , insert ( :oauth_token , user : user2 , scopes : [ " write:statuses " ] ) )
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> post ( " /api/v1/statuses " , %{ " status " = > " xD " , " in_reply_to_id " = > replied_to . id } )
2020-05-12 19:59:26 +00:00
assert %{ " content " = > " xD " , " id " = > id } = json_response_and_validate_schema ( conn1 , 200 )
2019-09-26 06:38:45 +00:00
activity = Activity . get_by_id_with_object ( id )
2021-01-04 12:38:31 +00:00
assert Object . normalize ( activity , fetch : false ) . data [ " inReplyTo " ] ==
Object . normalize ( replied_to , fetch : false ) . data [ " id " ]
2019-09-26 06:38:45 +00:00
assert Activity . get_in_reply_to_activity ( activity ) . id == replied_to . id
# Reblog from the third user
conn2 =
conn
|> assign ( :user , user3 )
2019-12-15 19:32:42 +00:00
|> assign ( :token , insert ( :oauth_token , user : user3 , scopes : [ " write:statuses " ] ) )
2020-05-12 19:59:26 +00:00
|> put_req_header ( " content-type " , " application/json " )
2019-09-26 06:38:45 +00:00
|> post ( " /api/v1/statuses/ #{ activity . id } /reblog " )
assert %{ " reblog " = > %{ " id " = > id , " reblogged " = > true , " reblogs_count " = > 1 } } =
2020-05-12 19:59:26 +00:00
json_response_and_validate_schema ( conn2 , 200 )
2019-09-26 06:38:45 +00:00
assert to_string ( activity . id ) == id
# Getting third user status
conn3 =
conn
|> assign ( :user , user3 )
2019-12-15 19:32:42 +00:00
|> assign ( :token , insert ( :oauth_token , user : user3 , scopes : [ " read:statuses " ] ) )
2019-09-26 06:38:45 +00:00
|> get ( " api/v1/timelines/home " )
2021-02-16 23:45:01 +00:00
[ reblogged_activity ] = json_response_and_validate_schema ( conn3 , 200 )
2019-09-26 06:38:45 +00:00
assert reblogged_activity [ " reblog " ] [ " in_reply_to_id " ] == replied_to . id
replied_to_user = User . get_by_ap_id ( replied_to . data [ " actor " ] )
assert reblogged_activity [ " reblog " ] [ " in_reply_to_account_id " ] == replied_to_user . id
end
describe " GET /api/v1/statuses/:id/favourited_by " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " read:accounts " ] )
2019-09-26 06:38:45 +00:00
2019-12-15 19:32:42 +00:00
setup %{ user : user } do
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " test " } )
2019-09-26 06:38:45 +00:00
2019-12-15 19:32:42 +00:00
%{ activity : activity }
2019-09-26 06:38:45 +00:00
end
test " returns users who have favorited the status " , %{ conn : conn , activity : activity } do
other_user = insert ( :user )
2019-10-16 14:16:39 +00:00
{ :ok , _ } = CommonAPI . favorite ( other_user , activity . id )
2019-09-26 06:38:45 +00:00
response =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } /favourited_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-09-26 06:38:45 +00:00
[ %{ " id " = > id } ] = response
assert id == other_user . id
end
test " returns empty array when status has not been favorited yet " , %{
conn : conn ,
activity : activity
} do
response =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } /favourited_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-09-26 06:38:45 +00:00
assert Enum . empty? ( response )
end
test " does not return users who have favorited the status but are blocked " , %{
conn : %{ assigns : %{ user : user } } = conn ,
activity : activity
} do
other_user = insert ( :user )
2019-11-19 20:22:10 +00:00
{ :ok , _user_relationship } = User . block ( user , other_user )
2019-09-26 06:38:45 +00:00
2019-10-16 14:16:39 +00:00
{ :ok , _ } = CommonAPI . favorite ( other_user , activity . id )
2019-09-26 06:38:45 +00:00
response =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } /favourited_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-09-26 06:38:45 +00:00
assert Enum . empty? ( response )
end
2019-12-15 19:32:42 +00:00
test " does not fail on an unauthenticated request " , %{ activity : activity } do
2019-09-26 06:38:45 +00:00
other_user = insert ( :user )
2019-10-16 14:16:39 +00:00
{ :ok , _ } = CommonAPI . favorite ( other_user , activity . id )
2019-09-26 06:38:45 +00:00
response =
2019-12-15 19:32:42 +00:00
build_conn ( )
2019-09-26 06:38:45 +00:00
|> get ( " /api/v1/statuses/ #{ activity . id } /favourited_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-09-26 06:38:45 +00:00
[ %{ " id " = > id } ] = response
assert id == other_user . id
end
2019-12-15 19:32:42 +00:00
test " requires authentication for private posts " , %{ user : user } do
2019-09-26 06:38:45 +00:00
other_user = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( user , %{
2020-05-12 19:59:26 +00:00
status : " @ #{ other_user . nickname } wanna get some # cofe together? " ,
visibility : " direct "
2019-09-26 06:38:45 +00:00
} )
2019-10-16 14:16:39 +00:00
{ :ok , _ } = CommonAPI . favorite ( other_user , activity . id )
2019-09-26 06:38:45 +00:00
2019-12-15 19:32:42 +00:00
favourited_by_url = " /api/v1/statuses/ #{ activity . id } /favourited_by "
build_conn ( )
|> get ( favourited_by_url )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 404 )
2019-09-26 06:38:45 +00:00
2019-12-15 19:32:42 +00:00
conn =
2019-09-26 06:38:45 +00:00
build_conn ( )
|> assign ( :user , other_user )
2019-12-15 19:32:42 +00:00
|> assign ( :token , insert ( :oauth_token , user : other_user , scopes : [ " read:accounts " ] ) )
conn
|> assign ( :token , nil )
|> get ( favourited_by_url )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 404 )
2019-12-15 19:32:42 +00:00
response =
conn
|> get ( favourited_by_url )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
[ %{ " id " = > id } ] = response
assert id == other_user . id
end
2020-07-28 19:49:49 +00:00
test " returns empty array when :show_reactions is disabled " , %{ conn : conn , activity : activity } do
2020-07-29 17:50:11 +00:00
clear_config ( [ :instance , :show_reactions ] , false )
2020-07-28 19:49:49 +00:00
other_user = insert ( :user )
{ :ok , _ } = CommonAPI . favorite ( other_user , activity . id )
response =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } /favourited_by " )
|> json_response_and_validate_schema ( :ok )
assert Enum . empty? ( response )
end
2019-09-26 06:38:45 +00:00
end
describe " GET /api/v1/statuses/:id/reblogged_by " do
2019-12-15 19:32:42 +00:00
setup do : oauth_access ( [ " read:accounts " ] )
2019-09-26 06:38:45 +00:00
2019-12-15 19:32:42 +00:00
setup %{ user : user } do
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " test " } )
2019-09-26 06:38:45 +00:00
2019-12-15 19:32:42 +00:00
%{ activity : activity }
2019-09-26 06:38:45 +00:00
end
test " returns users who have reblogged the status " , %{ conn : conn , activity : activity } do
other_user = insert ( :user )
2020-05-21 11:16:21 +00:00
{ :ok , _ } = CommonAPI . repeat ( activity . id , other_user )
2019-09-26 06:38:45 +00:00
response =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } /reblogged_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-09-26 06:38:45 +00:00
[ %{ " id " = > id } ] = response
assert id == other_user . id
end
test " returns empty array when status has not been reblogged yet " , %{
conn : conn ,
activity : activity
} do
response =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } /reblogged_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-09-26 06:38:45 +00:00
assert Enum . empty? ( response )
end
test " does not return users who have reblogged the status but are blocked " , %{
conn : %{ assigns : %{ user : user } } = conn ,
activity : activity
} do
other_user = insert ( :user )
2019-11-19 20:22:10 +00:00
{ :ok , _user_relationship } = User . block ( user , other_user )
2019-09-26 06:38:45 +00:00
2020-05-21 11:16:21 +00:00
{ :ok , _ } = CommonAPI . repeat ( activity . id , other_user )
2019-09-26 06:38:45 +00:00
response =
conn
2019-10-01 19:40:35 +00:00
|> get ( " /api/v1/statuses/ #{ activity . id } /reblogged_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-10-01 19:40:35 +00:00
assert Enum . empty? ( response )
end
test " does not return users who have reblogged the status privately " , %{
2020-05-21 11:16:21 +00:00
conn : conn
2019-10-01 19:40:35 +00:00
} do
other_user = insert ( :user )
2020-05-21 11:16:21 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " my secret post " } )
2019-10-01 19:40:35 +00:00
2020-05-21 11:16:21 +00:00
{ :ok , _ } = CommonAPI . repeat ( activity . id , other_user , %{ visibility : " private " } )
2019-10-01 19:40:35 +00:00
response =
conn
2019-09-26 06:38:45 +00:00
|> get ( " /api/v1/statuses/ #{ activity . id } /reblogged_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-09-26 06:38:45 +00:00
assert Enum . empty? ( response )
end
2019-12-15 19:32:42 +00:00
test " does not fail on an unauthenticated request " , %{ activity : activity } do
2019-09-26 06:38:45 +00:00
other_user = insert ( :user )
2020-05-21 11:16:21 +00:00
{ :ok , _ } = CommonAPI . repeat ( activity . id , other_user )
2019-09-26 06:38:45 +00:00
response =
2019-12-15 19:32:42 +00:00
build_conn ( )
2019-09-26 06:38:45 +00:00
|> get ( " /api/v1/statuses/ #{ activity . id } /reblogged_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-09-26 06:38:45 +00:00
[ %{ " id " = > id } ] = response
assert id == other_user . id
end
2019-12-15 19:32:42 +00:00
test " requires authentication for private posts " , %{ user : user } do
2019-09-26 06:38:45 +00:00
other_user = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( user , %{
2020-05-12 19:59:26 +00:00
status : " @ #{ other_user . nickname } wanna get some # cofe together? " ,
visibility : " direct "
2019-09-26 06:38:45 +00:00
} )
2019-12-15 19:32:42 +00:00
build_conn ( )
2019-09-26 06:38:45 +00:00
|> get ( " /api/v1/statuses/ #{ activity . id } /reblogged_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 404 )
2019-09-26 06:38:45 +00:00
response =
build_conn ( )
|> assign ( :user , other_user )
2019-12-15 19:32:42 +00:00
|> assign ( :token , insert ( :oauth_token , user : other_user , scopes : [ " read:accounts " ] ) )
2019-09-26 06:38:45 +00:00
|> get ( " /api/v1/statuses/ #{ activity . id } /reblogged_by " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( 200 )
2019-09-26 06:38:45 +00:00
assert [ ] == response
end
end
2019-09-26 07:28:35 +00:00
test " context " do
user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , %{ id : id1 } } = CommonAPI . post ( user , %{ status : " 1 " } )
{ :ok , %{ id : id2 } } = CommonAPI . post ( user , %{ status : " 2 " , in_reply_to_status_id : id1 } )
{ :ok , %{ id : id3 } } = CommonAPI . post ( user , %{ status : " 3 " , in_reply_to_status_id : id2 } )
{ :ok , %{ id : id4 } } = CommonAPI . post ( user , %{ status : " 4 " , in_reply_to_status_id : id3 } )
{ :ok , %{ id : id5 } } = CommonAPI . post ( user , %{ status : " 5 " , in_reply_to_status_id : id4 } )
2019-09-26 07:28:35 +00:00
response =
build_conn ( )
|> get ( " /api/v1/statuses/ #{ id3 } /context " )
2020-05-12 19:59:26 +00:00
|> json_response_and_validate_schema ( :ok )
2019-09-26 07:28:35 +00:00
assert %{
" ancestors " = > [ %{ " id " = > ^ id1 } , %{ " id " = > ^ id2 } ] ,
" descendants " = > [ %{ " id " = > ^ id4 } , %{ " id " = > ^ id5 } ]
} = response
end
2019-10-02 11:27:01 +00:00
2020-06-09 08:53:40 +00:00
test " favorites paginate correctly " do
%{ user : user , conn : conn } = oauth_access ( [ " read:favourites " ] )
other_user = insert ( :user )
{ :ok , first_post } = CommonAPI . post ( other_user , %{ status : " bla " } )
{ :ok , second_post } = CommonAPI . post ( other_user , %{ status : " bla " } )
{ :ok , third_post } = CommonAPI . post ( other_user , %{ status : " bla " } )
{ :ok , _first_favorite } = CommonAPI . favorite ( user , third_post . id )
{ :ok , _second_favorite } = CommonAPI . favorite ( user , first_post . id )
{ :ok , third_favorite } = CommonAPI . favorite ( user , second_post . id )
result =
conn
|> get ( " /api/v1/favourites?limit=1 " )
assert [ %{ " id " = > post_id } ] = json_response_and_validate_schema ( result , 200 )
assert post_id == second_post . id
# Using the header for pagination works correctly
[ next , _ ] = get_resp_header ( result , " link " ) |> hd ( ) |> String . split ( " , " )
2020-06-19 13:14:06 +00:00
[ _ , max_id ] = Regex . run ( ~r/ max_id=([^&]+) / , next )
2020-06-09 08:53:40 +00:00
assert max_id == third_favorite . id
result =
conn
|> get ( " /api/v1/favourites?max_id= #{ max_id } " )
assert [ %{ " id " = > first_post_id } , %{ " id " = > third_post_id } ] =
json_response_and_validate_schema ( result , 200 )
assert first_post_id == first_post . id
assert third_post_id == third_post . id
end
2019-12-15 19:32:42 +00:00
test " returns the favorites of a user " do
%{ user : user , conn : conn } = oauth_access ( [ " read:favourites " ] )
2019-10-02 11:27:01 +00:00
other_user = insert ( :user )
2020-05-12 19:59:26 +00:00
{ :ok , _ } = CommonAPI . post ( other_user , %{ status : " bla " } )
2020-06-09 08:53:40 +00:00
{ :ok , activity } = CommonAPI . post ( other_user , %{ status : " trees are happy " } )
2019-10-02 11:27:01 +00:00
2020-06-09 08:53:40 +00:00
{ :ok , last_like } = CommonAPI . favorite ( user , activity . id )
2019-10-02 11:27:01 +00:00
2019-12-15 19:32:42 +00:00
first_conn = get ( conn , " /api/v1/favourites " )
2019-10-02 11:27:01 +00:00
2020-05-12 19:59:26 +00:00
assert [ status ] = json_response_and_validate_schema ( first_conn , 200 )
2019-10-02 11:27:01 +00:00
assert status [ " id " ] == to_string ( activity . id )
assert [ { " link " , _link_header } ] =
Enum . filter ( first_conn . resp_headers , fn element -> match? ( { " link " , _ } , element ) end )
# Honours query params
{ :ok , second_activity } =
CommonAPI . post ( other_user , %{
2020-05-12 19:59:26 +00:00
status : " Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful. "
2019-10-02 11:27:01 +00:00
} )
2019-10-16 14:16:39 +00:00
{ :ok , _ } = CommonAPI . favorite ( user , second_activity . id )
2019-10-02 11:27:01 +00:00
2020-06-09 08:53:40 +00:00
second_conn = get ( conn , " /api/v1/favourites?since_id= #{ last_like . id } " )
2019-10-02 11:27:01 +00:00
2020-05-12 19:59:26 +00:00
assert [ second_status ] = json_response_and_validate_schema ( second_conn , 200 )
2019-10-02 11:27:01 +00:00
assert second_status [ " id " ] == to_string ( second_activity . id )
2019-12-15 19:32:42 +00:00
third_conn = get ( conn , " /api/v1/favourites?limit=0 " )
2019-10-02 11:27:01 +00:00
2020-05-12 19:59:26 +00:00
assert [ ] = json_response_and_validate_schema ( third_conn , 200 )
2019-10-02 11:27:01 +00:00
end
2020-02-18 13:09:50 +00:00
test " expires_at is nil for another user " do
%{ conn : conn , user : user } = oauth_access ( [ " read:statuses " ] )
2020-08-22 17:46:01 +00:00
expires_at = DateTime . add ( DateTime . utc_now ( ) , 1_000_000 )
2020-05-12 19:59:26 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " foobar " , expires_in : 1_000_000 } )
2020-02-18 13:09:50 +00:00
2020-08-22 17:46:01 +00:00
assert %{ " pleroma " = > %{ " expires_at " = > a_expires_at } } =
2020-05-12 19:59:26 +00:00
conn
|> get ( " /api/v1/statuses/ #{ activity . id } " )
|> json_response_and_validate_schema ( :ok )
2020-02-18 13:09:50 +00:00
2020-08-22 17:46:01 +00:00
{ :ok , a_expires_at , 0 } = DateTime . from_iso8601 ( a_expires_at )
assert DateTime . diff ( expires_at , a_expires_at ) == 0
2020-02-18 13:09:50 +00:00
%{ conn : conn } = oauth_access ( [ " read:statuses " ] )
assert %{ " pleroma " = > %{ " expires_at " = > nil } } =
2020-05-12 19:59:26 +00:00
conn
|> get ( " /api/v1/statuses/ #{ activity . id } " )
|> json_response_and_validate_schema ( :ok )
2020-02-18 13:09:50 +00:00
end
2020-11-16 18:23:25 +00:00
2022-05-05 02:51:40 +00:00
describe " local-only statuses " do
test " posting a local only status " do
%{ user : _user , conn : conn } = oauth_access ( [ " write:statuses " ] )
2020-10-02 17:00:50 +00:00
2022-05-05 02:51:40 +00:00
conn_one =
conn
|> put_req_header ( " content-type " , " application/json " )
|> post ( " /api/v1/statuses " , %{
" status " = > " cofe " ,
" visibility " = > " local "
} )
local = Utils . as_local_public ( )
2020-10-02 17:00:50 +00:00
2022-05-05 02:51:40 +00:00
assert %{ " content " = > " cofe " , " id " = > id , " visibility " = > " local " } =
json_response_and_validate_schema ( conn_one , 200 )
assert % Activity { id : ^ id , data : %{ " to " = > [ ^ local ] } } = Activity . get_by_id ( id )
end
2020-10-02 17:00:50 +00:00
2022-05-05 02:51:40 +00:00
test " other users can read local-only posts " do
user = insert ( :user )
2022-05-05 02:58:17 +00:00
%{ user : _reader , conn : conn } = oauth_access ( [ " read:statuses " ] )
2020-10-02 17:00:50 +00:00
2022-05-05 02:51:40 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " # 2hu # 2HU " , visibility : " local " } )
2020-10-02 17:00:50 +00:00
2022-05-05 02:51:40 +00:00
received =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } " )
|> json_response_and_validate_schema ( :ok )
assert received [ " id " ] == activity . id
end
2022-05-05 02:58:17 +00:00
test " anonymous users cannot see local-only posts " do
2022-05-05 02:51:40 +00:00
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ status : " # 2hu # 2HU " , visibility : " local " } )
2022-05-05 02:58:17 +00:00
_received =
build_conn ( )
2022-05-05 02:51:40 +00:00
|> get ( " /api/v1/statuses/ #{ activity . id } " )
2022-05-05 02:58:17 +00:00
|> json_response_and_validate_schema ( :not_found )
2022-05-05 02:51:40 +00:00
end
2020-10-02 17:00:50 +00:00
end
2020-11-17 14:29:52 +00:00
2020-11-16 18:23:25 +00:00
describe " muted reactions " do
test " index " do
%{ conn : conn , user : user } = oauth_access ( [ " read:statuses " ] )
other_user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ status : " test " } )
{ :ok , _ } = CommonAPI . react_with_emoji ( activity . id , other_user , " 🎅 " )
User . mute ( user , other_user )
result =
conn
|> get ( " /api/v1/statuses/?ids[]= #{ activity . id } " )
|> json_response_and_validate_schema ( 200 )
assert [
%{
" pleroma " = > %{
" emoji_reactions " = > [ ]
}
}
] = result
result =
conn
|> get ( " /api/v1/statuses/?ids[]= #{ activity . id } &with_muted=true " )
|> json_response_and_validate_schema ( 200 )
assert [
%{
" pleroma " = > %{
" emoji_reactions " = > [ %{ " count " = > 1 , " me " = > false , " name " = > " 🎅 " } ]
}
}
] = result
end
test " show " do
# %{conn: conn, user: user, token: token} = oauth_access(["read:statuses"])
%{ conn : conn , user : user , token : _token } = oauth_access ( [ " read:statuses " ] )
other_user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ status : " test " } )
{ :ok , _ } = CommonAPI . react_with_emoji ( activity . id , other_user , " 🎅 " )
User . mute ( user , other_user )
result =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } " )
|> json_response_and_validate_schema ( 200 )
assert %{
" pleroma " = > %{
" emoji_reactions " = > [ ]
}
} = result
result =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } ?with_muted=true " )
|> json_response_and_validate_schema ( 200 )
assert %{
" pleroma " = > %{
" emoji_reactions " = > [ %{ " count " = > 1 , " me " = > false , " name " = > " 🎅 " } ]
}
} = result
end
end
2022-05-30 03:50:31 +00:00
describe " get status history " do
setup do
2022-06-11 14:35:36 +00:00
%{ conn : build_conn ( ) }
2022-05-30 03:50:31 +00:00
end
test " unedited post " , %{ conn : conn } do
activity = insert ( :note_activity )
conn = get ( conn , " /api/v1/statuses/ #{ activity . id } /history " )
assert [ _ ] = json_response_and_validate_schema ( conn , 200 )
end
test " edited post " , %{ conn : conn } do
note =
insert (
:note ,
data : %{
" formerRepresentations " = > %{
" type " = > " OrderedCollection " ,
" orderedItems " = > [
%{
" type " = > " Note " ,
" content " = > " mew mew 2 " ,
" summary " = > " title 2 "
} ,
%{
" type " = > " Note " ,
" content " = > " mew mew 1 " ,
" summary " = > " title 1 "
}
] ,
" totalItems " = > 2
}
}
)
activity = insert ( :note_activity , note : note )
conn = get ( conn , " /api/v1/statuses/ #{ activity . id } /history " )
2022-06-11 23:52:07 +00:00
assert [ %{ " spoiler_text " = > " title 1 " } , %{ " spoiler_text " = > " title 2 " } , _ ] =
2022-05-30 03:50:31 +00:00
json_response_and_validate_schema ( conn , 200 )
end
end
2022-05-30 04:59:23 +00:00
describe " get status source " do
setup do
2022-06-11 14:35:36 +00:00
%{ conn : build_conn ( ) }
2022-05-30 04:59:23 +00:00
end
test " it returns the source " , %{ conn : conn } do
user = insert ( :user )
{ :ok , activity } = CommonAPI . post ( user , %{ status : " mew mew # abc " , spoiler_text : " # def " } )
conn = get ( conn , " /api/v1/statuses/ #{ activity . id } /source " )
id = activity . id
2022-05-31 18:29:12 +00:00
assert %{ " id " = > ^ id , " text " = > " mew mew # abc " , " spoiler_text " = > " # def " } =
json_response_and_validate_schema ( conn , 200 )
end
end
describe " update status " do
setup do
oauth_access ( [ " write:statuses " ] )
end
2022-06-09 15:39:51 +00:00
test " it updates the status " do
%{ conn : conn , user : user } = oauth_access ( [ " write:statuses " , " read:statuses " ] )
2022-05-31 18:29:12 +00:00
{ :ok , activity } = CommonAPI . post ( user , %{ status : " mew mew # abc " , spoiler_text : " # def " } )
2022-06-09 15:39:51 +00:00
conn
|> get ( " /api/v1/statuses/ #{ activity . id } " )
|> json_response_and_validate_schema ( 200 )
2022-05-31 18:29:12 +00:00
response =
conn
|> put_req_header ( " content-type " , " application/json " )
|> put ( " /api/v1/statuses/ #{ activity . id } " , %{
" status " = > " edited " ,
" spoiler_text " = > " lol "
} )
|> json_response_and_validate_schema ( 200 )
assert response [ " content " ] == " edited "
assert response [ " spoiler_text " ] == " lol "
2022-06-09 15:39:51 +00:00
response =
conn
|> get ( " /api/v1/statuses/ #{ activity . id } " )
|> json_response_and_validate_schema ( 200 )
assert response [ " content " ] == " edited "
assert response [ " spoiler_text " ] == " lol "
2022-05-31 18:29:12 +00:00
end
2022-06-08 15:45:24 +00:00
test " it updates the attachments " , %{ conn : conn , user : user } do
attachment = insert ( :attachment , user : user )
attachment_id = to_string ( attachment . id )
{ :ok , activity } = CommonAPI . post ( user , %{ status : " mew mew # abc " , spoiler_text : " # def " } )
response =
conn
|> put_req_header ( " content-type " , " application/json " )
|> put ( " /api/v1/statuses/ #{ activity . id } " , %{
" status " = > " mew mew # abc " ,
" spoiler_text " = > " # def " ,
" media_ids " = > [ attachment_id ]
} )
|> json_response_and_validate_schema ( 200 )
assert [ %{ " id " = > ^ attachment_id } ] = response [ " media_attachments " ]
end
2022-05-31 18:29:12 +00:00
test " it does not update visibility " , %{ conn : conn , user : user } do
{ :ok , activity } =
CommonAPI . post ( user , %{
status : " mew mew # abc " ,
spoiler_text : " # def " ,
visibility : " private "
} )
response =
conn
|> put_req_header ( " content-type " , " application/json " )
|> put ( " /api/v1/statuses/ #{ activity . id } " , %{
" status " = > " edited " ,
" spoiler_text " = > " lol "
} )
|> json_response_and_validate_schema ( 200 )
assert response [ " visibility " ] == " private "
end
test " it refuses to update when original post is not by the user " , %{ conn : conn } do
another_user = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( another_user , %{ status : " mew mew # abc " , spoiler_text : " # def " } )
conn
|> put_req_header ( " content-type " , " application/json " )
|> put ( " /api/v1/statuses/ #{ activity . id } " , %{
" status " = > " edited " ,
" spoiler_text " = > " lol "
} )
|> json_response_and_validate_schema ( :forbidden )
end
test " it returns 404 if the user cannot see the post " , %{ conn : conn } do
another_user = insert ( :user )
{ :ok , activity } =
CommonAPI . post ( another_user , %{
status : " mew mew # abc " ,
spoiler_text : " # def " ,
visibility : " private "
} )
conn
|> put_req_header ( " content-type " , " application/json " )
|> put ( " /api/v1/statuses/ #{ activity . id } " , %{
" status " = > " edited " ,
" spoiler_text " = > " lol "
} )
|> json_response_and_validate_schema ( :not_found )
2022-05-30 04:59:23 +00:00
end
end
2019-09-26 06:38:45 +00:00
end