start adding tests, add delete function for status edits

This commit is contained in:
kim 2024-11-16 10:16:32 +00:00
parent cf707893cc
commit 20e20feae0
6 changed files with 194 additions and 42 deletions

View file

@ -57,6 +57,7 @@ type BunDBStandardTestSuite struct {
testPolls map[string]*gtsmodel.Poll
testPollVotes map[string]*gtsmodel.PollVote
testInteractionRequests map[string]*gtsmodel.InteractionRequest
testStatusEdits map[string]*gtsmodel.StatusEdit
}
func (suite *BunDBStandardTestSuite) SetupSuite() {
@ -83,6 +84,7 @@ func (suite *BunDBStandardTestSuite) SetupSuite() {
suite.testPolls = testrig.NewTestPolls()
suite.testPollVotes = testrig.NewTestPollVotes()
suite.testInteractionRequests = testrig.NewTestInteractionRequests()
suite.testStatusEdits = testrig.NewTestStatusEdits()
}
func (suite *BunDBStandardTestSuite) SetupTest() {

View file

@ -19,8 +19,10 @@ package bundb
import (
"context"
"errors"
"slices"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtscontext"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@ -145,3 +147,47 @@ func (s *statusEditDB) PutStatusEdit(ctx context.Context, edit *gtsmodel.StatusE
return err
})
}
func (s *statusEditDB) DeleteStatusEdits(ctx context.Context, ids []string) error {
if len(ids) == 0 {
return nil
}
// Gather necessary fields from
// deleted for cache invalidation.
var deleted []*gtsmodel.StatusEdit
deleted = make([]*gtsmodel.StatusEdit, 0, len(ids))
// Delete all edits with IDs pertaining
// to given slice, returning status IDs.
if _, err := s.db.NewDelete().
Model(&deleted).
Where("? IN (?)", bun.Ident("id"), bun.In(ids)).
Returning("?", bun.Ident("status_id")).
Exec(ctx); err != nil &&
!errors.Is(err, db.ErrNoEntries) {
return err
}
// Invalidate all the cached status edits with IDs.
s.state.Caches.DB.StatusEdit.InvalidateIDs("ID", ids)
// Make sure we only end up calling
// the invalidate hook for each status
// once. This should just be the one,
// but we double check to save cycles.
m := make(map[string]struct{}, 1)
for _, edit := range deleted {
// Check not already called for status.
if _, ok := m[edit.StatusID]; ok {
continue
}
// Manually call status edit invalidate hook.
s.state.Caches.OnInvalidateStatusEdit(edit)
m[edit.StatusID] = struct{}{}
}
return nil
}

View file

@ -0,0 +1,91 @@
// 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 bundb_test
import (
"context"
"errors"
"reflect"
"testing"
"time"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
)
type StatusEditTestSuite struct {
BunDBStandardTestSuite
}
func (suite *StatusEditTestSuite) TestGetStatusEditBy() {
t := suite.T()
// Create a new context for this test.
ctx, cncl := context.WithCancel(context.Background())
defer cncl()
// Sentinel error to mark avoiding a test case.
sentinelErr := errors.New("sentinel")
// isEqual checks if 2 account models are equal.
isEqual := func(e1, e2 gtsmodel.StatusEdit) bool {
// Clear populated sub-models.
e1.Attachments = nil
e2.Attachments = nil
// Clear database-set fields.
e1.CreatedAt = time.Time{}
e2.CreatedAt = time.Time{}
return reflect.DeepEqual(e1, e2)
}
for _, edit := range suite.testStatusEdits {
for lookup, dbfunc := range map[string]func() (*gtsmodel.StatusEdit, error){
"id": func() (*gtsmodel.StatusEdit, error) {
return suite.db.GetStatusEditByID(ctx, edit.ID)
},
} {
// Clear database caches.
suite.state.Caches.Init()
t.Logf("checking database lookup %q", lookup)
// Perform database function.
checkEdit, err := dbfunc()
if err != nil {
if err == sentinelErr {
continue
}
t.Errorf("error encountered for database lookup %q: %v", lookup, err)
continue
}
// Check received account data.
if !isEqual(*checkEdit, *edit) {
t.Errorf("edit does not contain expected data: %+v", checkEdit)
continue
}
}
}
}
func TestStatusEditTestSuite(t *testing.T) {
suite.Run(t, new(StatusEditTestSuite))
}

View file

@ -36,4 +36,7 @@ type StatusEdit interface {
// PutStatusEdit ...
PutStatusEdit(ctx context.Context, edit *gtsmodel.StatusEdit) error
// DeleteStatusEdits ...
DeleteStatusEdits(ctx context.Context, ids []string) error
}

View file

@ -102,7 +102,7 @@ func CreateTestTables(db db.DB) {
ctx := context.Background()
for _, m := range testModels {
if err := db.CreateTable(ctx, m); err != nil {
log.Panicf(nil, "error creating table for %+v: %s", m, err)
log.Panicf(ctx, "error creating table for %+v: %s", m, err)
}
}
}
@ -126,243 +126,249 @@ func StandardDBSetup(db db.DB, accounts map[string]*gtsmodel.Account) {
for _, v := range NewTestTokens() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestClients() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestApplications() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestBlocks() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestReports() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestRules() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestDomainBlocks() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestInstances() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestUsers() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
if accounts == nil {
for _, v := range NewTestAccounts() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
} else {
for _, v := range accounts {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
}
for _, v := range NewTestAccountSettings() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestAttachments() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestStatuses() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestEmojis() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestEmojiCategories() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestStatusToEmojis() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestTags() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestStatusToTags() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestMentions() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestFaves() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestFollows() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestLists() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestListEntries() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestNotifications() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestTombstones() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestBookmarks() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestAccountNotes() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestMarkers() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestThreads() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestThreadToStatus() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestPolls() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestPollVotes() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestFilters() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestFilterKeywords() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestFilterStatuses() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestUserMutes() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestInteractionRequests() {
if err := db.Put(ctx, v); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
}
for _, v := range NewTestStatusEdits() {
if err := db.Put(ctx, v); err != nil {
log.Panic(ctx, err)
}
}
if err := db.CreateInstanceAccount(ctx); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
if err := db.CreateInstanceInstance(ctx); err != nil {
log.Panic(nil, err)
log.Panic(ctx, err)
}
log.Debug(nil, "testing db setup complete")
log.Debug(ctx, "testing db setup complete")
}
// StandardDBTeardown drops all the standard testing tables/models from the database to ensure it's clean for the next test.

View file

@ -3484,6 +3484,10 @@ func NewTestInteractionRequests() map[string]*gtsmodel.InteractionRequest {
}
}
func NewTestStatusEdits() map[string]*gtsmodel.StatusEdit {
panic("TODO")
}
// GetSignatureForActivity prepares a mock HTTP request as if it were going to deliver activity to destination signed for privkey and pubKeyID, signs the request and returns the header values.
func GetSignatureForActivity(activity pub.Activity, pubKeyID string, privkey *rsa.PrivateKey, destination *url.URL) (signatureHeader string, digestHeader string, dateHeader string) {
// convert the activity into json bytes