/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
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
@the_mighty_zork nice there it is:
https://social.pixie.town/users/f0x/statuses/106221628567855262/activity
`, Mentions: []*gtsmodel.Mention{ { TargetAccountURI: repliedAccount.URI, NameString: "@the_mighty_zork@localhost:8080", }, }, AccountID: replyingAccount.ID, AccountURI: replyingAccount.URI, InReplyToID: repliedStatus.ID, InReplyToURI: repliedStatus.URI, InReplyToAccountID: repliedAccount.ID, Visibility: gtsmodel.VisibilityUnlocked, ActivityStreamsType: ap.ObjectNote, Federated: true, Boostable: true, Replyable: true, Likeable: true, } // id the status based on the time it was created statusID, err := id.NewULIDFromTime(replyingStatus.CreatedAt) suite.NoError(err) replyingStatus.ID = statusID err = suite.db.PutStatus(context.Background(), replyingStatus) suite.NoError(err) err = suite.processor.ProcessFromFederator(context.Background(), messages.FromFederator{ APObjectType: ap.ObjectNote, APActivityType: ap.ActivityCreate, GTSModel: replyingStatus, ReceivingAccount: suite.testAccounts["local_account_1"], }) suite.NoError(err) // side effects should be triggered // 1. status should be in the database suite.NotEmpty(replyingStatus.ID) _, err = suite.db.GetStatusByID(context.Background(), replyingStatus.ID) suite.NoError(err) // 2. a notification should exist for the mention where := []db.Where{ { Key: "status_id", Value: replyingStatus.ID, }, } notif := >smodel.Notification{} err = suite.db.GetWhere(context.Background(), where, notif) suite.NoError(err) suite.Equal(gtsmodel.NotificationMention, notif.NotificationType) suite.Equal(replyingStatus.InReplyToAccountID, notif.TargetAccountID) suite.Equal(replyingStatus.AccountID, notif.OriginAccountID) suite.Equal(replyingStatus.ID, notif.StatusID) suite.False(notif.Read) } func (suite *FromFederatorTestSuite) TestProcessFave() { favedAccount := suite.testAccounts["local_account_1"] favedStatus := suite.testStatuses["local_account_1_status_1"] favingAccount := suite.testAccounts["remote_account_1"] stream, errWithCode := suite.processor.OpenStreamForAccount(context.Background(), favedAccount, "user") suite.NoError(errWithCode) fave := >smodel.StatusFave{ ID: "01FGKJPXFTVQPG9YSSZ95ADS7Q", CreatedAt: time.Now(), UpdatedAt: time.Now(), AccountID: favingAccount.ID, Account: favingAccount, TargetAccountID: favedAccount.ID, TargetAccount: favedAccount, StatusID: favedStatus.ID, Status: favedStatus, URI: favingAccount.URI + "/faves/aaaaaaaaaaaa", } err := suite.db.Put(context.Background(), fave) suite.NoError(err) err = suite.processor.ProcessFromFederator(context.Background(), messages.FromFederator{ APObjectType: ap.ActivityLike, APActivityType: ap.ActivityCreate, GTSModel: fave, ReceivingAccount: favedAccount, }) suite.NoError(err) // side effects should be triggered // 1. a notification should exist for the fave where := []db.Where{ { Key: "status_id", Value: favedStatus.ID, }, { Key: "origin_account_id", Value: favingAccount.ID, }, } notif := >smodel.Notification{} err = suite.db.GetWhere(context.Background(), where, notif) suite.NoError(err) suite.Equal(gtsmodel.NotificationFave, notif.NotificationType) suite.Equal(fave.TargetAccountID, notif.TargetAccountID) suite.Equal(fave.AccountID, notif.OriginAccountID) suite.Equal(fave.StatusID, notif.StatusID) suite.False(notif.Read) // 2. a notification should be streamed msg := <-stream.Messages suite.Equal("notification", msg.Event) suite.NotEmpty(msg.Payload) suite.EqualValues([]string{"user"}, msg.Stream) } // TestProcessFaveWithDifferentReceivingAccount ensures that when an account receives a fave that's for // another account in their AP inbox, a notification isn't streamed to the receiving account. // // This tests for an issue we were seeing where Misskey sends out faves to inboxes of people that don't own // the fave, but just follow the actor who received the fave. func (suite *FromFederatorTestSuite) TestProcessFaveWithDifferentReceivingAccount() { receivingAccount := suite.testAccounts["local_account_2"] favedAccount := suite.testAccounts["local_account_1"] favedStatus := suite.testStatuses["local_account_1_status_1"] favingAccount := suite.testAccounts["remote_account_1"] stream, errWithCode := suite.processor.OpenStreamForAccount(context.Background(), receivingAccount, "user") suite.NoError(errWithCode) fave := >smodel.StatusFave{ ID: "01FGKJPXFTVQPG9YSSZ95ADS7Q", CreatedAt: time.Now(), UpdatedAt: time.Now(), AccountID: favingAccount.ID, Account: favingAccount, TargetAccountID: favedAccount.ID, TargetAccount: favedAccount, StatusID: favedStatus.ID, Status: favedStatus, URI: favingAccount.URI + "/faves/aaaaaaaaaaaa", } err := suite.db.Put(context.Background(), fave) suite.NoError(err) err = suite.processor.ProcessFromFederator(context.Background(), messages.FromFederator{ APObjectType: ap.ActivityLike, APActivityType: ap.ActivityCreate, GTSModel: fave, ReceivingAccount: receivingAccount, }) suite.NoError(err) // side effects should be triggered // 1. a notification should exist for the fave where := []db.Where{ { Key: "status_id", Value: favedStatus.ID, }, { Key: "origin_account_id", Value: favingAccount.ID, }, } notif := >smodel.Notification{} err = suite.db.GetWhere(context.Background(), where, notif) suite.NoError(err) suite.Equal(gtsmodel.NotificationFave, notif.NotificationType) suite.Equal(fave.TargetAccountID, notif.TargetAccountID) suite.Equal(fave.AccountID, notif.OriginAccountID) suite.Equal(fave.StatusID, notif.StatusID) suite.False(notif.Read) // 2. no notification should be streamed to the account that received the fave message, because they weren't the target suite.Empty(stream.Messages) } func TestFromFederatorTestSuite(t *testing.T) { suite.Run(t, &FromFederatorTestSuite{}) }