2021-05-08 14:25:55 +02:00
/ *
GoToSocial
2023-01-05 12:43:00 +01:00
Copyright ( C ) 2021 - 2023 GoToSocial Authors admin @ gotosocial . org
2021-05-08 14:25:55 +02:00
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/>.
* /
package typeutils_test
import (
"context"
"encoding/json"
"fmt"
"testing"
"github.com/stretchr/testify/suite"
2021-11-13 17:29:43 +01:00
"github.com/superseriousbusiness/activity/streams"
"github.com/superseriousbusiness/activity/streams/vocab"
2021-08-10 13:32:39 +02:00
"github.com/superseriousbusiness/gotosocial/internal/ap"
2021-09-14 12:23:56 +02:00
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
2021-05-08 14:25:55 +02:00
)
type ASToInternalTestSuite struct {
2021-09-14 12:23:56 +02:00
TypeUtilsTestSuite
2021-05-08 14:25:55 +02:00
}
2023-01-25 11:12:27 +01:00
func ( suite * ASToInternalTestSuite ) jsonToType ( in string ) vocab . Type {
m := make ( map [ string ] interface { } )
if err := json . Unmarshal ( [ ] byte ( in ) , & m ) ; err != nil {
suite . FailNow ( err . Error ( ) )
}
t , err := streams . ToType ( context . Background ( ) , m )
if err != nil {
suite . FailNow ( err . Error ( ) )
}
return t
}
2021-05-08 14:25:55 +02:00
func ( suite * ASToInternalTestSuite ) TestParsePerson ( ) {
2021-09-14 12:23:56 +02:00
testPerson := suite . testPeople [ "https://unknown-instance.com/users/brand_new_person" ]
2021-05-08 14:25:55 +02:00
2022-06-11 11:01:34 +02:00
acct , err := suite . typeconverter . ASRepresentationToAccount ( context . Background ( ) , testPerson , "" , false )
2022-04-26 10:47:21 +02:00
suite . NoError ( err )
2021-05-08 14:25:55 +02:00
2021-08-23 12:46:05 +02:00
suite . Equal ( "https://unknown-instance.com/users/brand_new_person" , acct . URI )
suite . Equal ( "https://unknown-instance.com/users/brand_new_person/following" , acct . FollowingURI )
suite . Equal ( "https://unknown-instance.com/users/brand_new_person/followers" , acct . FollowersURI )
suite . Equal ( "https://unknown-instance.com/users/brand_new_person/inbox" , acct . InboxURI )
2022-09-23 21:27:35 +02:00
suite . Nil ( acct . SharedInboxURI )
2021-08-23 12:46:05 +02:00
suite . Equal ( "https://unknown-instance.com/users/brand_new_person/outbox" , acct . OutboxURI )
suite . Equal ( "https://unknown-instance.com/users/brand_new_person/collections/featured" , acct . FeaturedCollectionURI )
suite . Equal ( "brand_new_person" , acct . Username )
suite . Equal ( "Geoff Brando New Personson" , acct . DisplayName )
suite . Equal ( "hey I'm a new person, your instance hasn't seen me yet uwu" , acct . Note )
suite . Equal ( "https://unknown-instance.com/@brand_new_person" , acct . URL )
2022-08-15 12:35:05 +02:00
suite . True ( * acct . Discoverable )
2021-08-23 12:46:05 +02:00
suite . Equal ( "https://unknown-instance.com/users/brand_new_person#main-key" , acct . PublicKeyURI )
2022-08-15 12:35:05 +02:00
suite . False ( * acct . Locked )
2021-05-08 14:25:55 +02:00
}
2022-09-23 21:27:35 +02:00
func ( suite * ASToInternalTestSuite ) TestParsePersonWithSharedInbox ( ) {
testPerson := suite . testPeople [ "https://turnip.farm/users/turniplover6969" ]
acct , err := suite . typeconverter . ASRepresentationToAccount ( context . Background ( ) , testPerson , "" , false )
suite . NoError ( err )
suite . Equal ( "https://turnip.farm/users/turniplover6969" , acct . URI )
suite . Equal ( "https://turnip.farm/users/turniplover6969/following" , acct . FollowingURI )
suite . Equal ( "https://turnip.farm/users/turniplover6969/followers" , acct . FollowersURI )
suite . Equal ( "https://turnip.farm/users/turniplover6969/inbox" , acct . InboxURI )
suite . Equal ( "https://turnip.farm/sharedInbox" , * acct . SharedInboxURI )
suite . Equal ( "https://turnip.farm/users/turniplover6969/outbox" , acct . OutboxURI )
suite . Equal ( "https://turnip.farm/users/turniplover6969/collections/featured" , acct . FeaturedCollectionURI )
suite . Equal ( "turniplover6969" , acct . Username )
suite . Equal ( "Turnip Lover 6969" , acct . DisplayName )
suite . Equal ( "I just think they're neat" , acct . Note )
suite . Equal ( "https://turnip.farm/@turniplover6969" , acct . URL )
suite . True ( * acct . Discoverable )
suite . Equal ( "https://turnip.farm/users/turniplover6969#main-key" , acct . PublicKeyURI )
suite . False ( * acct . Locked )
}
2022-04-26 10:47:21 +02:00
func ( suite * ASToInternalTestSuite ) TestParsePublicStatus ( ) {
2023-01-25 11:12:27 +01:00
t := suite . jsonToType ( publicStatusActivityJson )
2022-04-26 10:47:21 +02:00
rep , ok := t . ( ap . Statusable )
2023-01-25 11:12:27 +01:00
if ! ok {
suite . FailNow ( "type not coercible" )
}
2022-04-26 10:47:21 +02:00
status , err := suite . typeconverter . ASStatusToStatus ( context . Background ( ) , rep )
suite . NoError ( err )
suite . Equal ( "reading: Punishment and Reward in the Corporate University" , status . ContentWarning )
suite . Equal ( ` <p>> So we have to examine critical thinking as a signifier, dynamic and ambiguous. It has a normative definition, a tacit definition, and an ideal definition. One of the hallmarks of graduate training is learning to comprehend those definitions and applying the correct one as needed for professional success.</p> ` , status . Content )
}
2022-05-23 17:10:48 +02:00
func ( suite * ASToInternalTestSuite ) TestParsePublicStatusNoURL ( ) {
2023-01-25 11:12:27 +01:00
t := suite . jsonToType ( publicStatusActivityJsonNoURL )
2022-05-23 17:10:48 +02:00
rep , ok := t . ( ap . Statusable )
2023-01-25 11:12:27 +01:00
if ! ok {
suite . FailNow ( "type not coercible" )
}
2022-05-23 17:10:48 +02:00
status , err := suite . typeconverter . ASStatusToStatus ( context . Background ( ) , rep )
suite . NoError ( err )
suite . Equal ( "reading: Punishment and Reward in the Corporate University" , status . ContentWarning )
suite . Equal ( ` <p>> So we have to examine critical thinking as a signifier, dynamic and ambiguous. It has a normative definition, a tacit definition, and an ideal definition. One of the hallmarks of graduate training is learning to comprehend those definitions and applying the correct one as needed for professional success.</p> ` , status . Content )
// on statuses with no URL in them (like ones we get from pleroma sometimes) we should use the AP URI of the status as URL
suite . Equal ( "http://fossbros-anonymous.io/users/foss_satan/statuses/108138763199405167" , status . URL )
}
2021-05-08 14:25:55 +02:00
func ( suite * ASToInternalTestSuite ) TestParseGargron ( ) {
2023-01-25 11:12:27 +01:00
t := suite . jsonToType ( gargronAsActivityJson )
2021-08-10 13:32:39 +02:00
rep , ok := t . ( ap . Accountable )
2023-01-25 11:12:27 +01:00
if ! ok {
suite . FailNow ( "type not coercible" )
}
2021-05-08 14:25:55 +02:00
2022-06-11 11:01:34 +02:00
acct , err := suite . typeconverter . ASRepresentationToAccount ( context . Background ( ) , rep , "" , false )
2022-04-26 10:47:21 +02:00
suite . NoError ( err )
2022-09-23 21:27:35 +02:00
suite . Equal ( "https://mastodon.social/inbox" , * acct . SharedInboxURI )
2021-05-08 14:25:55 +02:00
}
2021-09-14 12:23:56 +02:00
func ( suite * ASToInternalTestSuite ) TestParseReplyWithMention ( ) {
2023-01-25 11:12:27 +01:00
t := suite . jsonToType ( statusWithMentionsActivityJson )
2021-09-14 12:23:56 +02:00
create , ok := t . ( vocab . ActivityStreamsCreate )
2023-01-25 11:12:27 +01:00
if ! ok {
suite . FailNow ( "type not coercible" )
}
2021-09-14 12:23:56 +02:00
object := create . GetActivityStreamsObject ( )
var status * gtsmodel . Status
for i := object . Begin ( ) ; i != nil ; i = i . Next ( ) {
statusable := i . GetActivityStreamsNote ( )
s , err := suite . typeconverter . ASStatusToStatus ( context . Background ( ) , statusable )
suite . NoError ( err )
status = s
break
}
suite . NotNil ( status )
postingAccount := suite . testAccounts [ "remote_account_1" ]
inReplyToAccount := suite . testAccounts [ "local_account_1" ]
inReplyToStatus := suite . testStatuses [ "local_account_1_status_1" ]
suite . Equal ( "http://fossbros-anonymous.io/users/foss_satan/statuses/106221634728637552" , status . URI )
suite . Equal ( postingAccount . ID , status . AccountID )
suite . Equal ( postingAccount . URI , status . AccountURI )
suite . Equal ( inReplyToAccount . ID , status . InReplyToAccountID )
suite . Equal ( inReplyToStatus . ID , status . InReplyToID )
suite . Equal ( inReplyToStatus . URI , status . InReplyToURI )
2022-08-15 12:35:05 +02:00
suite . True ( * status . Federated )
suite . True ( * status . Boostable )
suite . True ( * status . Replyable )
suite . True ( * status . Likeable )
2021-09-14 12:23:56 +02:00
suite . Equal ( ` <p><span class="h-card"><a href="http://localhost:8080/@the_mighty_zork" class="u-url mention">@<span>the_mighty_zork</span></a></span> nice there it is:</p><p><a href="http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY/activity" rel="nofollow noopener noreferrer" target="_blank"><span class="invisible">https://</span><span class="ellipsis">social.pixie.town/users/f0x/st</span><span class="invisible">atuses/106221628567855262/activity</span></a></p> ` , status . Content )
suite . Len ( status . Mentions , 1 )
m1 := status . Mentions [ 0 ]
suite . Equal ( inReplyToAccount . URI , m1 . TargetAccountURI )
suite . Equal ( "@the_mighty_zork@localhost:8080" , m1 . NameString )
suite . Equal ( gtsmodel . VisibilityUnlocked , status . Visibility )
2021-05-08 14:25:55 +02:00
}
2022-05-27 16:35:35 +02:00
func ( suite * ASToInternalTestSuite ) TestParseOwncastService ( ) {
2023-01-25 11:12:27 +01:00
t := suite . jsonToType ( owncastService )
2022-05-27 16:35:35 +02:00
rep , ok := t . ( ap . Accountable )
2023-01-25 11:12:27 +01:00
if ! ok {
suite . FailNow ( "type not coercible" )
}
2022-05-27 16:35:35 +02:00
2022-06-11 11:01:34 +02:00
acct , err := suite . typeconverter . ASRepresentationToAccount ( context . Background ( ) , rep , "" , false )
2022-05-27 16:35:35 +02:00
suite . NoError ( err )
suite . Equal ( "rgh" , acct . Username )
suite . Equal ( "owncast.example.org" , acct . Domain )
suite . Equal ( "https://owncast.example.org/logo/external" , acct . AvatarRemoteURL )
suite . Equal ( "https://owncast.example.org/logo/external" , acct . HeaderRemoteURL )
suite . Equal ( "Rob's Owncast Server" , acct . DisplayName )
suite . Equal ( "linux audio stuff " , acct . Note )
2022-08-15 12:35:05 +02:00
suite . True ( * acct . Bot )
suite . False ( * acct . Locked )
suite . True ( * acct . Discoverable )
2022-05-27 16:35:35 +02:00
suite . Equal ( "https://owncast.example.org/federation/user/rgh" , acct . URI )
suite . Equal ( "https://owncast.example.org/federation/user/rgh" , acct . URL )
suite . Equal ( "https://owncast.example.org/federation/user/rgh/inbox" , acct . InboxURI )
suite . Equal ( "https://owncast.example.org/federation/user/rgh/outbox" , acct . OutboxURI )
suite . Equal ( "https://owncast.example.org/federation/user/rgh/followers" , acct . FollowersURI )
suite . Equal ( "Service" , acct . ActorType )
suite . Equal ( "https://owncast.example.org/federation/user/rgh#main-key" , acct . PublicKeyURI )
acct . ID = "01G42D57DTCJQE8XT9KD4K88RK"
apiAcct , err := suite . typeconverter . AccountToAPIAccountPublic ( context . Background ( ) , acct )
suite . NoError ( err )
suite . NotNil ( apiAcct )
b , err := json . Marshal ( apiAcct )
suite . NoError ( err )
fmt . Printf ( "\n\n\n%s\n\n\n" , string ( b ) )
}
2023-01-25 11:12:27 +01:00
func ( suite * ASToInternalTestSuite ) TestParseFlag1 ( ) {
reportedAccount := suite . testAccounts [ "local_account_1" ]
reportingAccount := suite . testAccounts [ "remote_account_1" ]
reportedStatus := suite . testStatuses [ "local_account_1_status_1" ]
raw := ` {
"@context" : "https://www.w3.org/ns/activitystreams" ,
"actor" : "` + reportingAccount.URI + `" ,
"content" : "Note: ` + reportedStatus.URL + `\n-----\nban this sick filth ⛔" ,
"id" : "http://fossbros-anonymous.io/db22128d-884e-4358-9935-6a7c3940535d" ,
"object" : "` + reportedAccount.URI + `" ,
"type" : "Flag"
} `
t := suite . jsonToType ( raw )
asFlag , ok := t . ( ap . Flaggable )
if ! ok {
suite . FailNow ( "type not coercible" )
}
report , err := suite . typeconverter . ASFlagToReport ( context . Background ( ) , asFlag )
if err != nil {
suite . FailNow ( err . Error ( ) )
}
suite . Equal ( report . AccountID , reportingAccount . ID )
suite . Equal ( report . TargetAccountID , reportedAccount . ID )
suite . Len ( report . StatusIDs , 1 )
suite . Len ( report . Statuses , 1 )
suite . Equal ( report . Statuses [ 0 ] . ID , reportedStatus . ID )
suite . Equal ( report . Comment , "Note: " + reportedStatus . URL + "\n-----\nban this sick filth ⛔" )
}
func ( suite * ASToInternalTestSuite ) TestParseFlag2 ( ) {
reportedAccount := suite . testAccounts [ "local_account_1" ]
reportingAccount := suite . testAccounts [ "remote_account_1" ]
// report a status that doesn't exist
reportedStatusURL := "http://localhost:8080/@the_mighty_zork/01GQHR6MCQSTCP85ZG4A0VR316"
raw := ` {
"@context" : "https://www.w3.org/ns/activitystreams" ,
"actor" : "` + reportingAccount.URI + `" ,
"content" : "Note: ` + reportedStatusURL + `\n-----\nban this sick filth ⛔" ,
"id" : "http://fossbros-anonymous.io/db22128d-884e-4358-9935-6a7c3940535d" ,
"object" : "` + reportedAccount.URI + `" ,
"type" : "Flag"
} `
t := suite . jsonToType ( raw )
asFlag , ok := t . ( ap . Flaggable )
if ! ok {
suite . FailNow ( "type not coercible" )
}
report , err := suite . typeconverter . ASFlagToReport ( context . Background ( ) , asFlag )
if err != nil {
suite . FailNow ( err . Error ( ) )
}
suite . Equal ( report . AccountID , reportingAccount . ID )
suite . Equal ( report . TargetAccountID , reportedAccount . ID )
// nonexistent status should just be skipped, it'll still be in the content though
suite . Len ( report . StatusIDs , 0 )
suite . Len ( report . Statuses , 0 )
suite . Equal ( report . Comment , "Note: " + reportedStatusURL + "\n-----\nban this sick filth ⛔" )
}
func ( suite * ASToInternalTestSuite ) TestParseFlag3 ( ) {
// flag an account that doesn't exist
reportedAccountURI := "http://localhost:8080/users/mr_e_man"
reportingAccount := suite . testAccounts [ "remote_account_1" ]
raw := ` {
"@context" : "https://www.w3.org/ns/activitystreams" ,
"actor" : "` + reportingAccount.URI + `" ,
"content" : "ban this sick filth ⛔" ,
"id" : "http://fossbros-anonymous.io/db22128d-884e-4358-9935-6a7c3940535d" ,
"object" : "` + reportedAccountURI + `" ,
"type" : "Flag"
} `
t := suite . jsonToType ( raw )
asFlag , ok := t . ( ap . Flaggable )
if ! ok {
suite . FailNow ( "type not coercible" )
}
report , err := suite . typeconverter . ASFlagToReport ( context . Background ( ) , asFlag )
suite . Nil ( report )
suite . EqualError ( err , "ASFlagToReport: account with uri http://localhost:8080/users/mr_e_man could not be found in the db" )
}
func ( suite * ASToInternalTestSuite ) TestParseFlag4 ( ) {
// flag an account from another instance
reportingAccount := suite . testAccounts [ "remote_account_1" ]
reportedAccountURI := suite . testAccounts [ "remote_account_2" ] . URI
raw := ` {
"@context" : "https://www.w3.org/ns/activitystreams" ,
"actor" : "` + reportingAccount.URI + `" ,
"content" : "ban this sick filth ⛔" ,
"id" : "http://fossbros-anonymous.io/db22128d-884e-4358-9935-6a7c3940535d" ,
"object" : "` + reportedAccountURI + `" ,
"type" : "Flag"
} `
t := suite . jsonToType ( raw )
asFlag , ok := t . ( ap . Flaggable )
if ! ok {
suite . FailNow ( "type not coercible" )
}
report , err := suite . typeconverter . ASFlagToReport ( context . Background ( ) , asFlag )
suite . Nil ( report )
suite . EqualError ( err , "ASFlagToReport: flaggable objects contained no recognizable target account uri" )
}
func ( suite * ASToInternalTestSuite ) TestParseFlag5 ( ) {
reportedAccount := suite . testAccounts [ "local_account_1" ]
reportingAccount := suite . testAccounts [ "remote_account_1" ]
reportedStatus := suite . testStatuses [ "local_account_1_status_1" ]
raw := ` {
"@context" : "https://www.w3.org/ns/activitystreams" ,
"actor" : "` + reportingAccount.URI + `" ,
"content" : "misinformation" ,
"id" : "http://fossbros-anonymous.io/db22128d-884e-4358-9935-6a7c3940535d" ,
"object" : [
"` + reportedAccount.URI + `" ,
"` + reportedStatus.URI + `"
] ,
"type" : "Flag"
} `
t := suite . jsonToType ( raw )
asFlag , ok := t . ( ap . Flaggable )
if ! ok {
suite . FailNow ( "type not coercible" )
}
report , err := suite . typeconverter . ASFlagToReport ( context . Background ( ) , asFlag )
if err != nil {
suite . FailNow ( err . Error ( ) )
}
suite . Equal ( report . AccountID , reportingAccount . ID )
suite . Equal ( report . TargetAccountID , reportedAccount . ID )
suite . Len ( report . StatusIDs , 1 )
suite . Len ( report . Statuses , 1 )
suite . Equal ( report . Statuses [ 0 ] . ID , reportedStatus . ID )
suite . Equal ( report . Comment , "misinformation" )
}
func ( suite * ASToInternalTestSuite ) TestParseFlag6 ( ) {
reportedAccount := suite . testAccounts [ "local_account_1" ]
reportingAccount := suite . testAccounts [ "remote_account_1" ]
// flag a status that belongs to another account
reportedStatus := suite . testStatuses [ "local_account_2_status_1" ]
raw := ` {
"@context" : "https://www.w3.org/ns/activitystreams" ,
"actor" : "` + reportingAccount.URI + `" ,
"content" : "misinformation" ,
"id" : "http://fossbros-anonymous.io/db22128d-884e-4358-9935-6a7c3940535d" ,
"object" : [
"` + reportedAccount.URI + `" ,
"` + reportedStatus.URI + `"
] ,
"type" : "Flag"
} `
t := suite . jsonToType ( raw )
asFlag , ok := t . ( ap . Flaggable )
if ! ok {
suite . FailNow ( "type not coercible" )
}
report , err := suite . typeconverter . ASFlagToReport ( context . Background ( ) , asFlag )
if err != nil {
suite . FailNow ( err . Error ( ) )
}
suite . Equal ( report . AccountID , reportingAccount . ID )
suite . Equal ( report . TargetAccountID , reportedAccount . ID )
suite . Len ( report . StatusIDs , 0 )
suite . Len ( report . Statuses , 0 )
suite . Equal ( report . Comment , "misinformation" )
}
2021-05-08 14:25:55 +02:00
func TestASToInternalTestSuite ( t * testing . T ) {
suite . Run ( t , new ( ASToInternalTestSuite ) )
}