| 
									
										
										
										
											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-09-04 13:29:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | package workers_test | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2024-04-11 10:45:35 +01:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/suite" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/ap" | 
					
						
							| 
									
										
										
										
											2023-01-02 13:10:50 +01:00
										 |  |  | 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/db" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/messages" | 
					
						
							| 
									
										
										
										
											2021-11-22 19:03:21 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/stream" | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/util" | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/testrig" | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | type FromFediAPITestSuite struct { | 
					
						
							|  |  |  | 	WorkersTestSuite | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // remote_account_1 boosts the first status of local_account_1 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | func (suite *FromFediAPITestSuite) TestProcessFederationAnnounce() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-24 13:27:42 +02:00
										 |  |  | 	boostedStatus := >smodel.Status{} | 
					
						
							|  |  |  | 	*boostedStatus = *suite.testStatuses["local_account_1_status_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	boostingAccount := >smodel.Account{} | 
					
						
							|  |  |  | 	*boostingAccount = *suite.testAccounts["remote_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 	announceStatus := >smodel.Status{} | 
					
						
							|  |  |  | 	announceStatus.URI = "https://example.org/some-announce-uri" | 
					
						
							| 
									
										
										
										
											2023-12-01 15:27:15 +01:00
										 |  |  | 	announceStatus.BoostOfURI = boostedStatus.URI | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 	announceStatus.CreatedAt = time.Now() | 
					
						
							|  |  |  | 	announceStatus.UpdatedAt = time.Now() | 
					
						
							|  |  |  | 	announceStatus.AccountID = boostingAccount.ID | 
					
						
							|  |  |  | 	announceStatus.AccountURI = boostingAccount.URI | 
					
						
							|  |  |  | 	announceStatus.Account = boostingAccount | 
					
						
							|  |  |  | 	announceStatus.Visibility = boostedStatus.Visibility | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err := testStructs.Processor.Workers().ProcessFromFediAPI(context.Background(), &messages.FromFediAPI{ | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		APObjectType:   ap.ActivityAnnounce, | 
					
						
							|  |  |  | 		APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 		GTSModel:       announceStatus, | 
					
						
							|  |  |  | 		Receiving:      suite.testAccounts["local_account_1"], | 
					
						
							|  |  |  | 		Requesting:     boostingAccount, | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2024-07-24 13:27:42 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-24 13:27:42 +02:00
										 |  |  | 	// Wait for side effects to trigger: | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 	// 1. status should have an ID, and be in the database | 
					
						
							| 
									
										
										
										
											2024-07-24 13:27:42 +02:00
										 |  |  | 	if !testrig.WaitFor(func() bool { | 
					
						
							|  |  |  | 		if announceStatus.ID == "" { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		_, err = testStructs.State.DB.GetStatusByID( | 
					
						
							|  |  |  | 			context.Background(), | 
					
						
							|  |  |  | 			announceStatus.ID, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		return err == nil | 
					
						
							|  |  |  | 	}) { | 
					
						
							|  |  |  | 		suite.FailNow("timed out waiting for announce to be in the database") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// 2. a notification should exist for the announce | 
					
						
							|  |  |  | 	where := []db.Where{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Key:   "status_id", | 
					
						
							|  |  |  | 			Value: announceStatus.ID, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	notif := >smodel.Notification{} | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err = testStructs.State.DB.GetWhere(context.Background(), where, notif) | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 	suite.Equal(gtsmodel.NotificationReblog, notif.NotificationType) | 
					
						
							|  |  |  | 	suite.Equal(boostedStatus.AccountID, notif.TargetAccountID) | 
					
						
							|  |  |  | 	suite.Equal(announceStatus.AccountID, notif.OriginAccountID) | 
					
						
							|  |  |  | 	suite.Equal(announceStatus.ID, notif.StatusID) | 
					
						
							| 
									
										
										
										
											2022-08-15 12:35:05 +02:00
										 |  |  | 	suite.False(*notif.Read) | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-24 13:27:42 +02:00
										 |  |  | func (suite *FromFediAPITestSuite) TestProcessReplyMention() { | 
					
						
							|  |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	repliedAccount := >smodel.Account{} | 
					
						
							|  |  |  | 	*repliedAccount = *suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	repliedStatus := >smodel.Status{} | 
					
						
							|  |  |  | 	*repliedStatus = *suite.testStatuses["local_account_1_status_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	replyingAccount := >smodel.Account{} | 
					
						
							|  |  |  | 	*replyingAccount = *suite.testAccounts["remote_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the replyingAccount's last fetched_at | 
					
						
							|  |  |  | 	// date to something recent so no refresh is attempted, | 
					
						
							|  |  |  | 	// and ensure it isn't a suspended account. | 
					
						
							|  |  |  | 	replyingAccount.FetchedAt = time.Now() | 
					
						
							|  |  |  | 	replyingAccount.SuspendedAt = time.Time{} | 
					
						
							|  |  |  | 	replyingAccount.SuspensionOrigin = "" | 
					
						
							|  |  |  | 	err := testStructs.State.DB.UpdateAccount(context.Background(), | 
					
						
							|  |  |  | 		replyingAccount, | 
					
						
							|  |  |  | 		"fetched_at", | 
					
						
							|  |  |  | 		"suspended_at", | 
					
						
							|  |  |  | 		"suspension_origin", | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Get replying statusable to use from remote test statuses. | 
					
						
							|  |  |  | 	const replyingURI = "http://fossbros-anonymous.io/users/foss_satan/statuses/106221634728637552" | 
					
						
							|  |  |  | 	replyingStatusable := testrig.NewTestFediStatuses()[replyingURI] | 
					
						
							|  |  |  | 	ap.AppendInReplyTo(replyingStatusable, testrig.URLMustParse(repliedStatus.URI)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Open a websocket stream to later test the streamed status reply. | 
					
						
							|  |  |  | 	wssStream, errWithCode := testStructs.Processor.Stream().Open(context.Background(), repliedAccount, stream.TimelineHome) | 
					
						
							|  |  |  | 	suite.NoError(errWithCode) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Send the replied status off to the fedi worker to be further processed. | 
					
						
							|  |  |  | 	err = testStructs.Processor.Workers().ProcessFromFediAPI(context.Background(), &messages.FromFediAPI{ | 
					
						
							|  |  |  | 		APObjectType:   ap.ObjectNote, | 
					
						
							|  |  |  | 		APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 		APObject:       replyingStatusable, | 
					
						
							|  |  |  | 		Receiving:      repliedAccount, | 
					
						
							|  |  |  | 		Requesting:     replyingAccount, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Wait for side effects to trigger: | 
					
						
							|  |  |  | 	// 1. status should be in the database | 
					
						
							|  |  |  | 	var replyingStatus *gtsmodel.Status | 
					
						
							|  |  |  | 	if !testrig.WaitFor(func() bool { | 
					
						
							|  |  |  | 		replyingStatus, err = testStructs.State.DB.GetStatusByURI(context.Background(), replyingURI) | 
					
						
							|  |  |  | 		return err == nil | 
					
						
							|  |  |  | 	}) { | 
					
						
							|  |  |  | 		suite.FailNow("timed out waiting for replying status to be in the database") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// 2. a notification should exist for the mention | 
					
						
							|  |  |  | 	var notif gtsmodel.Notification | 
					
						
							|  |  |  | 	err = testStructs.State.DB.GetWhere(context.Background(), []db.Where{ | 
					
						
							|  |  |  | 		{Key: "status_id", Value: replyingStatus.ID}, | 
					
						
							|  |  |  | 	}, ¬if) | 
					
						
							|  |  |  | 	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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx, _ := context.WithTimeout(context.Background(), time.Second*5) | 
					
						
							|  |  |  | 	msg, ok := wssStream.Recv(ctx) | 
					
						
							|  |  |  | 	suite.True(ok) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	suite.Equal(stream.EventTypeNotification, msg.Event) | 
					
						
							|  |  |  | 	suite.NotEmpty(msg.Payload) | 
					
						
							|  |  |  | 	suite.EqualValues([]string{stream.TimelineHome}, msg.Stream) | 
					
						
							|  |  |  | 	notifStreamed := &apimodel.Notification{} | 
					
						
							|  |  |  | 	err = json.Unmarshal([]byte(msg.Payload), notifStreamed) | 
					
						
							|  |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 	suite.Equal("mention", notifStreamed.Type) | 
					
						
							|  |  |  | 	suite.Equal(replyingAccount.ID, notifStreamed.Account.ID) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-09-14 12:23:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | func (suite *FromFediAPITestSuite) TestProcessFave() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	favedAccount := suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 	favedStatus := suite.testStatuses["local_account_1_status_1"] | 
					
						
							|  |  |  | 	favingAccount := suite.testAccounts["remote_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	wssStream, errWithCode := testStructs.Processor.Stream().Open(context.Background(), favedAccount, stream.TimelineNotifications) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	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", | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err := testStructs.State.DB.Put(context.Background(), fave) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err = testStructs.Processor.Workers().ProcessFromFediAPI(context.Background(), &messages.FromFediAPI{ | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		APObjectType:   ap.ActivityLike, | 
					
						
							|  |  |  | 		APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 		GTSModel:       fave, | 
					
						
							|  |  |  | 		Receiving:      favedAccount, | 
					
						
							|  |  |  | 		Requesting:     favingAccount, | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 	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{} | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err = testStructs.State.DB.GetWhere(context.Background(), where, notif) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	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) | 
					
						
							| 
									
										
										
										
											2022-08-15 12:35:05 +02:00
										 |  |  | 	suite.False(*notif.Read) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 18:07:49 +00:00
										 |  |  | 	ctx, _ := context.WithTimeout(context.Background(), time.Second*5) | 
					
						
							|  |  |  | 	msg, ok := wssStream.Recv(ctx) | 
					
						
							|  |  |  | 	suite.True(ok) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-22 19:03:21 +01:00
										 |  |  | 	suite.Equal(stream.EventTypeNotification, msg.Event) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	suite.NotEmpty(msg.Payload) | 
					
						
							| 
									
										
										
										
											2021-11-22 19:03:21 +01:00
										 |  |  | 	suite.EqualValues([]string{stream.TimelineNotifications}, msg.Stream) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 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. | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | func (suite *FromFediAPITestSuite) TestProcessFaveWithDifferentReceivingAccount() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	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"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	wssStream, errWithCode := testStructs.Processor.Stream().Open(context.Background(), receivingAccount, stream.TimelineHome) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	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", | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err := testStructs.State.DB.Put(context.Background(), fave) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err = testStructs.Processor.Workers().ProcessFromFediAPI(context.Background(), &messages.FromFediAPI{ | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		APObjectType:   ap.ActivityLike, | 
					
						
							|  |  |  | 		APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 		GTSModel:       fave, | 
					
						
							|  |  |  | 		Receiving:      receivingAccount, | 
					
						
							|  |  |  | 		Requesting:     favingAccount, | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 	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{} | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err = testStructs.State.DB.GetWhere(context.Background(), where, notif) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 	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) | 
					
						
							| 
									
										
										
										
											2022-08-15 12:35:05 +02:00
										 |  |  | 	suite.False(*notif.Read) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// 2. no notification should be streamed to the account that received the fave message, because they weren't the target | 
					
						
							| 
									
										
										
										
											2024-02-20 18:07:49 +00:00
										 |  |  | 	ctx, _ := context.WithTimeout(context.Background(), time.Second*5) | 
					
						
							|  |  |  | 	_, ok := wssStream.Recv(ctx) | 
					
						
							|  |  |  | 	suite.False(ok) | 
					
						
							| 
									
										
										
										
											2021-09-27 17:42:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | func (suite *FromFediAPITestSuite) TestProcessAccountDelete() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-24 13:27:42 +02:00
										 |  |  | 	deletedAccount := >smodel.Account{} | 
					
						
							|  |  |  | 	*deletedAccount = *suite.testAccounts["remote_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	receivingAccount := >smodel.Account{} | 
					
						
							|  |  |  | 	*receivingAccount = *suite.testAccounts["local_account_1"] | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// before doing the delete.... | 
					
						
							|  |  |  | 	// make local_account_1 and remote_account_1 into mufos | 
					
						
							|  |  |  | 	zorkFollowSatan := >smodel.Follow{ | 
					
						
							|  |  |  | 		ID:              "01FGRY72ASHBSET64353DPHK9T", | 
					
						
							|  |  |  | 		CreatedAt:       time.Now().Add(-1 * time.Hour), | 
					
						
							|  |  |  | 		UpdatedAt:       time.Now().Add(-1 * time.Hour), | 
					
						
							|  |  |  | 		AccountID:       deletedAccount.ID, | 
					
						
							|  |  |  | 		TargetAccountID: receivingAccount.ID, | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 		ShowReblogs:     util.Ptr(true), | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 		URI:             fmt.Sprintf("%s/follows/01FGRY72ASHBSET64353DPHK9T", deletedAccount.URI), | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 		Notify:          util.Ptr(false), | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err := testStructs.State.DB.Put(ctx, zorkFollowSatan) | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	satanFollowZork := >smodel.Follow{ | 
					
						
							|  |  |  | 		ID:              "01FGRYAVAWWPP926J175QGM0WV", | 
					
						
							|  |  |  | 		CreatedAt:       time.Now().Add(-1 * time.Hour), | 
					
						
							|  |  |  | 		UpdatedAt:       time.Now().Add(-1 * time.Hour), | 
					
						
							|  |  |  | 		AccountID:       receivingAccount.ID, | 
					
						
							|  |  |  | 		TargetAccountID: deletedAccount.ID, | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 		ShowReblogs:     util.Ptr(true), | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 		URI:             fmt.Sprintf("%s/follows/01FGRYAVAWWPP926J175QGM0WV", receivingAccount.URI), | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 		Notify:          util.Ptr(false), | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err = testStructs.State.DB.Put(ctx, satanFollowZork) | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// now they are mufos! | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err = testStructs.Processor.Workers().ProcessFromFediAPI(ctx, &messages.FromFediAPI{ | 
					
						
							| 
									
										
										
										
											2024-06-06 15:43:25 +02:00
										 |  |  | 		APObjectType:   ap.ActorPerson, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		APActivityType: ap.ActivityDelete, | 
					
						
							|  |  |  | 		GTSModel:       deletedAccount, | 
					
						
							|  |  |  | 		Receiving:      receivingAccount, | 
					
						
							|  |  |  | 		Requesting:     deletedAccount, | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// local account 2 blocked foss_satan, that block should be gone now | 
					
						
							|  |  |  | 	testBlock := suite.testBlocks["local_account_2_block_remote_account_1"] | 
					
						
							|  |  |  | 	dbBlock := >smodel.Block{} | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err = testStructs.State.DB.GetByID(ctx, testBlock.ID, dbBlock) | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	suite.ErrorIs(err, db.ErrNoEntries) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// the mufos should be gone now too | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	satanFollowsZork, err := testStructs.State.DB.IsFollowing(ctx, deletedAccount.ID, receivingAccount.ID) | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 	suite.False(satanFollowsZork) | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	zorkFollowsSatan, err := testStructs.State.DB.IsFollowing(ctx, receivingAccount.ID, deletedAccount.ID) | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 	suite.False(zorkFollowsSatan) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// no statuses from foss satan should be left in the database | 
					
						
							| 
									
										
										
										
											2022-09-21 19:55:52 +02:00
										 |  |  | 	if !testrig.WaitFor(func() bool { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		s, err := testStructs.State.DB.GetAccountStatuses(ctx, deletedAccount.ID, 0, false, false, "", "", false, false) | 
					
						
							| 
									
										
										
										
											2022-10-03 10:46:11 +02:00
										 |  |  | 		return s == nil && err == db.ErrNoEntries | 
					
						
							| 
									
										
										
										
											2022-09-21 19:55:52 +02:00
										 |  |  | 	}) { | 
					
						
							|  |  |  | 		suite.FailNow("timeout waiting for statuses to be deleted") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-08 14:32:17 +00:00
										 |  |  | 	var dbAccount *gtsmodel.Account | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// account data should be zeroed. | 
					
						
							|  |  |  | 	if !testrig.WaitFor(func() bool { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		dbAccount, err = testStructs.State.DB.GetAccountByID(ctx, deletedAccount.ID) | 
					
						
							| 
									
										
										
										
											2023-11-08 14:32:17 +00:00
										 |  |  | 		return err == nil && dbAccount.DisplayName == "" | 
					
						
							|  |  |  | 	}) { | 
					
						
							|  |  |  | 		suite.FailNow("timeout waiting for statuses to be deleted") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	suite.Empty(dbAccount.Note) | 
					
						
							|  |  |  | 	suite.Empty(dbAccount.DisplayName) | 
					
						
							|  |  |  | 	suite.Empty(dbAccount.AvatarMediaAttachmentID) | 
					
						
							|  |  |  | 	suite.Empty(dbAccount.AvatarRemoteURL) | 
					
						
							|  |  |  | 	suite.Empty(dbAccount.HeaderMediaAttachmentID) | 
					
						
							|  |  |  | 	suite.Empty(dbAccount.HeaderRemoteURL) | 
					
						
							|  |  |  | 	suite.Empty(dbAccount.Fields) | 
					
						
							| 
									
										
										
										
											2022-08-15 12:35:05 +02:00
										 |  |  | 	suite.False(*dbAccount.Discoverable) | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 	suite.WithinDuration(time.Now(), dbAccount.SuspendedAt, 30*time.Second) | 
					
						
							|  |  |  | 	suite.Equal(dbAccount.ID, dbAccount.SuspensionOrigin) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | func (suite *FromFediAPITestSuite) TestProcessFollowRequestLocked() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	originAccount := suite.testAccounts["remote_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// target is a locked account | 
					
						
							|  |  |  | 	targetAccount := suite.testAccounts["local_account_2"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	wssStream, errWithCode := testStructs.Processor.Stream().Open(context.Background(), targetAccount, stream.TimelineHome) | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	suite.NoError(errWithCode) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// put the follow request in the database as though it had passed through the federating db already | 
					
						
							|  |  |  | 	satanFollowRequestTurtle := >smodel.FollowRequest{ | 
					
						
							|  |  |  | 		ID:              "01FGRYAVAWWPP926J175QGM0WV", | 
					
						
							|  |  |  | 		CreatedAt:       time.Now(), | 
					
						
							|  |  |  | 		UpdatedAt:       time.Now(), | 
					
						
							|  |  |  | 		AccountID:       originAccount.ID, | 
					
						
							|  |  |  | 		Account:         originAccount, | 
					
						
							|  |  |  | 		TargetAccountID: targetAccount.ID, | 
					
						
							|  |  |  | 		TargetAccount:   targetAccount, | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 		ShowReblogs:     util.Ptr(true), | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 		URI:             fmt.Sprintf("%s/follows/01FGRYAVAWWPP926J175QGM0WV", originAccount.URI), | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 		Notify:          util.Ptr(false), | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err := testStructs.State.DB.Put(ctx, satanFollowRequestTurtle) | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err = testStructs.Processor.Workers().ProcessFromFediAPI(ctx, &messages.FromFediAPI{ | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		APObjectType:   ap.ActivityFollow, | 
					
						
							|  |  |  | 		APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 		GTSModel:       satanFollowRequestTurtle, | 
					
						
							|  |  |  | 		Receiving:      targetAccount, | 
					
						
							|  |  |  | 		Requesting:     originAccount, | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 18:07:49 +00:00
										 |  |  | 	ctx, _ = context.WithTimeout(ctx, time.Second*5) | 
					
						
							|  |  |  | 	msg, ok := wssStream.Recv(context.Background()) | 
					
						
							|  |  |  | 	suite.True(ok) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-22 19:03:21 +01:00
										 |  |  | 	suite.Equal(stream.EventTypeNotification, msg.Event) | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	suite.NotEmpty(msg.Payload) | 
					
						
							| 
									
										
										
										
											2021-11-22 19:03:21 +01:00
										 |  |  | 	suite.EqualValues([]string{stream.TimelineHome}, msg.Stream) | 
					
						
							| 
									
										
										
										
											2023-01-02 13:10:50 +01:00
										 |  |  | 	notif := &apimodel.Notification{} | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	err = json.Unmarshal([]byte(msg.Payload), notif) | 
					
						
							|  |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 	suite.Equal("follow_request", notif.Type) | 
					
						
							|  |  |  | 	suite.Equal(originAccount.ID, notif.Account.ID) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// no messages should have been sent out, since we didn't need to federate an accept | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	suite.Empty(testStructs.HTTPClient.SentMessages) | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | func (suite *FromFediAPITestSuite) TestProcessFollowRequestUnlocked() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	originAccount := suite.testAccounts["remote_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// target is an unlocked account | 
					
						
							|  |  |  | 	targetAccount := suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	wssStream, errWithCode := testStructs.Processor.Stream().Open(context.Background(), targetAccount, stream.TimelineHome) | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	suite.NoError(errWithCode) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// put the follow request in the database as though it had passed through the federating db already | 
					
						
							|  |  |  | 	satanFollowRequestTurtle := >smodel.FollowRequest{ | 
					
						
							|  |  |  | 		ID:              "01FGRYAVAWWPP926J175QGM0WV", | 
					
						
							|  |  |  | 		CreatedAt:       time.Now(), | 
					
						
							|  |  |  | 		UpdatedAt:       time.Now(), | 
					
						
							|  |  |  | 		AccountID:       originAccount.ID, | 
					
						
							|  |  |  | 		Account:         originAccount, | 
					
						
							|  |  |  | 		TargetAccountID: targetAccount.ID, | 
					
						
							|  |  |  | 		TargetAccount:   targetAccount, | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 		ShowReblogs:     util.Ptr(true), | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 		URI:             fmt.Sprintf("%s/follows/01FGRYAVAWWPP926J175QGM0WV", originAccount.URI), | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 		Notify:          util.Ptr(false), | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err := testStructs.State.DB.Put(ctx, satanFollowRequestTurtle) | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err = testStructs.Processor.Workers().ProcessFromFediAPI(ctx, &messages.FromFediAPI{ | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		APObjectType:   ap.ActivityFollow, | 
					
						
							|  |  |  | 		APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 		GTSModel:       satanFollowRequestTurtle, | 
					
						
							|  |  |  | 		Receiving:      targetAccount, | 
					
						
							|  |  |  | 		Requesting:     originAccount, | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	accept := &struct { | 
					
						
							|  |  |  | 		Actor  string `json:"actor"` | 
					
						
							|  |  |  | 		ID     string `json:"id"` | 
					
						
							|  |  |  | 		Object struct { | 
					
						
							|  |  |  | 			Actor  string `json:"actor"` | 
					
						
							|  |  |  | 			ID     string `json:"id"` | 
					
						
							|  |  |  | 			Object string `json:"object"` | 
					
						
							|  |  |  | 			To     string `json:"to"` | 
					
						
							|  |  |  | 			Type   string `json:"type"` | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		To   string `json:"to"` | 
					
						
							|  |  |  | 		Type string `json:"type"` | 
					
						
							|  |  |  | 	}{} | 
					
						
							| 
									
										
										
										
											2024-04-11 10:45:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// an accept message should be sent to satan's inbox | 
					
						
							|  |  |  | 	var sent []byte | 
					
						
							|  |  |  | 	if !testrig.WaitFor(func() bool { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		delivery, ok := testStructs.State.Workers.Delivery.Queue.Pop() | 
					
						
							| 
									
										
										
										
											2024-04-11 10:45:35 +01:00
										 |  |  | 		if !ok { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if !testrig.EqualRequestURIs(delivery.Request.URL, *originAccount.SharedInboxURI) { | 
					
						
							|  |  |  | 			panic("differing request uris") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		sent, err = io.ReadAll(delivery.Request.Body) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			panic("error reading body: " + err.Error()) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err = json.Unmarshal(sent, accept) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			panic("error unmarshaling json: " + err.Error()) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return true | 
					
						
							|  |  |  | 	}) { | 
					
						
							|  |  |  | 		suite.FailNow("timed out waiting for message") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	suite.Equal(targetAccount.URI, accept.Actor) | 
					
						
							|  |  |  | 	suite.Equal(originAccount.URI, accept.Object.Actor) | 
					
						
							|  |  |  | 	suite.Equal(satanFollowRequestTurtle.URI, accept.Object.ID) | 
					
						
							|  |  |  | 	suite.Equal(targetAccount.URI, accept.Object.Object) | 
					
						
							|  |  |  | 	suite.Equal(targetAccount.URI, accept.Object.To) | 
					
						
							|  |  |  | 	suite.Equal("Follow", accept.Object.Type) | 
					
						
							|  |  |  | 	suite.Equal(originAccount.URI, accept.To) | 
					
						
							|  |  |  | 	suite.Equal("Accept", accept.Type) | 
					
						
							| 
									
										
										
										
											2022-08-31 17:31:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 18:07:49 +00:00
										 |  |  | 	ctx, _ = context.WithTimeout(ctx, time.Second*5) | 
					
						
							|  |  |  | 	msg, ok := wssStream.Recv(context.Background()) | 
					
						
							|  |  |  | 	suite.True(ok) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-31 17:31:21 +02:00
										 |  |  | 	suite.Equal(stream.EventTypeNotification, msg.Event) | 
					
						
							|  |  |  | 	suite.NotEmpty(msg.Payload) | 
					
						
							|  |  |  | 	suite.EqualValues([]string{stream.TimelineHome}, msg.Stream) | 
					
						
							| 
									
										
										
										
											2023-01-02 13:10:50 +01:00
										 |  |  | 	notif := &apimodel.Notification{} | 
					
						
							| 
									
										
										
										
											2022-08-31 17:31:21 +02:00
										 |  |  | 	err = json.Unmarshal([]byte(msg.Payload), notif) | 
					
						
							|  |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 	suite.Equal("follow", notif.Type) | 
					
						
							|  |  |  | 	suite.Equal(originAccount.ID, notif.Account.ID) | 
					
						
							| 
									
										
										
										
											2021-10-01 19:08:50 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | // TestCreateStatusFromIRI checks if a forwarded status can be dereferenced by the processor. | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | func (suite *FromFediAPITestSuite) TestCreateStatusFromIRI() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	receivingAccount := suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 	statusCreator := suite.testAccounts["remote_account_2"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err := testStructs.Processor.Workers().ProcessFromFediAPI(ctx, &messages.FromFediAPI{ | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		APObjectType:   ap.ObjectNote, | 
					
						
							|  |  |  | 		APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 		GTSModel:       nil, // gtsmodel is nil because this is a forwarded status -- we want to dereference it using the iri | 
					
						
							|  |  |  | 		Receiving:      receivingAccount, | 
					
						
							|  |  |  | 		Requesting:     statusCreator, | 
					
						
							|  |  |  | 		APIRI:          testrig.URLMustParse("http://example.org/users/Some_User/statuses/afaba698-5740-4e32-a702-af61aa543bc1"), | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// status should now be in the database, attributed to remote_account_2 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	s, err := testStructs.State.DB.GetStatusByURI(context.Background(), "http://example.org/users/Some_User/statuses/afaba698-5740-4e32-a702-af61aa543bc1") | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 	suite.Equal(statusCreator.URI, s.AccountURI) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | func (suite *FromFediAPITestSuite) TestMoveAccount() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 	// We're gonna migrate foss_satan to our local admin account. | 
					
						
							|  |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 	receivingAcct := suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Copy requesting and target accounts | 
					
						
							|  |  |  | 	// since we'll be changing these. | 
					
						
							|  |  |  | 	requestingAcct := >smodel.Account{} | 
					
						
							|  |  |  | 	*requestingAcct = *suite.testAccounts["remote_account_1"] | 
					
						
							|  |  |  | 	targetAcct := >smodel.Account{} | 
					
						
							|  |  |  | 	*targetAcct = *suite.testAccounts["admin_account"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set alsoKnownAs on the admin account. | 
					
						
							|  |  |  | 	targetAcct.AlsoKnownAsURIs = []string{requestingAcct.URI} | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.UpdateAccount(ctx, targetAcct, "also_known_as_uris"); err != nil { | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Remove existing follow from zork to admin account. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.DeleteFollowByID( | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 		ctx, | 
					
						
							|  |  |  | 		suite.testFollows["local_account_1_admin_account"].ID, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Have Zork follow foss_satan instead. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.PutFollow(ctx, >smodel.Follow{ | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 		ID:              "01HRA0XZYFZC5MNWTKEBR58SSE", | 
					
						
							|  |  |  | 		URI:             "http://localhost:8080/users/the_mighty_zork/follows/01HRA0XZYFZC5MNWTKEBR58SSE", | 
					
						
							|  |  |  | 		AccountID:       receivingAcct.ID, | 
					
						
							|  |  |  | 		TargetAccountID: requestingAcct.ID, | 
					
						
							|  |  |  | 	}); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the Move. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	err := testStructs.Processor.Workers().ProcessFromFediAPI(ctx, &messages.FromFediAPI{ | 
					
						
							| 
									
										
										
										
											2024-06-06 15:43:25 +02:00
										 |  |  | 		APObjectType:   ap.ActorPerson, | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 		APActivityType: ap.ActivityMove, | 
					
						
							|  |  |  | 		GTSModel: >smodel.Move{ | 
					
						
							|  |  |  | 			OriginURI: requestingAcct.URI, | 
					
						
							|  |  |  | 			Origin:    testrig.URLMustParse(requestingAcct.URI), | 
					
						
							|  |  |  | 			TargetURI: targetAcct.URI, | 
					
						
							|  |  |  | 			Target:    testrig.URLMustParse(targetAcct.URI), | 
					
						
							|  |  |  | 			URI:       "https://fossbros-anonymous.io/users/foss_satan/moves/01HRA064871MR8HGVSAFJ333GM", | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		Receiving:  receivingAcct, | 
					
						
							|  |  |  | 		Requesting: requestingAcct, | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 	suite.NoError(err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-13 15:08:43 +02:00
										 |  |  | 	// Wait for side effects to trigger: | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 	// Zork should now be following admin account. | 
					
						
							| 
									
										
										
										
											2024-06-13 15:08:43 +02:00
										 |  |  | 	if !testrig.WaitFor(func() bool { | 
					
						
							|  |  |  | 		follows, err := testStructs.State.DB.IsFollowing(ctx, receivingAcct.ID, targetAcct.ID) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return follows | 
					
						
							|  |  |  | 	}) { | 
					
						
							|  |  |  | 		suite.FailNow("timed out waiting for zork to follow admin account") | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Move should be in the DB. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	move, err := testStructs.State.DB.GetMoveByURI(ctx, "https://fossbros-anonymous.io/users/foss_satan/moves/01HRA064871MR8HGVSAFJ333GM") | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Move should be marked as completed. | 
					
						
							|  |  |  | 	suite.WithinDuration(time.Now(), move.SucceededAt, 1*time.Minute) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | func TestFromFederatorTestSuite(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	suite.Run(t, &FromFediAPITestSuite{}) | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | } |