| 
									
										
										
										
											2023-08-09 19:14:33 +02: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/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package workers_test | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							|  |  |  | 	"errors" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/suite" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/ap" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/config" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/db" | 
					
						
							| 
									
										
										
										
											2024-05-06 04:49:08 -07:00
										 |  |  | 	statusfilter "github.com/superseriousbusiness/gotosocial/internal/filter/status" | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/id" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/messages" | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/state" | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/stream" | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/util" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/testrig" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type FromClientAPITestSuite struct { | 
					
						
							|  |  |  | 	WorkersTestSuite | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (suite *FromClientAPITestSuite) newStatus( | 
					
						
							|  |  |  | 	ctx context.Context, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	state *state.State, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	account *gtsmodel.Account, | 
					
						
							|  |  |  | 	visibility gtsmodel.Visibility, | 
					
						
							|  |  |  | 	replyToStatus *gtsmodel.Status, | 
					
						
							|  |  |  | 	boostOfStatus *gtsmodel.Status, | 
					
						
							|  |  |  | ) *gtsmodel.Status { | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		protocol = config.GetProtocol() | 
					
						
							|  |  |  | 		host     = config.GetHost() | 
					
						
							|  |  |  | 		statusID = id.NewULID() | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Make a new status from given account. | 
					
						
							|  |  |  | 	newStatus := >smodel.Status{ | 
					
						
							|  |  |  | 		ID:                  statusID, | 
					
						
							|  |  |  | 		URI:                 protocol + "://" + host + "/users/" + account.Username + "/statuses/" + statusID, | 
					
						
							|  |  |  | 		URL:                 protocol + "://" + host + "/@" + account.Username + "/statuses/" + statusID, | 
					
						
							|  |  |  | 		Content:             "pee pee poo poo", | 
					
						
							|  |  |  | 		Local:               util.Ptr(true), | 
					
						
							|  |  |  | 		AccountURI:          account.URI, | 
					
						
							|  |  |  | 		AccountID:           account.ID, | 
					
						
							|  |  |  | 		Visibility:          visibility, | 
					
						
							|  |  |  | 		ActivityStreamsType: ap.ObjectNote, | 
					
						
							|  |  |  | 		Federated:           util.Ptr(true), | 
					
						
							|  |  |  | 		Boostable:           util.Ptr(true), | 
					
						
							|  |  |  | 		Replyable:           util.Ptr(true), | 
					
						
							|  |  |  | 		Likeable:            util.Ptr(true), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if replyToStatus != nil { | 
					
						
							|  |  |  | 		// Status is a reply. | 
					
						
							|  |  |  | 		newStatus.InReplyToAccountID = replyToStatus.AccountID | 
					
						
							|  |  |  | 		newStatus.InReplyToID = replyToStatus.ID | 
					
						
							|  |  |  | 		newStatus.InReplyToURI = replyToStatus.URI | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 		newStatus.ThreadID = replyToStatus.ThreadID | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Mention the replied-to account. | 
					
						
							|  |  |  | 		mention := >smodel.Mention{ | 
					
						
							|  |  |  | 			ID:               id.NewULID(), | 
					
						
							|  |  |  | 			StatusID:         statusID, | 
					
						
							|  |  |  | 			OriginAccountID:  account.ID, | 
					
						
							|  |  |  | 			OriginAccountURI: account.URI, | 
					
						
							|  |  |  | 			TargetAccountID:  replyToStatus.AccountID, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		if err := state.DB.PutMention(ctx, mention); err != nil { | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		newStatus.Mentions = []*gtsmodel.Mention{mention} | 
					
						
							|  |  |  | 		newStatus.MentionIDs = []string{mention.ID} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if boostOfStatus != nil { | 
					
						
							|  |  |  | 		// Status is a boost. | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 		newStatus.Content = "" | 
					
						
							|  |  |  | 		newStatus.BoostOfAccountID = boostOfStatus.AccountID | 
					
						
							|  |  |  | 		newStatus.BoostOfID = boostOfStatus.ID | 
					
						
							|  |  |  | 		newStatus.Visibility = boostOfStatus.Visibility | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Put the status in the db, to mimic what would | 
					
						
							|  |  |  | 	// have already happened earlier up the flow. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := state.DB.PutStatus(ctx, newStatus); err != nil { | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return newStatus | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (suite *FromClientAPITestSuite) checkStreamed( | 
					
						
							|  |  |  | 	str *stream.Stream, | 
					
						
							|  |  |  | 	expectMessage bool, | 
					
						
							|  |  |  | 	expectPayload string, | 
					
						
							|  |  |  | 	expectEventType string, | 
					
						
							|  |  |  | ) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 18:07:49 +00:00
										 |  |  | 	// Set a 5s timeout on context. | 
					
						
							|  |  |  | 	ctx := context.Background() | 
					
						
							|  |  |  | 	ctx, cncl := context.WithTimeout(ctx, time.Second*5) | 
					
						
							|  |  |  | 	defer cncl() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	msg, ok := str.Recv(ctx) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if expectMessage && !ok { | 
					
						
							|  |  |  | 		suite.FailNow("expected a message but message was not received") | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 18:07:49 +00:00
										 |  |  | 	if !expectMessage && ok { | 
					
						
							|  |  |  | 		suite.FailNow("expected no message but message was received") | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if expectPayload != "" && msg.Payload != expectPayload { | 
					
						
							|  |  |  | 		suite.FailNow("", "expected payload %s but payload was: %s", expectPayload, msg.Payload) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if expectEventType != "" && msg.Event != expectEventType { | 
					
						
							|  |  |  | 		suite.FailNow("", "expected event type %s but event type was: %s", expectEventType, msg.Event) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (suite *FromClientAPITestSuite) statusJSON( | 
					
						
							|  |  |  | 	ctx context.Context, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	typeConverter *typeutils.Converter, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	status *gtsmodel.Status, | 
					
						
							|  |  |  | 	requestingAccount *gtsmodel.Account, | 
					
						
							|  |  |  | ) string { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	apiStatus, err := typeConverter.StatusToAPIStatus( | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		ctx, | 
					
						
							|  |  |  | 		status, | 
					
						
							|  |  |  | 		requestingAccount, | 
					
						
							| 
									
										
										
										
											2024-05-06 04:49:08 -07:00
										 |  |  | 		statusfilter.FilterContextNone, | 
					
						
							|  |  |  | 		nil, | 
					
						
							| 
									
										
										
										
											2024-06-06 09:38:02 -07:00
										 |  |  | 		nil, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	statusJSON, err := json.Marshal(apiStatus) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return string(statusJSON) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (suite *FromClientAPITestSuite) TestProcessCreateStatusWithNotification() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		ctx              = context.Background() | 
					
						
							|  |  |  | 		postingAccount   = suite.testAccounts["admin_account"] | 
					
						
							|  |  |  | 		receivingAccount = suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 		testList         = suite.testLists["local_account_1_list_1"] | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		streams          = suite.openStreams(ctx, | 
					
						
							|  |  |  | 			testStructs.Processor, | 
					
						
							|  |  |  | 			receivingAccount, | 
					
						
							|  |  |  | 			[]string{testList.ID}, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		homeStream  = streams[stream.TimelineHome] | 
					
						
							|  |  |  | 		listStream  = streams[stream.TimelineList+":"+testList.ID] | 
					
						
							|  |  |  | 		notifStream = streams[stream.TimelineNotifications] | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Admin account posts a new top-level status. | 
					
						
							|  |  |  | 		status = suite.newStatus( | 
					
						
							|  |  |  | 			ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 			testStructs.State, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			postingAccount, | 
					
						
							|  |  |  | 			gtsmodel.VisibilityPublic, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Update the follow from receiving account -> posting account so | 
					
						
							|  |  |  | 	// that receiving account wants notifs when posting account posts. | 
					
						
							|  |  |  | 	follow := new(gtsmodel.Follow) | 
					
						
							|  |  |  | 	*follow = *suite.testFollows["local_account_1_admin_account"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	follow.Notify = util.Ptr(true) | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.UpdateFollow(ctx, follow); err != nil { | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.Processor.Workers().ProcessFromClientAPI( | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		&messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			APObjectType:   ap.ObjectNote, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 			GTSModel:       status, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 			Origin:         postingAccount, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 	statusJSON := suite.statusJSON( | 
					
						
							|  |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		testStructs.TypeConverter, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 		status, | 
					
						
							|  |  |  | 		receivingAccount, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	// Check message in home stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		homeStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		statusJSON, | 
					
						
							|  |  |  | 		stream.EventTypeUpdate, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check message in list stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		listStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		statusJSON, | 
					
						
							|  |  |  | 		stream.EventTypeUpdate, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Wait for a notification to appear for the status. | 
					
						
							|  |  |  | 	var notif *gtsmodel.Notification | 
					
						
							|  |  |  | 	if !testrig.WaitFor(func() bool { | 
					
						
							|  |  |  | 		var err error | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		notif, err = testStructs.State.DB.GetNotification( | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			ctx, | 
					
						
							|  |  |  | 			gtsmodel.NotificationStatus, | 
					
						
							|  |  |  | 			receivingAccount.ID, | 
					
						
							|  |  |  | 			postingAccount.ID, | 
					
						
							|  |  |  | 			status.ID, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		return err == nil | 
					
						
							|  |  |  | 	}) { | 
					
						
							|  |  |  | 		suite.FailNow("timed out waiting for new status notification") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-06 09:38:02 -07:00
										 |  |  | 	apiNotif, err := testStructs.TypeConverter.NotificationToAPINotification(ctx, notif, nil, nil) | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	notifJSON, err := json.Marshal(apiNotif) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check message in notification stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		notifStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		string(notifJSON), | 
					
						
							|  |  |  | 		stream.EventTypeNotification, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (suite *FromClientAPITestSuite) TestProcessCreateStatusReply() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		ctx              = context.Background() | 
					
						
							|  |  |  | 		postingAccount   = suite.testAccounts["admin_account"] | 
					
						
							|  |  |  | 		receivingAccount = suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 		testList         = suite.testLists["local_account_1_list_1"] | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		streams          = suite.openStreams(ctx, testStructs.Processor, receivingAccount, []string{testList.ID}) | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		homeStream       = streams[stream.TimelineHome] | 
					
						
							|  |  |  | 		listStream       = streams[stream.TimelineList+":"+testList.ID] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Admin account posts a reply to turtle. | 
					
						
							|  |  |  | 		// Since turtle is followed by zork, and | 
					
						
							|  |  |  | 		// the default replies policy for this list | 
					
						
							|  |  |  | 		// is to show replies to followed accounts, | 
					
						
							|  |  |  | 		// post should also show in the list stream. | 
					
						
							|  |  |  | 		status = suite.newStatus( | 
					
						
							|  |  |  | 			ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 			testStructs.State, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			postingAccount, | 
					
						
							|  |  |  | 			gtsmodel.VisibilityPublic, | 
					
						
							|  |  |  | 			suite.testStatuses["local_account_2_status_1"], | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.Processor.Workers().ProcessFromClientAPI( | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		&messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			APObjectType:   ap.ObjectNote, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 			GTSModel:       status, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 			Origin:         postingAccount, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 	statusJSON := suite.statusJSON( | 
					
						
							|  |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		testStructs.TypeConverter, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 		status, | 
					
						
							|  |  |  | 		receivingAccount, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	// Check message in home stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		homeStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		statusJSON, | 
					
						
							|  |  |  | 		stream.EventTypeUpdate, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check message in list stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		listStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		statusJSON, | 
					
						
							|  |  |  | 		stream.EventTypeUpdate, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | func (suite *FromClientAPITestSuite) TestProcessCreateStatusReplyMuted() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		ctx              = context.Background() | 
					
						
							|  |  |  | 		postingAccount   = suite.testAccounts["admin_account"] | 
					
						
							|  |  |  | 		receivingAccount = suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Admin account posts a reply to zork. | 
					
						
							|  |  |  | 		// Normally zork would get a notification | 
					
						
							|  |  |  | 		// for this, but zork mutes this thread. | 
					
						
							|  |  |  | 		status = suite.newStatus( | 
					
						
							|  |  |  | 			ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 			testStructs.State, | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 			postingAccount, | 
					
						
							|  |  |  | 			gtsmodel.VisibilityPublic, | 
					
						
							|  |  |  | 			suite.testStatuses["local_account_1_status_1"], | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		threadMute = >smodel.ThreadMute{ | 
					
						
							|  |  |  | 			ID:        "01HD3KRMBB1M85QRWHD912QWRE", | 
					
						
							|  |  |  | 			ThreadID:  suite.testStatuses["local_account_1_status_1"].ThreadID, | 
					
						
							|  |  |  | 			AccountID: receivingAccount.ID, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Store the thread mute before processing new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.PutThreadMute(ctx, threadMute); err != nil { | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.Processor.Workers().ProcessFromClientAPI( | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		&messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 			APObjectType:   ap.ObjectNote, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 			GTSModel:       status, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 			Origin:         postingAccount, | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Ensure no notification received. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	notif, err := testStructs.State.DB.GetNotification( | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 		ctx, | 
					
						
							|  |  |  | 		gtsmodel.NotificationMention, | 
					
						
							|  |  |  | 		receivingAccount.ID, | 
					
						
							|  |  |  | 		postingAccount.ID, | 
					
						
							|  |  |  | 		status.ID, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	suite.ErrorIs(err, db.ErrNoEntries) | 
					
						
							|  |  |  | 	suite.Nil(notif) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (suite *FromClientAPITestSuite) TestProcessCreateStatusBoostMuted() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		ctx              = context.Background() | 
					
						
							|  |  |  | 		postingAccount   = suite.testAccounts["admin_account"] | 
					
						
							|  |  |  | 		receivingAccount = suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Admin account boosts a status by zork. | 
					
						
							|  |  |  | 		// Normally zork would get a notification | 
					
						
							|  |  |  | 		// for this, but zork mutes this thread. | 
					
						
							|  |  |  | 		status = suite.newStatus( | 
					
						
							|  |  |  | 			ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 			testStructs.State, | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 			postingAccount, | 
					
						
							|  |  |  | 			gtsmodel.VisibilityPublic, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 			suite.testStatuses["local_account_1_status_1"], | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		threadMute = >smodel.ThreadMute{ | 
					
						
							|  |  |  | 			ID:        "01HD3KRMBB1M85QRWHD912QWRE", | 
					
						
							|  |  |  | 			ThreadID:  suite.testStatuses["local_account_1_status_1"].ThreadID, | 
					
						
							|  |  |  | 			AccountID: receivingAccount.ID, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Store the thread mute before processing new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.PutThreadMute(ctx, threadMute); err != nil { | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.Processor.Workers().ProcessFromClientAPI( | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		&messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 			APObjectType:   ap.ActivityAnnounce, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 			GTSModel:       status, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 			Origin:         postingAccount, | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Ensure no notification received. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	notif, err := testStructs.State.DB.GetNotification( | 
					
						
							| 
									
										
										
										
											2023-10-25 16:04:53 +02:00
										 |  |  | 		ctx, | 
					
						
							|  |  |  | 		gtsmodel.NotificationReblog, | 
					
						
							|  |  |  | 		receivingAccount.ID, | 
					
						
							|  |  |  | 		postingAccount.ID, | 
					
						
							|  |  |  | 		status.ID, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	suite.ErrorIs(err, db.ErrNoEntries) | 
					
						
							|  |  |  | 	suite.Nil(notif) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | func (suite *FromClientAPITestSuite) TestProcessCreateStatusListRepliesPolicyListOnlyOK() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	// We're modifying the test list so take a copy. | 
					
						
							|  |  |  | 	testList := new(gtsmodel.List) | 
					
						
							|  |  |  | 	*testList = *suite.testLists["local_account_1_list_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		ctx              = context.Background() | 
					
						
							|  |  |  | 		postingAccount   = suite.testAccounts["admin_account"] | 
					
						
							|  |  |  | 		receivingAccount = suite.testAccounts["local_account_1"] | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		streams          = suite.openStreams(ctx, testStructs.Processor, receivingAccount, []string{testList.ID}) | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		homeStream       = streams[stream.TimelineHome] | 
					
						
							|  |  |  | 		listStream       = streams[stream.TimelineList+":"+testList.ID] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Admin account posts a reply to turtle. | 
					
						
							|  |  |  | 		status = suite.newStatus( | 
					
						
							|  |  |  | 			ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 			testStructs.State, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			postingAccount, | 
					
						
							|  |  |  | 			gtsmodel.VisibilityPublic, | 
					
						
							|  |  |  | 			suite.testStatuses["local_account_2_status_1"], | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Modify replies policy of test list to show replies | 
					
						
							|  |  |  | 	// only to other accounts in the same list. Since turtle | 
					
						
							|  |  |  | 	// and admin are in the same list, this means the reply | 
					
						
							|  |  |  | 	// should be shown in the list. | 
					
						
							|  |  |  | 	testList.RepliesPolicy = gtsmodel.RepliesPolicyList | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.UpdateList(ctx, testList, "replies_policy"); err != nil { | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.Processor.Workers().ProcessFromClientAPI( | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		&messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			APObjectType:   ap.ObjectNote, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 			GTSModel:       status, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 			Origin:         postingAccount, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 	statusJSON := suite.statusJSON( | 
					
						
							|  |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		testStructs.TypeConverter, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 		status, | 
					
						
							|  |  |  | 		receivingAccount, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	// Check message in home stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		homeStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		statusJSON, | 
					
						
							|  |  |  | 		stream.EventTypeUpdate, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check message in list stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		listStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		statusJSON, | 
					
						
							|  |  |  | 		stream.EventTypeUpdate, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (suite *FromClientAPITestSuite) TestProcessCreateStatusListRepliesPolicyListOnlyNo() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	// We're modifying the test list so take a copy. | 
					
						
							|  |  |  | 	testList := new(gtsmodel.List) | 
					
						
							|  |  |  | 	*testList = *suite.testLists["local_account_1_list_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		ctx              = context.Background() | 
					
						
							|  |  |  | 		postingAccount   = suite.testAccounts["admin_account"] | 
					
						
							|  |  |  | 		receivingAccount = suite.testAccounts["local_account_1"] | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		streams          = suite.openStreams(ctx, testStructs.Processor, receivingAccount, []string{testList.ID}) | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		homeStream       = streams[stream.TimelineHome] | 
					
						
							|  |  |  | 		listStream       = streams[stream.TimelineList+":"+testList.ID] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Admin account posts a reply to turtle. | 
					
						
							|  |  |  | 		status = suite.newStatus( | 
					
						
							|  |  |  | 			ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 			testStructs.State, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			postingAccount, | 
					
						
							|  |  |  | 			gtsmodel.VisibilityPublic, | 
					
						
							|  |  |  | 			suite.testStatuses["local_account_2_status_1"], | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Modify replies policy of test list to show replies | 
					
						
							|  |  |  | 	// only to other accounts in the same list. We're | 
					
						
							|  |  |  | 	// about to remove turtle from the same list as admin, | 
					
						
							|  |  |  | 	// so the new post should not be streamed to the list. | 
					
						
							|  |  |  | 	testList.RepliesPolicy = gtsmodel.RepliesPolicyList | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.UpdateList(ctx, testList, "replies_policy"); err != nil { | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Remove turtle from the list. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.DeleteListEntry(ctx, suite.testListEntries["local_account_1_list_1_entry_1"].ID); err != nil { | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.Processor.Workers().ProcessFromClientAPI( | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		&messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			APObjectType:   ap.ObjectNote, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 			GTSModel:       status, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 			Origin:         postingAccount, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 	statusJSON := suite.statusJSON( | 
					
						
							|  |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		testStructs.TypeConverter, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 		status, | 
					
						
							|  |  |  | 		receivingAccount, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	// Check message in home stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		homeStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		statusJSON, | 
					
						
							|  |  |  | 		stream.EventTypeUpdate, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check message NOT in list stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		listStream, | 
					
						
							|  |  |  | 		false, | 
					
						
							|  |  |  | 		"", | 
					
						
							|  |  |  | 		"", | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (suite *FromClientAPITestSuite) TestProcessCreateStatusReplyListRepliesPolicyNone() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	// We're modifying the test list so take a copy. | 
					
						
							|  |  |  | 	testList := new(gtsmodel.List) | 
					
						
							|  |  |  | 	*testList = *suite.testLists["local_account_1_list_1"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		ctx              = context.Background() | 
					
						
							|  |  |  | 		postingAccount   = suite.testAccounts["admin_account"] | 
					
						
							|  |  |  | 		receivingAccount = suite.testAccounts["local_account_1"] | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		streams          = suite.openStreams(ctx, testStructs.Processor, receivingAccount, []string{testList.ID}) | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		homeStream       = streams[stream.TimelineHome] | 
					
						
							|  |  |  | 		listStream       = streams[stream.TimelineList+":"+testList.ID] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Admin account posts a reply to turtle. | 
					
						
							|  |  |  | 		status = suite.newStatus( | 
					
						
							|  |  |  | 			ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 			testStructs.State, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			postingAccount, | 
					
						
							|  |  |  | 			gtsmodel.VisibilityPublic, | 
					
						
							|  |  |  | 			suite.testStatuses["local_account_2_status_1"], | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Modify replies policy of test list. | 
					
						
							|  |  |  | 	// Since we're modifying the list to not | 
					
						
							|  |  |  | 	// show any replies, the post should not | 
					
						
							|  |  |  | 	// be streamed to the list. | 
					
						
							|  |  |  | 	testList.RepliesPolicy = gtsmodel.RepliesPolicyNone | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.UpdateList(ctx, testList, "replies_policy"); err != nil { | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.Processor.Workers().ProcessFromClientAPI( | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		&messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			APObjectType:   ap.ObjectNote, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 			GTSModel:       status, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 			Origin:         postingAccount, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 	statusJSON := suite.statusJSON( | 
					
						
							|  |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		testStructs.TypeConverter, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 		status, | 
					
						
							|  |  |  | 		receivingAccount, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	// Check message in home stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		homeStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		statusJSON, | 
					
						
							|  |  |  | 		stream.EventTypeUpdate, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check message NOT in list stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		listStream, | 
					
						
							|  |  |  | 		false, | 
					
						
							|  |  |  | 		"", | 
					
						
							|  |  |  | 		"", | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | func (suite *FromClientAPITestSuite) TestProcessCreateStatusBoost() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		ctx              = context.Background() | 
					
						
							|  |  |  | 		postingAccount   = suite.testAccounts["admin_account"] | 
					
						
							|  |  |  | 		receivingAccount = suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 		testList         = suite.testLists["local_account_1_list_1"] | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		streams          = suite.openStreams(ctx, testStructs.Processor, receivingAccount, []string{testList.ID}) | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 		homeStream       = streams[stream.TimelineHome] | 
					
						
							|  |  |  | 		listStream       = streams[stream.TimelineList+":"+testList.ID] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Admin account boosts a post by turtle. | 
					
						
							|  |  |  | 		status = suite.newStatus( | 
					
						
							|  |  |  | 			ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 			testStructs.State, | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 			postingAccount, | 
					
						
							|  |  |  | 			gtsmodel.VisibilityPublic, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 			suite.testStatuses["local_account_2_status_1"], | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.Processor.Workers().ProcessFromClientAPI( | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		&messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 			APObjectType:   ap.ActivityAnnounce, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 			GTSModel:       status, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 			Origin:         postingAccount, | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 	statusJSON := suite.statusJSON( | 
					
						
							|  |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		testStructs.TypeConverter, | 
					
						
							| 
									
										
										
										
											2024-04-16 13:10:13 +02:00
										 |  |  | 		status, | 
					
						
							|  |  |  | 		receivingAccount, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 	// Check message in home stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		homeStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		statusJSON, | 
					
						
							|  |  |  | 		stream.EventTypeUpdate, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check message in list stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		listStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		statusJSON, | 
					
						
							|  |  |  | 		stream.EventTypeUpdate, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (suite *FromClientAPITestSuite) TestProcessCreateStatusBoostNoReblogs() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		ctx              = context.Background() | 
					
						
							|  |  |  | 		postingAccount   = suite.testAccounts["admin_account"] | 
					
						
							|  |  |  | 		receivingAccount = suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 		testList         = suite.testLists["local_account_1_list_1"] | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		streams          = suite.openStreams(ctx, testStructs.Processor, receivingAccount, []string{testList.ID}) | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 		homeStream       = streams[stream.TimelineHome] | 
					
						
							|  |  |  | 		listStream       = streams[stream.TimelineList+":"+testList.ID] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Admin account boosts a post by turtle. | 
					
						
							|  |  |  | 		status = suite.newStatus( | 
					
						
							|  |  |  | 			ctx, | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 			testStructs.State, | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 			postingAccount, | 
					
						
							|  |  |  | 			gtsmodel.VisibilityPublic, | 
					
						
							|  |  |  | 			nil, | 
					
						
							|  |  |  | 			suite.testStatuses["local_account_2_status_1"], | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Update zork's follow of admin | 
					
						
							|  |  |  | 	// to not show boosts in timeline. | 
					
						
							|  |  |  | 	follow := new(gtsmodel.Follow) | 
					
						
							|  |  |  | 	*follow = *suite.testFollows["local_account_1_admin_account"] | 
					
						
							|  |  |  | 	follow.ShowReblogs = util.Ptr(false) | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.UpdateFollow(ctx, follow, "show_reblogs"); err != nil { | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the new status. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.Processor.Workers().ProcessFromClientAPI( | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		&messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 			APObjectType:   ap.ActivityAnnounce, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityCreate, | 
					
						
							|  |  |  | 			GTSModel:       status, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 			Origin:         postingAccount, | 
					
						
							| 
									
										
										
										
											2023-08-10 17:10:27 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check message NOT in home stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		homeStream, | 
					
						
							|  |  |  | 		false, | 
					
						
							|  |  |  | 		"", | 
					
						
							|  |  |  | 		"", | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check message NOT in list stream. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		listStream, | 
					
						
							|  |  |  | 		false, | 
					
						
							|  |  |  | 		"", | 
					
						
							|  |  |  | 		"", | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | func (suite *FromClientAPITestSuite) TestProcessStatusDelete() { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	testStructs := suite.SetupTestStructs() | 
					
						
							|  |  |  | 	defer suite.TearDownTestStructs(testStructs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		ctx                  = context.Background() | 
					
						
							|  |  |  | 		deletingAccount      = suite.testAccounts["local_account_1"] | 
					
						
							|  |  |  | 		receivingAccount     = suite.testAccounts["local_account_2"] | 
					
						
							|  |  |  | 		deletedStatus        = suite.testStatuses["local_account_1_status_1"] | 
					
						
							|  |  |  | 		boostOfDeletedStatus = suite.testStatuses["admin_account_status_4"] | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		streams              = suite.openStreams(ctx, testStructs.Processor, receivingAccount, nil) | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		homeStream           = streams[stream.TimelineHome] | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Delete the status from the db first, to mimic what | 
					
						
							|  |  |  | 	// would have already happened earlier up the flow | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.State.DB.DeleteStatusByID(ctx, deletedStatus.ID); err != nil { | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the status delete. | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 	if err := testStructs.Processor.Workers().ProcessFromClientAPI( | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 		&messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 			APObjectType:   ap.ObjectNote, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityDelete, | 
					
						
							|  |  |  | 			GTSModel:       deletedStatus, | 
					
						
							| 
									
										
										
										
											2024-04-26 13:50:46 +01:00
										 |  |  | 			Origin:         deletingAccount, | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	); err != nil { | 
					
						
							|  |  |  | 		suite.FailNow(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Stream should have the delete | 
					
						
							|  |  |  | 	// of admin's boost in it now. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		homeStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		boostOfDeletedStatus.ID, | 
					
						
							|  |  |  | 		stream.EventTypeDelete, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Stream should also have the delete | 
					
						
							|  |  |  | 	// of the message itself in it. | 
					
						
							|  |  |  | 	suite.checkStreamed( | 
					
						
							|  |  |  | 		homeStream, | 
					
						
							|  |  |  | 		true, | 
					
						
							|  |  |  | 		deletedStatus.ID, | 
					
						
							|  |  |  | 		stream.EventTypeDelete, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Boost should no longer be in the database. | 
					
						
							|  |  |  | 	if !testrig.WaitFor(func() bool { | 
					
						
							| 
									
										
										
										
											2024-04-29 11:43:18 +02:00
										 |  |  | 		_, err := testStructs.State.DB.GetStatusByID(ctx, boostOfDeletedStatus.ID) | 
					
						
							| 
									
										
										
										
											2023-08-09 19:14:33 +02:00
										 |  |  | 		return errors.Is(err, db.ErrNoEntries) | 
					
						
							|  |  |  | 	}) { | 
					
						
							|  |  |  | 		suite.FailNow("timed out waiting for status delete") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestFromClientAPITestSuite(t *testing.T) { | 
					
						
							|  |  |  | 	suite.Run(t, &FromClientAPITestSuite{}) | 
					
						
							|  |  |  | } |