2023-03-12 16:00:57 +01:00
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
2021-04-19 19:42:19 +02:00
2023-01-02 13:10:50 +01:00
package statuses_test
2021-04-19 19:42:19 +02:00
import (
2021-08-25 15:34:33 +02:00
"context"
2021-04-19 19:42:19 +02:00
"encoding/json"
"fmt"
2024-03-06 18:05:45 +01:00
"io"
2021-04-19 19:42:19 +02:00
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
2024-03-06 18:05:45 +01:00
"strings"
2021-04-19 19:42:19 +02:00
"testing"
"github.com/stretchr/testify/suite"
2023-01-02 13:10:50 +01:00
"github.com/superseriousbusiness/gotosocial/internal/api/client/statuses"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
2021-05-21 15:48:26 +02:00
"github.com/superseriousbusiness/gotosocial/internal/db"
2021-05-08 14:25:55 +02:00
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
2021-04-19 19:42:19 +02:00
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/testrig"
)
type StatusCreateTestSuite struct {
2021-05-08 14:25:55 +02:00
StatusStandardTestSuite
2021-04-19 19:42:19 +02:00
}
2022-08-06 12:09:21 +02:00
const (
statusWithLinksAndTags = "#test alright, should be able to post #links with fragments in them now, let's see........\n\nhttps://docs.gotosocial.org/en/latest/user_guide/posts/#links\n\n#gotosocial\n\n(tobi remember to pull the docker image challenge)"
statusMarkdown = "# Title\n\n## Smaller title\n\nThis is a post written in [markdown](https://www.markdownguide.org/)\n\n<img src=\"https://d33wubrfki0l68.cloudfront.net/f1f475a6fda1c2c4be4cac04033db5c3293032b4/513a4/assets/images/markdown-mark-white.svg\"/>"
2023-08-11 14:40:11 +02:00
statusMarkdownExpected = "<h1>Title</h1><h2>Smaller title</h2><p>This is a post written in <a href=\"https://www.markdownguide.org/\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">markdown</a></p>"
2022-08-06 12:09:21 +02:00
)
2021-07-29 13:18:22 +02:00
2021-04-19 19:42:19 +02:00
// Post a new status with some custom visibility settings
func ( suite * StatusCreateTestSuite ) TestPostNewStatus ( ) {
t := suite . testTokens [ "local_account_1" ]
2021-08-25 15:34:33 +02:00
oauthToken := oauth . DBTokenToToken ( t )
2021-04-19 19:42:19 +02:00
// setup
recorder := httptest . NewRecorder ( )
2022-07-12 09:32:20 +02:00
ctx , _ := testrig . CreateGinTestContext ( recorder , nil )
2021-04-19 19:42:19 +02:00
ctx . Set ( oauth . SessionAuthorizedApplication , suite . testApplications [ "application_1" ] )
ctx . Set ( oauth . SessionAuthorizedToken , oauthToken )
ctx . Set ( oauth . SessionAuthorizedUser , suite . testUsers [ "local_account_1" ] )
ctx . Set ( oauth . SessionAuthorizedAccount , suite . testAccounts [ "local_account_1" ] )
2023-01-02 13:10:50 +01:00
ctx . Request = httptest . NewRequest ( http . MethodPost , fmt . Sprintf ( "http://localhost:8080/%s" , statuses . BasePath ) , nil ) // the endpoint we're hitting
2021-12-11 17:50:00 +01:00
ctx . Request . Header . Set ( "accept" , "application/json" )
2021-04-19 19:42:19 +02:00
ctx . Request . Form = url . Values {
2021-08-12 21:03:24 +02:00
"status" : { "this is a brand new status! #helloworld" } ,
"spoiler_text" : { "hello hello" } ,
"sensitive" : { "true" } ,
2023-01-02 13:10:50 +01:00
"visibility" : { string ( apimodel . VisibilityMutualsOnly ) } ,
2021-04-19 19:42:19 +02:00
}
suite . statusModule . StatusCreatePOSTHandler ( ctx )
// check response
// 1. we should have OK from our call to the function
suite . EqualValues ( http . StatusOK , recorder . Code )
result := recorder . Result ( )
defer result . Body . Close ( )
b , err := ioutil . ReadAll ( result . Body )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2021-04-19 19:42:19 +02:00
2023-01-02 13:10:50 +01:00
statusReply := & apimodel . Status { }
2021-04-19 19:42:19 +02:00
err = json . Unmarshal ( b , statusReply )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
suite . Equal ( "hello hello" , statusReply . SpoilerText )
suite . Equal ( "<p>this is a brand new status! <a href=\"http://localhost:8080/tags/helloworld\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>helloworld</span></a></p>" , statusReply . Content )
suite . True ( statusReply . Sensitive )
2023-01-02 13:10:50 +01:00
suite . Equal ( apimodel . VisibilityPrivate , statusReply . Visibility ) // even though we set this status to mutuals only, it should serialize to private, because the mastodon api has no idea about mutuals_only
2022-03-29 11:54:56 +02:00
suite . Len ( statusReply . Tags , 1 )
2023-01-02 13:10:50 +01:00
suite . Equal ( apimodel . Tag {
2021-04-19 19:42:19 +02:00
Name : "helloworld" ,
URL : "http://localhost:8080/tags/helloworld" ,
} , statusReply . Tags [ 0 ] )
gtsTag := & gtsmodel . Tag { }
2021-08-25 15:34:33 +02:00
err = suite . db . GetWhere ( context . Background ( ) , [ ] db . Where { { Key : "name" , Value : "helloworld" } } , gtsTag )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
}
2022-08-06 12:09:21 +02:00
func ( suite * StatusCreateTestSuite ) TestPostNewStatusMarkdown ( ) {
2024-03-22 14:03:46 +01:00
// Copy zork.
testAccount := & gtsmodel . Account { }
* testAccount = * suite . testAccounts [ "local_account_1" ]
// Copy zork's settings.
settings := & gtsmodel . AccountSettings { }
* settings = * suite . testAccounts [ "local_account_1" ] . Settings
testAccount . Settings = settings
// set default post language of zork to markdown
testAccount . Settings . StatusContentType = "text/markdown"
err := suite . db . UpdateAccountSettings ( context . Background ( ) , testAccount . Settings )
2022-08-06 12:09:21 +02:00
if err != nil {
suite . FailNow ( err . Error ( ) )
}
2024-03-22 14:03:46 +01:00
suite . Equal ( testAccount . Settings . StatusContentType , "text/markdown" )
2022-08-06 12:09:21 +02:00
t := suite . testTokens [ "local_account_1" ]
oauthToken := oauth . DBTokenToToken ( t )
recorder := httptest . NewRecorder ( )
ctx , _ := testrig . CreateGinTestContext ( recorder , nil )
ctx . Set ( oauth . SessionAuthorizedApplication , suite . testApplications [ "application_1" ] )
ctx . Set ( oauth . SessionAuthorizedToken , oauthToken )
ctx . Set ( oauth . SessionAuthorizedUser , suite . testUsers [ "local_account_1" ] )
2024-03-22 14:03:46 +01:00
ctx . Set ( oauth . SessionAuthorizedAccount , testAccount )
2022-08-06 12:09:21 +02:00
2023-01-02 13:10:50 +01:00
ctx . Request = httptest . NewRequest ( http . MethodPost , fmt . Sprintf ( "http://localhost:8080/%s" , statuses . BasePath ) , nil )
2022-08-06 12:09:21 +02:00
ctx . Request . Header . Set ( "accept" , "application/json" )
ctx . Request . Form = url . Values {
"status" : { statusMarkdown } ,
2023-01-02 13:10:50 +01:00
"visibility" : { string ( apimodel . VisibilityPublic ) } ,
2022-08-06 12:09:21 +02:00
}
suite . statusModule . StatusCreatePOSTHandler ( ctx )
suite . EqualValues ( http . StatusOK , recorder . Code )
result := recorder . Result ( )
defer result . Body . Close ( )
b , err := ioutil . ReadAll ( result . Body )
suite . NoError ( err )
2023-01-02 13:10:50 +01:00
statusReply := & apimodel . Status { }
2022-08-06 12:09:21 +02:00
err = json . Unmarshal ( b , statusReply )
suite . NoError ( err )
suite . Equal ( statusMarkdownExpected , statusReply . Content )
}
2022-03-29 11:54:56 +02:00
// mention an account that is not yet known to the instance -- it should be looked up and put in the db
func ( suite * StatusCreateTestSuite ) TestMentionUnknownAccount ( ) {
// first remove remote account 1 from the database so it gets looked up again
remoteAccount := suite . testAccounts [ "remote_account_1" ]
2022-11-15 19:45:15 +01:00
err := suite . db . DeleteAccount ( context . Background ( ) , remoteAccount . ID )
suite . NoError ( err )
2022-03-29 11:54:56 +02:00
t := suite . testTokens [ "local_account_1" ]
oauthToken := oauth . DBTokenToToken ( t )
// setup
recorder := httptest . NewRecorder ( )
2022-07-12 09:32:20 +02:00
ctx , _ := testrig . CreateGinTestContext ( recorder , nil )
2022-03-29 11:54:56 +02:00
ctx . Set ( oauth . SessionAuthorizedApplication , suite . testApplications [ "application_1" ] )
ctx . Set ( oauth . SessionAuthorizedToken , oauthToken )
ctx . Set ( oauth . SessionAuthorizedUser , suite . testUsers [ "local_account_1" ] )
ctx . Set ( oauth . SessionAuthorizedAccount , suite . testAccounts [ "local_account_1" ] )
2023-01-02 13:10:50 +01:00
ctx . Request = httptest . NewRequest ( http . MethodPost , fmt . Sprintf ( "http://localhost:8080/%s" , statuses . BasePath ) , nil ) // the endpoint we're hitting
2022-03-29 11:54:56 +02:00
ctx . Request . Header . Set ( "accept" , "application/json" )
ctx . Request . Form = url . Values {
2022-06-11 11:01:34 +02:00
"status" : { "hello @brand_new_person@unknown-instance.com" } ,
2023-01-02 13:10:50 +01:00
"visibility" : { string ( apimodel . VisibilityPublic ) } ,
2022-03-29 11:54:56 +02:00
}
suite . statusModule . StatusCreatePOSTHandler ( ctx )
suite . EqualValues ( http . StatusOK , recorder . Code )
result := recorder . Result ( )
defer result . Body . Close ( )
b , err := ioutil . ReadAll ( result . Body )
suite . NoError ( err )
2023-01-02 13:10:50 +01:00
statusReply := & apimodel . Status { }
2022-03-29 11:54:56 +02:00
err = json . Unmarshal ( b , statusReply )
suite . NoError ( err )
// if the status is properly formatted, that means the account has been put in the db
2022-06-11 11:01:34 +02:00
suite . Equal ( ` <p>hello <span class="h-card"><a href="https://unknown-instance.com/@brand_new_person" class="u-url mention" rel="nofollow noreferrer noopener" target="_blank">@<span>brand_new_person</span></a></span></p> ` , statusReply . Content )
2023-01-02 13:10:50 +01:00
suite . Equal ( apimodel . VisibilityPublic , statusReply . Visibility )
2021-04-19 19:42:19 +02:00
}
2021-07-29 13:18:22 +02:00
func ( suite * StatusCreateTestSuite ) TestPostAnotherNewStatus ( ) {
t := suite . testTokens [ "local_account_1" ]
2021-08-25 15:34:33 +02:00
oauthToken := oauth . DBTokenToToken ( t )
2021-07-29 13:18:22 +02:00
// setup
recorder := httptest . NewRecorder ( )
2022-07-12 09:32:20 +02:00
ctx , _ := testrig . CreateGinTestContext ( recorder , nil )
2021-07-29 13:18:22 +02:00
ctx . Set ( oauth . SessionAuthorizedApplication , suite . testApplications [ "application_1" ] )
ctx . Set ( oauth . SessionAuthorizedToken , oauthToken )
ctx . Set ( oauth . SessionAuthorizedUser , suite . testUsers [ "local_account_1" ] )
ctx . Set ( oauth . SessionAuthorizedAccount , suite . testAccounts [ "local_account_1" ] )
2023-01-02 13:10:50 +01:00
ctx . Request = httptest . NewRequest ( http . MethodPost , fmt . Sprintf ( "http://localhost:8080/%s" , statuses . BasePath ) , nil ) // the endpoint we're hitting
2021-12-11 17:50:00 +01:00
ctx . Request . Header . Set ( "accept" , "application/json" )
2021-07-29 13:18:22 +02:00
ctx . Request . Form = url . Values {
"status" : { statusWithLinksAndTags } ,
}
suite . statusModule . StatusCreatePOSTHandler ( ctx )
// check response
// 1. we should have OK from our call to the function
suite . EqualValues ( http . StatusOK , recorder . Code )
result := recorder . Result ( )
defer result . Body . Close ( )
b , err := ioutil . ReadAll ( result . Body )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2021-07-29 13:18:22 +02:00
2023-01-02 13:10:50 +01:00
statusReply := & apimodel . Status { }
2021-07-29 13:18:22 +02:00
err = json . Unmarshal ( b , statusReply )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2021-07-29 13:18:22 +02:00
2023-02-03 11:58:58 +01:00
suite . Equal ( "<p><a href=\"http://localhost:8080/tags/test\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>test</span></a> alright, should be able to post <a href=\"http://localhost:8080/tags/links\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>links</span></a> with fragments in them now, let's see........<br><br><a href=\"https://docs.gotosocial.org/en/latest/user_guide/posts/#links\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://docs.gotosocial.org/en/latest/user_guide/posts/#links</a><br><br><a href=\"http://localhost:8080/tags/gotosocial\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>gotosocial</span></a><br><br>(tobi remember to pull the docker image challenge)</p>" , statusReply . Content )
2021-07-29 13:18:22 +02:00
}
2021-04-19 19:42:19 +02:00
func ( suite * StatusCreateTestSuite ) TestPostNewStatusWithEmoji ( ) {
t := suite . testTokens [ "local_account_1" ]
2021-08-25 15:34:33 +02:00
oauthToken := oauth . DBTokenToToken ( t )
2021-04-19 19:42:19 +02:00
// setup
recorder := httptest . NewRecorder ( )
2022-07-12 09:32:20 +02:00
ctx , _ := testrig . CreateGinTestContext ( recorder , nil )
2021-04-19 19:42:19 +02:00
ctx . Set ( oauth . SessionAuthorizedApplication , suite . testApplications [ "application_1" ] )
ctx . Set ( oauth . SessionAuthorizedToken , oauthToken )
ctx . Set ( oauth . SessionAuthorizedUser , suite . testUsers [ "local_account_1" ] )
ctx . Set ( oauth . SessionAuthorizedAccount , suite . testAccounts [ "local_account_1" ] )
2023-01-02 13:10:50 +01:00
ctx . Request = httptest . NewRequest ( http . MethodPost , fmt . Sprintf ( "http://localhost:8080/%s" , statuses . BasePath ) , nil ) // the endpoint we're hitting
2021-12-11 17:50:00 +01:00
ctx . Request . Header . Set ( "accept" , "application/json" )
2021-04-19 19:42:19 +02:00
ctx . Request . Form = url . Values {
"status" : { "here is a rainbow emoji a few times! :rainbow: :rainbow: :rainbow: \n here's an emoji that isn't in the db: :test_emoji: " } ,
}
suite . statusModule . StatusCreatePOSTHandler ( ctx )
suite . EqualValues ( http . StatusOK , recorder . Code )
result := recorder . Result ( )
defer result . Body . Close ( )
b , err := ioutil . ReadAll ( result . Body )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2021-04-19 19:42:19 +02:00
2023-01-02 13:10:50 +01:00
statusReply := & apimodel . Status { }
2021-04-19 19:42:19 +02:00
err = json . Unmarshal ( b , statusReply )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2021-04-19 19:42:19 +02:00
2022-03-29 11:54:56 +02:00
suite . Equal ( "" , statusReply . SpoilerText )
2023-02-03 11:58:58 +01:00
suite . Equal ( "<p>here is a rainbow emoji a few times! :rainbow: :rainbow: :rainbow:<br>here's an emoji that isn't in the db: :test_emoji:</p>" , statusReply . Content )
2021-04-19 19:42:19 +02:00
2022-03-29 11:54:56 +02:00
suite . Len ( statusReply . Emojis , 1 )
2021-10-04 15:24:19 +02:00
apiEmoji := statusReply . Emojis [ 0 ]
2021-04-19 19:42:19 +02:00
gtsEmoji := testrig . NewTestEmojis ( ) [ "rainbow" ]
2022-03-29 11:54:56 +02:00
suite . Equal ( gtsEmoji . Shortcode , apiEmoji . Shortcode )
suite . Equal ( gtsEmoji . ImageURL , apiEmoji . URL )
suite . Equal ( gtsEmoji . ImageStaticURL , apiEmoji . StaticURL )
2021-04-19 19:42:19 +02:00
}
// Try to reply to a status that doesn't exist
func ( suite * StatusCreateTestSuite ) TestReplyToNonexistentStatus ( ) {
t := suite . testTokens [ "local_account_1" ]
2021-08-25 15:34:33 +02:00
oauthToken := oauth . DBTokenToToken ( t )
2021-04-19 19:42:19 +02:00
// setup
recorder := httptest . NewRecorder ( )
2022-07-12 09:32:20 +02:00
ctx , _ := testrig . CreateGinTestContext ( recorder , nil )
2021-04-19 19:42:19 +02:00
ctx . Set ( oauth . SessionAuthorizedApplication , suite . testApplications [ "application_1" ] )
ctx . Set ( oauth . SessionAuthorizedToken , oauthToken )
ctx . Set ( oauth . SessionAuthorizedUser , suite . testUsers [ "local_account_1" ] )
ctx . Set ( oauth . SessionAuthorizedAccount , suite . testAccounts [ "local_account_1" ] )
2023-01-02 13:10:50 +01:00
ctx . Request = httptest . NewRequest ( http . MethodPost , fmt . Sprintf ( "http://localhost:8080/%s" , statuses . BasePath ) , nil ) // the endpoint we're hitting
2021-12-11 17:50:00 +01:00
ctx . Request . Header . Set ( "accept" , "application/json" )
2021-04-19 19:42:19 +02:00
ctx . Request . Form = url . Values {
"status" : { "this is a reply to a status that doesn't exist" } ,
"spoiler_text" : { "don't open cuz it won't work" } ,
"in_reply_to_id" : { "3759e7ef-8ee1-4c0c-86f6-8b70b9ad3d50" } ,
}
suite . statusModule . StatusCreatePOSTHandler ( ctx )
// check response
2024-02-29 15:20:57 +01:00
suite . EqualValues ( http . StatusNotFound , recorder . Code )
2021-04-19 19:42:19 +02:00
result := recorder . Result ( )
defer result . Body . Close ( )
b , err := ioutil . ReadAll ( result . Body )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2024-02-29 15:20:57 +01:00
suite . Equal ( ` { "error":"Not Found: target status not found"} ` , string ( b ) )
2021-04-19 19:42:19 +02:00
}
// Post a reply to the status of a local user that allows replies.
func ( suite * StatusCreateTestSuite ) TestReplyToLocalStatus ( ) {
t := suite . testTokens [ "local_account_1" ]
2021-08-25 15:34:33 +02:00
oauthToken := oauth . DBTokenToToken ( t )
2021-04-19 19:42:19 +02:00
// setup
recorder := httptest . NewRecorder ( )
2022-07-12 09:32:20 +02:00
ctx , _ := testrig . CreateGinTestContext ( recorder , nil )
2021-04-19 19:42:19 +02:00
ctx . Set ( oauth . SessionAuthorizedApplication , suite . testApplications [ "application_1" ] )
ctx . Set ( oauth . SessionAuthorizedToken , oauthToken )
ctx . Set ( oauth . SessionAuthorizedUser , suite . testUsers [ "local_account_1" ] )
ctx . Set ( oauth . SessionAuthorizedAccount , suite . testAccounts [ "local_account_1" ] )
2023-01-02 13:10:50 +01:00
ctx . Request = httptest . NewRequest ( http . MethodPost , fmt . Sprintf ( "http://localhost:8080/%s" , statuses . BasePath ) , nil ) // the endpoint we're hitting
2021-12-11 17:50:00 +01:00
ctx . Request . Header . Set ( "accept" , "application/json" )
2021-04-19 19:42:19 +02:00
ctx . Request . Form = url . Values {
"status" : { fmt . Sprintf ( "hello @%s this reply should work!" , testrig . NewTestAccounts ( ) [ "local_account_2" ] . Username ) } ,
"in_reply_to_id" : { testrig . NewTestStatuses ( ) [ "local_account_2_status_1" ] . ID } ,
}
suite . statusModule . StatusCreatePOSTHandler ( ctx )
// check response
suite . EqualValues ( http . StatusOK , recorder . Code )
result := recorder . Result ( )
defer result . Body . Close ( )
b , err := ioutil . ReadAll ( result . Body )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2021-04-19 19:42:19 +02:00
2023-01-02 13:10:50 +01:00
statusReply := & apimodel . Status { }
2021-04-19 19:42:19 +02:00
err = json . Unmarshal ( b , statusReply )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
suite . Equal ( "" , statusReply . SpoilerText )
suite . Equal ( fmt . Sprintf ( "<p>hello <span class=\"h-card\"><a href=\"http://localhost:8080/@%s\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>%s</span></a></span> this reply should work!</p>" , testrig . NewTestAccounts ( ) [ "local_account_2" ] . Username , testrig . NewTestAccounts ( ) [ "local_account_2" ] . Username ) , statusReply . Content )
suite . False ( statusReply . Sensitive )
2023-01-02 13:10:50 +01:00
suite . Equal ( apimodel . VisibilityPublic , statusReply . Visibility )
2022-09-02 17:00:11 +02:00
suite . Equal ( testrig . NewTestStatuses ( ) [ "local_account_2_status_1" ] . ID , * statusReply . InReplyToID )
suite . Equal ( testrig . NewTestAccounts ( ) [ "local_account_2" ] . ID , * statusReply . InReplyToAccountID )
2022-03-29 11:54:56 +02:00
suite . Len ( statusReply . Mentions , 1 )
2021-04-19 19:42:19 +02:00
}
// Take a media file which is currently not associated with a status, and attach it to a new status.
func ( suite * StatusCreateTestSuite ) TestAttachNewMediaSuccess ( ) {
t := suite . testTokens [ "local_account_1" ]
2021-08-25 15:34:33 +02:00
oauthToken := oauth . DBTokenToToken ( t )
2021-04-19 19:42:19 +02:00
2021-07-29 13:18:22 +02:00
attachment := suite . testAttachments [ "local_account_1_unattached_1" ]
2021-04-19 19:42:19 +02:00
// setup
recorder := httptest . NewRecorder ( )
2022-07-12 09:32:20 +02:00
ctx , _ := testrig . CreateGinTestContext ( recorder , nil )
2021-04-19 19:42:19 +02:00
ctx . Set ( oauth . SessionAuthorizedApplication , suite . testApplications [ "application_1" ] )
ctx . Set ( oauth . SessionAuthorizedToken , oauthToken )
ctx . Set ( oauth . SessionAuthorizedUser , suite . testUsers [ "local_account_1" ] )
ctx . Set ( oauth . SessionAuthorizedAccount , suite . testAccounts [ "local_account_1" ] )
2023-01-02 13:10:50 +01:00
ctx . Request = httptest . NewRequest ( http . MethodPost , fmt . Sprintf ( "http://localhost:8080/%s" , statuses . BasePath ) , nil ) // the endpoint we're hitting
2021-12-11 17:50:00 +01:00
ctx . Request . Header . Set ( "accept" , "application/json" )
2021-04-19 19:42:19 +02:00
ctx . Request . Form = url . Values {
2022-07-28 16:43:27 +02:00
"status" : { "here's an image attachment" } ,
2022-07-22 13:43:51 +02:00
"media_ids[]" : { attachment . ID } ,
2021-04-19 19:42:19 +02:00
}
suite . statusModule . StatusCreatePOSTHandler ( ctx )
// check response
suite . EqualValues ( http . StatusOK , recorder . Code )
result := recorder . Result ( )
defer result . Body . Close ( )
b , err := ioutil . ReadAll ( result . Body )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2021-04-19 19:42:19 +02:00
2023-01-02 13:10:50 +01:00
statusResponse := & apimodel . Status { }
2021-07-29 13:18:22 +02:00
err = json . Unmarshal ( b , statusResponse )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2021-04-19 19:42:19 +02:00
2022-03-29 11:54:56 +02:00
suite . Equal ( "" , statusResponse . SpoilerText )
2023-02-03 11:58:58 +01:00
suite . Equal ( "<p>here's an image attachment</p>" , statusResponse . Content )
2022-03-29 11:54:56 +02:00
suite . False ( statusResponse . Sensitive )
2023-01-02 13:10:50 +01:00
suite . Equal ( apimodel . VisibilityPublic , statusResponse . Visibility )
2021-04-19 19:42:19 +02:00
// there should be one media attachment
2022-03-29 11:54:56 +02:00
suite . Len ( statusResponse . MediaAttachments , 1 )
2021-04-19 19:42:19 +02:00
// get the updated media attachment from the database
2021-08-25 15:34:33 +02:00
gtsAttachment , err := suite . db . GetAttachmentByID ( context . Background ( ) , statusResponse . MediaAttachments [ 0 ] . ID )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2021-04-19 19:42:19 +02:00
2021-10-04 15:24:19 +02:00
// convert it to a api attachment
gtsAttachmentAsapi , err := suite . tc . AttachmentToAPIAttachment ( context . Background ( ) , gtsAttachment )
2022-03-29 11:54:56 +02:00
suite . NoError ( err )
2021-04-19 19:42:19 +02:00
// compare it with what we have now
2023-12-09 16:54:38 +01:00
suite . EqualValues ( * statusResponse . MediaAttachments [ 0 ] , gtsAttachmentAsapi )
2021-04-19 19:42:19 +02:00
// the status id of the attachment should now be set to the id of the status we just created
2022-03-29 11:54:56 +02:00
suite . Equal ( statusResponse . ID , gtsAttachment . StatusID )
2021-04-19 19:42:19 +02:00
}
2023-08-07 10:25:54 +02:00
// Post a new status with a language tag that is not in canonical format
func ( suite * StatusCreateTestSuite ) TestPostNewStatusWithNoncanonicalLanguageTag ( ) {
t := suite . testTokens [ "local_account_1" ]
oauthToken := oauth . DBTokenToToken ( t )
// setup
recorder := httptest . NewRecorder ( )
ctx , _ := testrig . CreateGinTestContext ( recorder , nil )
ctx . Set ( oauth . SessionAuthorizedApplication , suite . testApplications [ "application_1" ] )
ctx . Set ( oauth . SessionAuthorizedToken , oauthToken )
ctx . Set ( oauth . SessionAuthorizedUser , suite . testUsers [ "local_account_1" ] )
ctx . Set ( oauth . SessionAuthorizedAccount , suite . testAccounts [ "local_account_1" ] )
ctx . Request = httptest . NewRequest ( http . MethodPost , fmt . Sprintf ( "http://localhost:8080/%s" , statuses . BasePath ) , nil ) // the endpoint we're hitting
ctx . Request . Header . Set ( "accept" , "application/json" )
ctx . Request . Form = url . Values {
"status" : { "English? what's English? i speak American" } ,
"language" : { "en-us" } ,
}
suite . statusModule . StatusCreatePOSTHandler ( ctx )
suite . EqualValues ( http . StatusOK , recorder . Code )
result := recorder . Result ( )
defer result . Body . Close ( )
b , err := ioutil . ReadAll ( result . Body )
suite . NoError ( err )
statusReply := & apimodel . Status { }
err = json . Unmarshal ( b , statusReply )
suite . NoError ( err )
suite . Equal ( "<p>English? what's English? i speak American</p>" , statusReply . Content )
suite . NotNil ( statusReply . Language )
suite . Equal ( "en-US" , * statusReply . Language )
}
2024-03-06 18:05:45 +01:00
// Post a new status with an attached poll.
func ( suite * StatusCreateTestSuite ) testPostNewStatusWithPoll ( configure func ( request * http . Request ) ) {
t := suite . testTokens [ "local_account_1" ]
oauthToken := oauth . DBTokenToToken ( t )
// setup
recorder := httptest . NewRecorder ( )
ctx , _ := testrig . CreateGinTestContext ( recorder , nil )
ctx . Set ( oauth . SessionAuthorizedApplication , suite . testApplications [ "application_1" ] )
ctx . Set ( oauth . SessionAuthorizedToken , oauthToken )
ctx . Set ( oauth . SessionAuthorizedUser , suite . testUsers [ "local_account_1" ] )
ctx . Set ( oauth . SessionAuthorizedAccount , suite . testAccounts [ "local_account_1" ] )
ctx . Request = httptest . NewRequest ( http . MethodPost , fmt . Sprintf ( "http://localhost:8080/%s" , statuses . BasePath ) , nil ) // the endpoint we're hitting
ctx . Request . Header . Set ( "accept" , "application/json" )
configure ( ctx . Request )
suite . statusModule . StatusCreatePOSTHandler ( ctx )
suite . EqualValues ( http . StatusOK , recorder . Code )
result := recorder . Result ( )
defer result . Body . Close ( )
b , err := ioutil . ReadAll ( result . Body )
suite . NoError ( err )
statusReply := & apimodel . Status { }
err = json . Unmarshal ( b , statusReply )
suite . NoError ( err )
suite . Equal ( "<p>this is a status with a poll!</p>" , statusReply . Content )
suite . Equal ( apimodel . VisibilityPublic , statusReply . Visibility )
if suite . NotNil ( statusReply . Poll ) {
if suite . Len ( statusReply . Poll . Options , 2 ) {
suite . Equal ( "first option" , statusReply . Poll . Options [ 0 ] . Title )
suite . Equal ( "second option" , statusReply . Poll . Options [ 1 ] . Title )
}
suite . NotZero ( statusReply . Poll . ExpiresAt )
suite . False ( statusReply . Poll . Expired )
suite . True ( statusReply . Poll . Multiple )
}
}
func ( suite * StatusCreateTestSuite ) TestPostNewStatusWithPollForm ( ) {
suite . testPostNewStatusWithPoll ( func ( request * http . Request ) {
request . Form = url . Values {
"status" : { "this is a status with a poll!" } ,
"visibility" : { "public" } ,
"poll[options][]" : { "first option" , "second option" } ,
"poll[expires_in]" : { "3600" } ,
"poll[multiple]" : { "true" } ,
}
} )
}
func ( suite * StatusCreateTestSuite ) TestPostNewStatusWithPollJSON ( ) {
suite . testPostNewStatusWithPoll ( func ( request * http . Request ) {
request . Header . Set ( "content-type" , "application/json" )
request . Body = io . NopCloser ( strings . NewReader ( ` {
"status" : "this is a status with a poll!" ,
"visibility" : "public" ,
"poll" : {
"options" : [ "first option" , "second option" ] ,
"expires_in" : 3600 ,
"multiple" : true
}
} ` ) )
} )
}
2021-04-19 19:42:19 +02:00
func TestStatusCreateTestSuite ( t * testing . T ) {
suite . Run ( t , new ( StatusCreateTestSuite ) )
}