mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 04:02:26 -05:00 
			
		
		
		
	[bugfix] Fix report serialization errors caused by user delete (#1659)
* [bugfix] Fix report serialization errors caused by user delete * fix tests
This commit is contained in:
		
					parent
					
						
							
								344c7e5cbd
							
						
					
				
			
			
				commit
				
					
						d9bbcc60a6
					
				
			
		
					 6 changed files with 430 additions and 20 deletions
				
			
		|  | @ -195,7 +195,7 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() { | ||||||
|       "ip": "118.44.18.196", |       "ip": "118.44.18.196", | ||||||
|       "ips": [], |       "ips": [], | ||||||
|       "locale": "en", |       "locale": "en", | ||||||
|       "invite_request": "", |       "invite_request": null, | ||||||
|       "role": { |       "role": { | ||||||
|         "name": "user" |         "name": "user" | ||||||
|       }, |       }, | ||||||
|  | @ -240,7 +240,7 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() { | ||||||
|       "ip": "89.122.255.1", |       "ip": "89.122.255.1", | ||||||
|       "ips": [], |       "ips": [], | ||||||
|       "locale": "en", |       "locale": "en", | ||||||
|       "invite_request": "", |       "invite_request": null, | ||||||
|       "role": { |       "role": { | ||||||
|         "name": "admin" |         "name": "admin" | ||||||
|       }, |       }, | ||||||
|  | @ -286,7 +286,7 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() { | ||||||
|       "ip": "89.122.255.1", |       "ip": "89.122.255.1", | ||||||
|       "ips": [], |       "ips": [], | ||||||
|       "locale": "en", |       "locale": "en", | ||||||
|       "invite_request": "", |       "invite_request": null, | ||||||
|       "role": { |       "role": { | ||||||
|         "name": "admin" |         "name": "admin" | ||||||
|       }, |       }, | ||||||
|  | @ -345,7 +345,7 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() { | ||||||
|       "ip": "118.44.18.196", |       "ip": "118.44.18.196", | ||||||
|       "ips": [], |       "ips": [], | ||||||
|       "locale": "en", |       "locale": "en", | ||||||
|       "invite_request": "", |       "invite_request": null, | ||||||
|       "role": { |       "role": { | ||||||
|         "name": "user" |         "name": "user" | ||||||
|       }, |       }, | ||||||
|  | @ -546,7 +546,7 @@ func (suite *ReportsGetTestSuite) TestReportsGetCreatedByAccount() { | ||||||
|       "ip": "118.44.18.196", |       "ip": "118.44.18.196", | ||||||
|       "ips": [], |       "ips": [], | ||||||
|       "locale": "en", |       "locale": "en", | ||||||
|       "invite_request": "", |       "invite_request": null, | ||||||
|       "role": { |       "role": { | ||||||
|         "name": "user" |         "name": "user" | ||||||
|       }, |       }, | ||||||
|  | @ -747,7 +747,7 @@ func (suite *ReportsGetTestSuite) TestReportsGetTargetAccount() { | ||||||
|       "ip": "118.44.18.196", |       "ip": "118.44.18.196", | ||||||
|       "ips": [], |       "ips": [], | ||||||
|       "locale": "en", |       "locale": "en", | ||||||
|       "invite_request": "", |       "invite_request": null, | ||||||
|       "role": { |       "role": { | ||||||
|         "name": "user" |         "name": "user" | ||||||
|       }, |       }, | ||||||
|  |  | ||||||
|  | @ -21,15 +21,18 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"net" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"codeberg.org/gruf/go-kv" | 	"codeberg.org/gruf/go-kv" | ||||||
|  | 	"github.com/google/uuid" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/ap" | 	"github.com/superseriousbusiness/gotosocial/internal/ap" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/log" | 	"github.com/superseriousbusiness/gotosocial/internal/log" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/messages" | 	"github.com/superseriousbusiness/gotosocial/internal/messages" | ||||||
|  | 	"golang.org/x/crypto/bcrypt" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const deleteSelectLimit = 50 | const deleteSelectLimit = 50 | ||||||
|  | @ -136,8 +139,13 @@ func (p *Processor) deleteUserAndTokensForAccount(ctx context.Context, account * | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := p.state.DB.DeleteUserByID(ctx, user.ID); err != nil { | 	columns, err := stubbifyUser(user) | ||||||
| 		return fmt.Errorf("deleteUserAndTokensForAccount: db error deleting user: %w", err) | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("deleteUserAndTokensForAccount: error stubbifying user: %w", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err := p.state.DB.UpdateUser(ctx, user, columns...); err != nil { | ||||||
|  | 		return fmt.Errorf("deleteUserAndTokensForAccount: db error updating user: %w", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  | @ -473,3 +481,61 @@ func stubbifyAccount(account *gtsmodel.Account, origin string) []string { | ||||||
| 		"enable_rss", | 		"enable_rss", | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // stubbifyUser renders the given user as a stub, | ||||||
|  | // removing sensitive information like IP addresses | ||||||
|  | // and sign-in times, but keeping email addresses to | ||||||
|  | // prevent the same email address from creating another | ||||||
|  | // account on this instance. | ||||||
|  | // | ||||||
|  | // `encrypted_password` is set to the bcrypt hash of a | ||||||
|  | // random uuid, so if the action is reversed, the user | ||||||
|  | // will have to reset their password via email. | ||||||
|  | // | ||||||
|  | // For caller's convenience, this function returns the db | ||||||
|  | // names of all columns that are updated by it. | ||||||
|  | func stubbifyUser(user *gtsmodel.User) ([]string, error) { | ||||||
|  | 	uuid, err := uuid.New().MarshalBinary() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dummyPassword, err := bcrypt.GenerateFromPassword(uuid, bcrypt.DefaultCost) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var never = time.Time{} | ||||||
|  | 
 | ||||||
|  | 	user.EncryptedPassword = string(dummyPassword) | ||||||
|  | 	user.SignUpIP = net.IPv4zero | ||||||
|  | 	user.CurrentSignInAt = never | ||||||
|  | 	user.CurrentSignInIP = net.IPv4zero | ||||||
|  | 	user.LastSignInAt = never | ||||||
|  | 	user.LastSignInIP = net.IPv4zero | ||||||
|  | 	user.SignInCount = 1 | ||||||
|  | 	user.Locale = "" | ||||||
|  | 	user.CreatedByApplicationID = "" | ||||||
|  | 	user.LastEmailedAt = never | ||||||
|  | 	user.ConfirmationToken = "" | ||||||
|  | 	user.ConfirmationSentAt = never | ||||||
|  | 	user.ResetPasswordToken = "" | ||||||
|  | 	user.ResetPasswordSentAt = never | ||||||
|  | 
 | ||||||
|  | 	return []string{ | ||||||
|  | 		"encrypted_password", | ||||||
|  | 		"sign_up_ip", | ||||||
|  | 		"current_sign_in_at", | ||||||
|  | 		"current_sign_in_ip", | ||||||
|  | 		"last_sign_in_at", | ||||||
|  | 		"last_sign_in_ip", | ||||||
|  | 		"sign_in_count", | ||||||
|  | 		"locale", | ||||||
|  | 		"created_by_application_id", | ||||||
|  | 		"last_emailed_at", | ||||||
|  | 		"confirmation_token", | ||||||
|  | 		"confirmation_sent_at", | ||||||
|  | 		"reset_password_token", | ||||||
|  | 		"reset_password_sent_at", | ||||||
|  | 	}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										102
									
								
								internal/processing/account/delete_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								internal/processing/account/delete_test.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,102 @@ | ||||||
|  | // 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 account_test | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"net" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/suite" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type AccountDeleteTestSuite struct { | ||||||
|  | 	AccountStandardTestSuite | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *AccountDeleteTestSuite) TestAccountDeleteLocal() { | ||||||
|  | 	ctx := context.Background() | ||||||
|  | 
 | ||||||
|  | 	// Keep a reference around to the original account | ||||||
|  | 	// and user, before the delete was processed. | ||||||
|  | 	ogAccount := suite.testAccounts["local_account_1"] | ||||||
|  | 	ogUser := suite.testUsers["local_account_1"] | ||||||
|  | 
 | ||||||
|  | 	testAccount := >smodel.Account{} | ||||||
|  | 	*testAccount = *ogAccount | ||||||
|  | 
 | ||||||
|  | 	suspensionOrigin := "01GWVP2A8J38Q2J2FDZ6TS8AQG" | ||||||
|  | 	if err := suite.accountProcessor.Delete(ctx, testAccount, suspensionOrigin); err != nil { | ||||||
|  | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	updatedAccount, err := suite.db.GetAccountByID(ctx, ogAccount.ID) | ||||||
|  | 	if err != nil { | ||||||
|  | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	suite.WithinDuration(time.Now(), updatedAccount.UpdatedAt, 1*time.Minute) | ||||||
|  | 	suite.Zero(updatedAccount.FetchedAt) | ||||||
|  | 	suite.Zero(updatedAccount.AvatarMediaAttachmentID) | ||||||
|  | 	suite.Zero(updatedAccount.AvatarRemoteURL) | ||||||
|  | 	suite.Zero(updatedAccount.HeaderMediaAttachmentID) | ||||||
|  | 	suite.Zero(updatedAccount.HeaderRemoteURL) | ||||||
|  | 	suite.Zero(updatedAccount.DisplayName) | ||||||
|  | 	suite.Nil(updatedAccount.EmojiIDs) | ||||||
|  | 	suite.Nil(updatedAccount.Emojis) | ||||||
|  | 	suite.Nil(updatedAccount.Fields) | ||||||
|  | 	suite.Zero(updatedAccount.Note) | ||||||
|  | 	suite.Zero(updatedAccount.NoteRaw) | ||||||
|  | 	suite.False(*updatedAccount.Memorial) | ||||||
|  | 	suite.Zero(updatedAccount.AlsoKnownAs) | ||||||
|  | 	suite.Zero(updatedAccount.Reason) | ||||||
|  | 	suite.False(*updatedAccount.Discoverable) | ||||||
|  | 	suite.Zero(updatedAccount.StatusContentType) | ||||||
|  | 	suite.Zero(updatedAccount.CustomCSS) | ||||||
|  | 	suite.WithinDuration(time.Now(), updatedAccount.SuspendedAt, 1*time.Minute) | ||||||
|  | 	suite.Equal(suspensionOrigin, updatedAccount.SuspensionOrigin) | ||||||
|  | 	suite.True(*updatedAccount.HideCollections) | ||||||
|  | 	suite.False(*updatedAccount.EnableRSS) | ||||||
|  | 
 | ||||||
|  | 	updatedUser, err := suite.db.GetUserByAccountID(ctx, testAccount.ID) | ||||||
|  | 	if err != nil { | ||||||
|  | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	suite.WithinDuration(time.Now(), updatedUser.UpdatedAt, 1*time.Minute) | ||||||
|  | 	suite.NotEqual(updatedUser.EncryptedPassword, ogUser.EncryptedPassword) | ||||||
|  | 	suite.Equal(net.IPv4zero, updatedUser.SignUpIP) | ||||||
|  | 	suite.Zero(updatedUser.CurrentSignInAt) | ||||||
|  | 	suite.Equal(net.IPv4zero, updatedUser.CurrentSignInIP) | ||||||
|  | 	suite.Zero(updatedUser.LastSignInAt) | ||||||
|  | 	suite.Equal(net.IPv4zero, updatedUser.LastSignInIP) | ||||||
|  | 	suite.Equal(1, updatedUser.SignInCount) | ||||||
|  | 	suite.Zero(updatedUser.Locale) | ||||||
|  | 	suite.Zero(updatedUser.CreatedByApplicationID) | ||||||
|  | 	suite.Zero(updatedUser.LastEmailedAt) | ||||||
|  | 	suite.Zero(updatedUser.ConfirmationToken) | ||||||
|  | 	suite.Zero(updatedUser.ConfirmationSentAt) | ||||||
|  | 	suite.Zero(updatedUser.ResetPasswordToken) | ||||||
|  | 	suite.Zero(updatedUser.ResetPasswordSentAt) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestAccountDeleteTestSuite(t *testing.T) { | ||||||
|  | 	suite.Run(t, new(AccountDeleteTestSuite)) | ||||||
|  | } | ||||||
|  | @ -22,6 +22,7 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/activity/streams/vocab" | 	"github.com/superseriousbusiness/activity/streams/vocab" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/processing" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/state" | 	"github.com/superseriousbusiness/gotosocial/internal/state" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/testrig" | 	"github.com/superseriousbusiness/gotosocial/testrig" | ||||||
|  | @ -482,13 +483,17 @@ type TypeUtilsTestSuite struct { | ||||||
| 	typeconverter typeutils.TypeConverter | 	typeconverter typeutils.TypeConverter | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *TypeUtilsTestSuite) SetupSuite() { | func (suite *TypeUtilsTestSuite) SetupTest() { | ||||||
| 	suite.state.Caches.Init() | 	suite.state.Caches.Init() | ||||||
| 
 | 
 | ||||||
| 	testrig.InitTestConfig() | 	testrig.InitTestConfig() | ||||||
| 	testrig.InitTestLog() | 	testrig.InitTestLog() | ||||||
| 
 | 
 | ||||||
| 	suite.db = testrig.NewTestDB(&suite.state) | 	suite.db = testrig.NewTestDB(&suite.state) | ||||||
|  | 	suite.state.DB = suite.db | ||||||
|  | 	storage := testrig.NewInMemoryStorage() | ||||||
|  | 	suite.state.Storage = storage | ||||||
|  | 
 | ||||||
| 	suite.testAccounts = testrig.NewTestAccounts() | 	suite.testAccounts = testrig.NewTestAccounts() | ||||||
| 	suite.testStatuses = testrig.NewTestStatuses() | 	suite.testStatuses = testrig.NewTestStatuses() | ||||||
| 	suite.testAttachments = testrig.NewTestAttachments() | 	suite.testAttachments = testrig.NewTestAttachments() | ||||||
|  | @ -497,13 +502,23 @@ func (suite *TypeUtilsTestSuite) SetupSuite() { | ||||||
| 	suite.testReports = testrig.NewTestReports() | 	suite.testReports = testrig.NewTestReports() | ||||||
| 	suite.testMentions = testrig.NewTestMentions() | 	suite.testMentions = testrig.NewTestMentions() | ||||||
| 	suite.typeconverter = typeutils.NewConverter(suite.db) | 	suite.typeconverter = typeutils.NewConverter(suite.db) | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| func (suite *TypeUtilsTestSuite) SetupTest() { |  | ||||||
| 	suite.state.Caches.Init() // reset |  | ||||||
| 	testrig.StandardDBSetup(suite.db, nil) | 	testrig.StandardDBSetup(suite.db, nil) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *TypeUtilsTestSuite) TearDownTest() { | func (suite *TypeUtilsTestSuite) TearDownTest() { | ||||||
| 	testrig.StandardDBTeardown(suite.db) | 	testrig.StandardDBTeardown(suite.db) | ||||||
|  | 	testrig.StopWorkers(&suite.state) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetProcessor is a utility function that instantiates a processor. | ||||||
|  | // Useful when a test in the test suite needs to change some state. | ||||||
|  | func (suite *TypeUtilsTestSuite) GetProcessor() *processing.Processor { | ||||||
|  | 	testrig.StartWorkers(&suite.state) | ||||||
|  | 	httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") | ||||||
|  | 	transportController := testrig.NewTestTransportController(&suite.state, httpClient) | ||||||
|  | 	mediaManager := testrig.NewTestMediaManager(&suite.state) | ||||||
|  | 	federator := testrig.NewTestFederator(&suite.state, transportController, mediaManager) | ||||||
|  | 	emailSender := testrig.NewEmailSender("../../web/template/", nil) | ||||||
|  | 	return testrig.NewTestProcessor(&suite.state, federator, emailSender, mediaManager) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -270,7 +270,7 @@ func (c *converter) AccountToAdminAPIAccount(ctx context.Context, a *gtsmodel.Ac | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	// take user-level information if possible | 	// take user-level information if possible | ||||||
| 	if a.Domain != "" { | 	if a.IsRemote() { | ||||||
| 		domain = &a.Domain | 		domain = &a.Domain | ||||||
| 	} else { | 	} else { | ||||||
| 		user, err := c.db.GetUserByAccountID(ctx, a.ID) | 		user, err := c.db.GetUserByAccountID(ctx, a.ID) | ||||||
|  | @ -289,7 +289,9 @@ func (c *converter) AccountToAdminAPIAccount(ctx context.Context, a *gtsmodel.Ac | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		locale = user.Locale | 		locale = user.Locale | ||||||
| 		inviteRequest = &user.Account.Reason | 		if user.Account.Reason != "" { | ||||||
|  | 			inviteRequest = &user.Account.Reason | ||||||
|  | 		} | ||||||
| 		if *user.Admin { | 		if *user.Admin { | ||||||
| 			role.Name = apimodel.AccountRoleAdmin | 			role.Name = apimodel.AccountRoleAdmin | ||||||
| 		} else if *user.Moderator { | 		} else if *user.Moderator { | ||||||
|  | @ -298,11 +300,12 @@ func (c *converter) AccountToAdminAPIAccount(ctx context.Context, a *gtsmodel.Ac | ||||||
| 		confirmed = !user.ConfirmedAt.IsZero() | 		confirmed = !user.ConfirmedAt.IsZero() | ||||||
| 		approved = *user.Approved | 		approved = *user.Approved | ||||||
| 		disabled = *user.Disabled | 		disabled = *user.Disabled | ||||||
| 		silenced = !user.Account.SilencedAt.IsZero() |  | ||||||
| 		suspended = !user.Account.SuspendedAt.IsZero() |  | ||||||
| 		createdByApplicationID = user.CreatedByApplicationID | 		createdByApplicationID = user.CreatedByApplicationID | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	silenced = !a.SilencedAt.IsZero() | ||||||
|  | 	suspended = !a.SuspendedAt.IsZero() | ||||||
|  | 
 | ||||||
| 	apiAccount, err := c.AccountToAPIAccountPublic(ctx, a) | 	apiAccount, err := c.AccountToAPIAccountPublic(ctx, a) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, fmt.Errorf("AccountToAdminAPIAccount: error converting account to api account for account id %s: %w", a.ID, err) | 		return nil, fmt.Errorf("AccountToAdminAPIAccount: error converting account to api account for account id %s: %w", a.ID, err) | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/config" | 	"github.com/superseriousbusiness/gotosocial/internal/config" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/testrig" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type InternalToFrontendTestSuite struct { | type InternalToFrontendTestSuite struct { | ||||||
|  | @ -908,7 +909,7 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() { | ||||||
|     "ip": "118.44.18.196", |     "ip": "118.44.18.196", | ||||||
|     "ips": [], |     "ips": [], | ||||||
|     "locale": "en", |     "locale": "en", | ||||||
|     "invite_request": "", |     "invite_request": null, | ||||||
|     "role": { |     "role": { | ||||||
|       "name": "user" |       "name": "user" | ||||||
|     }, |     }, | ||||||
|  | @ -953,7 +954,7 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() { | ||||||
|     "ip": "89.122.255.1", |     "ip": "89.122.255.1", | ||||||
|     "ips": [], |     "ips": [], | ||||||
|     "locale": "en", |     "locale": "en", | ||||||
|     "invite_request": "", |     "invite_request": null, | ||||||
|     "role": { |     "role": { | ||||||
|       "name": "admin" |       "name": "admin" | ||||||
|     }, |     }, | ||||||
|  | @ -999,7 +1000,7 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() { | ||||||
|     "ip": "89.122.255.1", |     "ip": "89.122.255.1", | ||||||
|     "ips": [], |     "ips": [], | ||||||
|     "locale": "en", |     "locale": "en", | ||||||
|     "invite_request": "", |     "invite_request": null, | ||||||
|     "role": { |     "role": { | ||||||
|       "name": "admin" |       "name": "admin" | ||||||
|     }, |     }, | ||||||
|  | @ -1068,7 +1069,7 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend2() { | ||||||
|     "ip": "118.44.18.196", |     "ip": "118.44.18.196", | ||||||
|     "ips": [], |     "ips": [], | ||||||
|     "locale": "en", |     "locale": "en", | ||||||
|     "invite_request": "", |     "invite_request": null, | ||||||
|     "role": { |     "role": { | ||||||
|       "name": "user" |       "name": "user" | ||||||
|     }, |     }, | ||||||
|  | @ -1234,6 +1235,229 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend2() { | ||||||
| }`, string(b)) | }`, string(b)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLocalAccount() { | ||||||
|  | 	ctx := context.Background() | ||||||
|  | 	requestingAccount := suite.testAccounts["admin_account"] | ||||||
|  | 	reportedAccount := >smodel.Account{} | ||||||
|  | 	*reportedAccount = *suite.testAccounts["local_account_2"] | ||||||
|  | 
 | ||||||
|  | 	// Suspend/delete the reported account. | ||||||
|  | 	if err := suite.GetProcessor().Account().Delete(ctx, reportedAccount, requestingAccount.ID); err != nil { | ||||||
|  | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Wait for the delete to process. Stubbifying | ||||||
|  | 	// the account is the last part of the delete, | ||||||
|  | 	// so once it's stubbified we know we're done. | ||||||
|  | 	if !testrig.WaitFor(func() bool { | ||||||
|  | 		dbAccount, err := suite.db.GetAccountByID(ctx, reportedAccount.ID) | ||||||
|  | 		if err != nil { | ||||||
|  | 			suite.FailNow(err.Error()) | ||||||
|  | 		} | ||||||
|  | 		return dbAccount.DisplayName == "" | ||||||
|  | 	}) { | ||||||
|  | 		suite.FailNow("timed out waiting for account delete") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	adminReport, err := suite.typeconverter.ReportToAdminAPIReport(context.Background(), suite.testReports["remote_account_1_report_local_account_2"], requestingAccount) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	b, err := json.MarshalIndent(adminReport, "", "  ") | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(`{ | ||||||
|  |   "id": "01GP3DFY9XQ1TJMZT5BGAZPXX7", | ||||||
|  |   "action_taken": true, | ||||||
|  |   "action_taken_at": "2022-05-15T15:01:56.000Z", | ||||||
|  |   "category": "other", | ||||||
|  |   "comment": "this is a turtle, not a person, therefore should not be a poster", | ||||||
|  |   "forwarded": true, | ||||||
|  |   "created_at": "2022-05-15T14:20:12.000Z", | ||||||
|  |   "updated_at": "2022-05-15T14:20:12.000Z", | ||||||
|  |   "account": { | ||||||
|  |     "id": "01F8MH5ZK5VRH73AKHQM6Y9VNX", | ||||||
|  |     "username": "foss_satan", | ||||||
|  |     "domain": "fossbros-anonymous.io", | ||||||
|  |     "created_at": "2021-09-26T10:52:36.000Z", | ||||||
|  |     "email": "", | ||||||
|  |     "ip": null, | ||||||
|  |     "ips": [], | ||||||
|  |     "locale": "", | ||||||
|  |     "invite_request": null, | ||||||
|  |     "role": { | ||||||
|  |       "name": "user" | ||||||
|  |     }, | ||||||
|  |     "confirmed": false, | ||||||
|  |     "approved": false, | ||||||
|  |     "disabled": false, | ||||||
|  |     "silenced": false, | ||||||
|  |     "suspended": false, | ||||||
|  |     "account": { | ||||||
|  |       "id": "01F8MH5ZK5VRH73AKHQM6Y9VNX", | ||||||
|  |       "username": "foss_satan", | ||||||
|  |       "acct": "foss_satan@fossbros-anonymous.io", | ||||||
|  |       "display_name": "big gerald", | ||||||
|  |       "locked": false, | ||||||
|  |       "discoverable": true, | ||||||
|  |       "bot": false, | ||||||
|  |       "created_at": "2021-09-26T10:52:36.000Z", | ||||||
|  |       "note": "i post about like, i dunno, stuff, or whatever!!!!", | ||||||
|  |       "url": "http://fossbros-anonymous.io/@foss_satan", | ||||||
|  |       "avatar": "", | ||||||
|  |       "avatar_static": "", | ||||||
|  |       "header": "http://localhost:8080/assets/default_header.png", | ||||||
|  |       "header_static": "http://localhost:8080/assets/default_header.png", | ||||||
|  |       "followers_count": 0, | ||||||
|  |       "following_count": 0, | ||||||
|  |       "statuses_count": 1, | ||||||
|  |       "last_status_at": "2021-09-20T10:40:37.000Z", | ||||||
|  |       "emojis": [], | ||||||
|  |       "fields": [] | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "target_account": { | ||||||
|  |     "id": "01F8MH5NBDF2MV7CTC4Q5128HF", | ||||||
|  |     "username": "1happyturtle", | ||||||
|  |     "domain": null, | ||||||
|  |     "created_at": "2022-06-04T13:12:00.000Z", | ||||||
|  |     "email": "tortle.dude@example.org", | ||||||
|  |     "ip": "0.0.0.0", | ||||||
|  |     "ips": [], | ||||||
|  |     "locale": "", | ||||||
|  |     "invite_request": null, | ||||||
|  |     "role": { | ||||||
|  |       "name": "user" | ||||||
|  |     }, | ||||||
|  |     "confirmed": true, | ||||||
|  |     "approved": true, | ||||||
|  |     "disabled": false, | ||||||
|  |     "silenced": false, | ||||||
|  |     "suspended": true, | ||||||
|  |     "account": { | ||||||
|  |       "id": "01F8MH5NBDF2MV7CTC4Q5128HF", | ||||||
|  |       "username": "1happyturtle", | ||||||
|  |       "acct": "1happyturtle", | ||||||
|  |       "display_name": "", | ||||||
|  |       "locked": true, | ||||||
|  |       "discoverable": false, | ||||||
|  |       "bot": false, | ||||||
|  |       "created_at": "2022-06-04T13:12:00.000Z", | ||||||
|  |       "note": "", | ||||||
|  |       "url": "http://localhost:8080/@1happyturtle", | ||||||
|  |       "avatar": "", | ||||||
|  |       "avatar_static": "", | ||||||
|  |       "header": "http://localhost:8080/assets/default_header.png", | ||||||
|  |       "header_static": "http://localhost:8080/assets/default_header.png", | ||||||
|  |       "followers_count": 0, | ||||||
|  |       "following_count": 0, | ||||||
|  |       "statuses_count": 0, | ||||||
|  |       "last_status_at": null, | ||||||
|  |       "emojis": [], | ||||||
|  |       "fields": [], | ||||||
|  |       "suspended": true, | ||||||
|  |       "role": { | ||||||
|  |         "name": "user" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "assigned_account": { | ||||||
|  |     "id": "01F8MH17FWEB39HZJ76B6VXSKF", | ||||||
|  |     "username": "admin", | ||||||
|  |     "domain": null, | ||||||
|  |     "created_at": "2022-05-17T13:10:59.000Z", | ||||||
|  |     "email": "admin@example.org", | ||||||
|  |     "ip": "89.122.255.1", | ||||||
|  |     "ips": [], | ||||||
|  |     "locale": "en", | ||||||
|  |     "invite_request": null, | ||||||
|  |     "role": { | ||||||
|  |       "name": "admin" | ||||||
|  |     }, | ||||||
|  |     "confirmed": true, | ||||||
|  |     "approved": true, | ||||||
|  |     "disabled": false, | ||||||
|  |     "silenced": false, | ||||||
|  |     "suspended": false, | ||||||
|  |     "account": { | ||||||
|  |       "id": "01F8MH17FWEB39HZJ76B6VXSKF", | ||||||
|  |       "username": "admin", | ||||||
|  |       "acct": "admin", | ||||||
|  |       "display_name": "", | ||||||
|  |       "locked": false, | ||||||
|  |       "discoverable": true, | ||||||
|  |       "bot": false, | ||||||
|  |       "created_at": "2022-05-17T13:10:59.000Z", | ||||||
|  |       "note": "", | ||||||
|  |       "url": "http://localhost:8080/@admin", | ||||||
|  |       "avatar": "", | ||||||
|  |       "avatar_static": "", | ||||||
|  |       "header": "http://localhost:8080/assets/default_header.png", | ||||||
|  |       "header_static": "http://localhost:8080/assets/default_header.png", | ||||||
|  |       "followers_count": 1, | ||||||
|  |       "following_count": 1, | ||||||
|  |       "statuses_count": 4, | ||||||
|  |       "last_status_at": "2021-10-20T10:41:37.000Z", | ||||||
|  |       "emojis": [], | ||||||
|  |       "fields": [], | ||||||
|  |       "enable_rss": true, | ||||||
|  |       "role": { | ||||||
|  |         "name": "admin" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F" | ||||||
|  |   }, | ||||||
|  |   "action_taken_by_account": { | ||||||
|  |     "id": "01F8MH17FWEB39HZJ76B6VXSKF", | ||||||
|  |     "username": "admin", | ||||||
|  |     "domain": null, | ||||||
|  |     "created_at": "2022-05-17T13:10:59.000Z", | ||||||
|  |     "email": "admin@example.org", | ||||||
|  |     "ip": "89.122.255.1", | ||||||
|  |     "ips": [], | ||||||
|  |     "locale": "en", | ||||||
|  |     "invite_request": null, | ||||||
|  |     "role": { | ||||||
|  |       "name": "admin" | ||||||
|  |     }, | ||||||
|  |     "confirmed": true, | ||||||
|  |     "approved": true, | ||||||
|  |     "disabled": false, | ||||||
|  |     "silenced": false, | ||||||
|  |     "suspended": false, | ||||||
|  |     "account": { | ||||||
|  |       "id": "01F8MH17FWEB39HZJ76B6VXSKF", | ||||||
|  |       "username": "admin", | ||||||
|  |       "acct": "admin", | ||||||
|  |       "display_name": "", | ||||||
|  |       "locked": false, | ||||||
|  |       "discoverable": true, | ||||||
|  |       "bot": false, | ||||||
|  |       "created_at": "2022-05-17T13:10:59.000Z", | ||||||
|  |       "note": "", | ||||||
|  |       "url": "http://localhost:8080/@admin", | ||||||
|  |       "avatar": "", | ||||||
|  |       "avatar_static": "", | ||||||
|  |       "header": "http://localhost:8080/assets/default_header.png", | ||||||
|  |       "header_static": "http://localhost:8080/assets/default_header.png", | ||||||
|  |       "followers_count": 1, | ||||||
|  |       "following_count": 1, | ||||||
|  |       "statuses_count": 4, | ||||||
|  |       "last_status_at": "2021-10-20T10:41:37.000Z", | ||||||
|  |       "emojis": [], | ||||||
|  |       "fields": [], | ||||||
|  |       "enable_rss": true, | ||||||
|  |       "role": { | ||||||
|  |         "name": "admin" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F" | ||||||
|  |   }, | ||||||
|  |   "statuses": [], | ||||||
|  |   "rule_ids": [], | ||||||
|  |   "action_taken_comment": "user was warned not to be a turtle anymore" | ||||||
|  | }`, string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestInternalToFrontendTestSuite(t *testing.T) { | func TestInternalToFrontendTestSuite(t *testing.T) { | ||||||
| 	suite.Run(t, new(InternalToFrontendTestSuite)) | 	suite.Run(t, new(InternalToFrontendTestSuite)) | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue