From 7ab9e78b44537c297d9af4ef752389c671046259 Mon Sep 17 00:00:00 2001 From: tsmethurst Date: Sat, 10 Apr 2021 18:50:28 +0200 Subject: [PATCH] more work on test rig --- internal/apimodule/media/mediacreate_test.go | 77 ++++++++++-------- internal/gotosocial/actions.go | 5 +- internal/mastotypes/mock_Converter.go | 42 ++++++++++ internal/media/mock_MediaHandler.go | 23 ++++++ internal/storage/inmem.go | 19 +++++ internal/storage/local.go | 51 +++++++++++- internal/storage/mock_Storage.go | 37 +++++++++ internal/storage/storage.go | 2 + testrig/config.go | 18 +++++ testrig/db.go | 18 +++++ testrig/log.go | 28 +++++++ testrig/mastoconverter.go | 29 +++++++ testrig/media/welcome-original.jpeg | Bin 0 -> 62529 bytes testrig/media/welcome-small.jpeg | Bin 0 -> 6872 bytes testrig/mediahandler.go | 31 +++++++ testrig/oauthserver.go | 29 +++++++ testrig/storage.go | 71 ++++++++++++++-- testrig/{models.go => testmodels.go} | 81 ++++++++++++++++++- 18 files changed, 514 insertions(+), 47 deletions(-) create mode 100644 testrig/log.go create mode 100644 testrig/mastoconverter.go create mode 100755 testrig/media/welcome-original.jpeg create mode 100755 testrig/media/welcome-small.jpeg create mode 100644 testrig/mediahandler.go create mode 100644 testrig/oauthserver.go rename testrig/{models.go => testmodels.go} (87%) diff --git a/internal/apimodule/media/mediacreate_test.go b/internal/apimodule/media/mediacreate_test.go index f598260..0c5c533 100644 --- a/internal/apimodule/media/mediacreate_test.go +++ b/internal/apimodule/media/mediacreate_test.go @@ -13,7 +13,6 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" @@ -27,48 +26,43 @@ import ( ) type MediaCreateTestSuite struct { + // standard suite interfaces suite.Suite - config *config.Config - mockOauthServer *oauth.MockServer - mockStorage *storage.MockStorage - mediaHandler media.MediaHandler - mastoConverter mastotypes.Converter + config *config.Config + db db.DB + log *logrus.Logger + storage storage.Storage + mastoConverter mastotypes.Converter + mediaHandler media.MediaHandler + oauthServer oauth.Server + + // standard suite models testTokens map[string]*oauth.Token testClients map[string]*oauth.Client testApplications map[string]*gtsmodel.Application testUsers map[string]*gtsmodel.User testAccounts map[string]*gtsmodel.Account - log *logrus.Logger - db db.DB - mediaModule *mediaModule + testAttachments map[string]*gtsmodel.MediaAttachment + + // item being tested + mediaModule *mediaModule } /* TEST INFRASTRUCTURE */ -// SetupSuite sets some variables on the suite that we can use as consts (more or less) throughout func (suite *MediaCreateTestSuite) SetupSuite() { - // some of our subsequent entities need a log so create this here - log := logrus.New() - log.SetLevel(logrus.TraceLevel) - suite.log = log - - // Direct config to local postgres instance + // setup standard items suite.config = testrig.NewTestConfig() + suite.db = testrig.NewTestDB() + suite.log = testrig.NewTestLog() + suite.storage = testrig.NewTestStorage() + suite.mastoConverter = testrig.NewTestMastoConverter(suite.db) + suite.mediaHandler = testrig.NewTestMediaHandler(suite.db, suite.storage) + suite.oauthServer = testrig.NewTestOauthServer(suite.db) - // use an actual database for this, because it's just easier than mocking one out - database, err := db.New(context.Background(), suite.config, log) - if err != nil { - suite.FailNow(err.Error()) - } - suite.db = database - - suite.mockOauthServer = &oauth.MockServer{} - suite.mockStorage = &storage.MockStorage{} - suite.mockStorage.On("StoreFileAt", mock.AnythingOfType("string"), mock.AnythingOfType("[]uint8")).Return(nil) // just pretend to store - suite.mediaHandler = media.New(suite.config, suite.db, suite.mockStorage, log) - suite.mastoConverter = mastotypes.New(suite.config, suite.db) + // setup module being tested suite.mediaModule = New(suite.db, suite.mediaHandler, suite.mastoConverter, suite.config, suite.log).(*mediaModule) } @@ -80,16 +74,18 @@ func (suite *MediaCreateTestSuite) TearDownSuite() { func (suite *MediaCreateTestSuite) SetupTest() { testrig.StandardDBSetup(suite.db) + testrig.StandardStorageSetup(suite.storage, "../../../testrig/media") suite.testTokens = testrig.NewTestTokens() suite.testClients = testrig.NewTestClients() suite.testApplications = testrig.NewTestApplications() suite.testUsers = testrig.NewTestUsers() suite.testAccounts = testrig.NewTestAccounts() + suite.testAttachments = testrig.NewTestAttachments() } -// TearDownTest drops tables to make sure there's no data in the db func (suite *MediaCreateTestSuite) TearDownTest() { testrig.StandardDBTeardown(suite.db) + testrig.StandardStorageTeardown(suite.storage) } /* @@ -98,28 +94,42 @@ func (suite *MediaCreateTestSuite) TearDownTest() { func (suite *MediaCreateTestSuite) TestStatusCreatePOSTImageHandlerSuccessful() { + // set up the context for the request t := suite.testTokens["local_account_1"] oauthToken := oauth.PGTokenToOauthToken(t) - - // setup recorder := httptest.NewRecorder() ctx, _ := gin.CreateTestContext(recorder) ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) ctx.Set(oauth.SessionAuthorizedToken, oauthToken) ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"]) ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"]) - buf, w, err := testrig.CreateMultipartFormData("file", "../../media/test/test-jpeg.jpg", map[string]string{ + + // see what's in storage *before* the request + storageKeysBeforeRequest, err := suite.storage.ListKeys() + if err != nil { + panic(err) + } + + // create the request + buf, w, err := testrig.CreateMultipartFormData("file", "../../../testrig/media/test-jpeg.jpg", map[string]string{ "description": "this is a test image -- a cool background from somewhere", "focus": "-0.5,0.5", }) if err != nil { panic(err) } - ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", basePath), bytes.NewReader(buf.Bytes())) // the endpoint we're hitting ctx.Request.Header.Set("Content-Type", w.FormDataContentType()) + + // do the actual request suite.mediaModule.mediaCreatePOSTHandler(ctx) + // check what's in storage *after* the request + storageKeysAfterRequest, err := suite.storage.ListKeys() + if err != nil { + panic(err) + } + // check response suite.EqualValues(http.StatusAccepted, recorder.Code) @@ -157,6 +167,7 @@ func (suite *MediaCreateTestSuite) TestStatusCreatePOSTImageHandlerSuccessful() assert.NotEmpty(suite.T(), attachmentReply.ID) assert.NotEmpty(suite.T(), attachmentReply.URL) assert.NotEmpty(suite.T(), attachmentReply.PreviewURL) + assert.Equal(suite.T(), len(storageKeysBeforeRequest) + 2, len(storageKeysAfterRequest)) // 2 images should be added to storage: the original and the thumbnail } func TestMediaCreateTestSuite(t *testing.T) { diff --git a/internal/gotosocial/actions.go b/internal/gotosocial/actions.go index 1b3dbf6..2e745e7 100644 --- a/internal/gotosocial/actions.go +++ b/internal/gotosocial/actions.go @@ -31,6 +31,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/apimodule/account" "github.com/superseriousbusiness/gotosocial/internal/apimodule/app" "github.com/superseriousbusiness/gotosocial/internal/apimodule/auth" + mediaModule "github.com/superseriousbusiness/gotosocial/internal/apimodule/media" "github.com/superseriousbusiness/gotosocial/internal/cache" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" @@ -54,7 +55,7 @@ var Run action.GTSAction = func(ctx context.Context, c *config.Config, log *logr return fmt.Errorf("error creating router: %s", err) } - storageBackend, err := storage.NewInMem(c, log) + storageBackend, err := storage.NewLocal(c, log) if err != nil { return fmt.Errorf("error creating storage backend: %s", err) } @@ -70,11 +71,13 @@ var Run action.GTSAction = func(ctx context.Context, c *config.Config, log *logr authModule := auth.New(oauthServer, dbService, log) accountModule := account.New(c, dbService, oauthServer, mediaHandler, mastoConverter, log) appsModule := app.New(oauthServer, dbService, mastoConverter, log) + mm := mediaModule.New(dbService, mediaHandler, mastoConverter, c, log) apiModules := []apimodule.ClientAPIModule{ authModule, // this one has to go first so the other modules use its middleware accountModule, appsModule, + mm, } for _, m := range apiModules { diff --git a/internal/mastotypes/mock_Converter.go b/internal/mastotypes/mock_Converter.go index 881bc48..732d933 100644 --- a/internal/mastotypes/mock_Converter.go +++ b/internal/mastotypes/mock_Converter.go @@ -104,3 +104,45 @@ func (_m *MockConverter) AppToMastoSensitive(application *gtsmodel.Application) return r0, r1 } + +// AttachmentToMasto provides a mock function with given fields: attachment +func (_m *MockConverter) AttachmentToMasto(attachment *gtsmodel.MediaAttachment) (mastotypes.Attachment, error) { + ret := _m.Called(attachment) + + var r0 mastotypes.Attachment + if rf, ok := ret.Get(0).(func(*gtsmodel.MediaAttachment) mastotypes.Attachment); ok { + r0 = rf(attachment) + } else { + r0 = ret.Get(0).(mastotypes.Attachment) + } + + var r1 error + if rf, ok := ret.Get(1).(func(*gtsmodel.MediaAttachment) error); ok { + r1 = rf(attachment) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MentionToMasto provides a mock function with given fields: m +func (_m *MockConverter) MentionToMasto(m *gtsmodel.Mention) (mastotypes.Mention, error) { + ret := _m.Called(m) + + var r0 mastotypes.Mention + if rf, ok := ret.Get(0).(func(*gtsmodel.Mention) mastotypes.Mention); ok { + r0 = rf(m) + } else { + r0 = ret.Get(0).(mastotypes.Mention) + } + + var r1 error + if rf, ok := ret.Get(1).(func(*gtsmodel.Mention) error); ok { + r1 = rf(m) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/internal/media/mock_MediaHandler.go b/internal/media/mock_MediaHandler.go index 6f04f1f..1f87555 100644 --- a/internal/media/mock_MediaHandler.go +++ b/internal/media/mock_MediaHandler.go @@ -12,6 +12,29 @@ type MockMediaHandler struct { mock.Mock } +// ProcessAttachment provides a mock function with given fields: img, accountID +func (_m *MockMediaHandler) ProcessAttachment(img []byte, accountID string) (*gtsmodel.MediaAttachment, error) { + ret := _m.Called(img, accountID) + + var r0 *gtsmodel.MediaAttachment + if rf, ok := ret.Get(0).(func([]byte, string) *gtsmodel.MediaAttachment); ok { + r0 = rf(img, accountID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*gtsmodel.MediaAttachment) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func([]byte, string) error); ok { + r1 = rf(img, accountID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // SetHeaderOrAvatarForAccountID provides a mock function with given fields: img, accountID, headerOrAvi func (_m *MockMediaHandler) SetHeaderOrAvatarForAccountID(img []byte, accountID string, headerOrAvi string) (*gtsmodel.MediaAttachment, error) { ret := _m.Called(img, accountID, headerOrAvi) diff --git a/internal/storage/inmem.go b/internal/storage/inmem.go index 31c2bd9..976ddd7 100644 --- a/internal/storage/inmem.go +++ b/internal/storage/inmem.go @@ -15,22 +15,41 @@ import ( func NewInMem(c *config.Config, log *logrus.Logger) (Storage, error) { return &inMemStorage{ stored: make(map[string][]byte), + log: log, }, nil } type inMemStorage struct { stored map[string][]byte + log *logrus.Logger } func (s *inMemStorage) StoreFileAt(path string, data []byte) error { + l := s.log.WithField("func", "StoreFileAt") + l.Debugf("storing at path %s", path) s.stored[path] = data return nil } func (s *inMemStorage) RetrieveFileFrom(path string) ([]byte, error) { + l := s.log.WithField("func", "RetrieveFileFrom") + l.Debugf("retrieving from path %s", path) d, ok := s.stored[path] if !ok { return nil, fmt.Errorf("no data found at path %s", path) } return d, nil } + +func (s *inMemStorage)ListKeys() ([]string, error) { + keys := []string{} + for k := range s.stored { + keys = append(keys, k) + } + return keys, nil +} + +func (s *inMemStorage) RemoveFileAt(path string) error { + delete(s.stored, path) + return nil +} diff --git a/internal/storage/local.go b/internal/storage/local.go index 620467d..09a62be 100644 --- a/internal/storage/local.go +++ b/internal/storage/local.go @@ -1,6 +1,11 @@ package storage import ( + "fmt" + "os" + "path/filepath" + "strings" + "github.com/sirupsen/logrus" "github.com/superseriousbusiness/gotosocial/internal/config" ) @@ -8,16 +13,58 @@ import ( // NewLocal returns an implementation of the Storage interface that uses // the local filesystem for storing and retrieving files, attachments, etc. func NewLocal(c *config.Config, log *logrus.Logger) (Storage, error) { - return &localStorage{}, nil + return &localStorage{ + config: c, + log: log, + }, nil } type localStorage struct { + config *config.Config + log *logrus.Logger } func (s *localStorage) StoreFileAt(path string, data []byte) error { + l := s.log.WithField("func", "StoreFileAt") + l.Debugf("storing at path %s", path) + components := strings.Split(path, "/") + dir := strings.Join(components[0:len(components) - 1], "/") + if err := os.MkdirAll(dir, 0777); err != nil { + return fmt.Errorf("error writing file at %s: %s", path, err) + } + if err := os.WriteFile(path, data, 0777); err != nil { + return fmt.Errorf("error writing file at %s: %s", path, err) + } return nil } func (s *localStorage) RetrieveFileFrom(path string) ([]byte, error) { - return nil, nil + l := s.log.WithField("func", "RetrieveFileFrom") + l.Debugf("retrieving from path %s", path) + b, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("error reading file at %s: %s", path, err) + } + return b, nil +} + +func (s *localStorage) ListKeys() ([]string, error) { + keys := []string{} + err := filepath.Walk(s.config.StorageConfig.BasePath, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + keys = append(keys, path) + } + return nil + }) + if err != nil { + return nil, err + } + return keys, nil +} + +func (s *localStorage) RemoveFileAt(path string) error { + return os.Remove(path) } diff --git a/internal/storage/mock_Storage.go b/internal/storage/mock_Storage.go index 865d522..2444f03 100644 --- a/internal/storage/mock_Storage.go +++ b/internal/storage/mock_Storage.go @@ -9,6 +9,43 @@ type MockStorage struct { mock.Mock } +// ListKeys provides a mock function with given fields: +func (_m *MockStorage) ListKeys() ([]string, error) { + ret := _m.Called() + + var r0 []string + if rf, ok := ret.Get(0).(func() []string); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RemoveFileAt provides a mock function with given fields: path +func (_m *MockStorage) RemoveFileAt(path string) error { + ret := _m.Called(path) + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(path) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // RetrieveFileFrom provides a mock function with given fields: path func (_m *MockStorage) RetrieveFileFrom(path string) ([]byte, error) { ret := _m.Called(path) diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 7c85d0a..493c364 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -25,4 +25,6 @@ package storage type Storage interface { StoreFileAt(path string, data []byte) error RetrieveFileFrom(path string) ([]byte, error) + ListKeys() ([]string, error) + RemoveFileAt(path string) error } diff --git a/testrig/config.go b/testrig/config.go index 1bc0b8b..f7028b1 100644 --- a/testrig/config.go +++ b/testrig/config.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + package testrig import "github.com/superseriousbusiness/gotosocial/internal/config" diff --git a/testrig/db.go b/testrig/db.go index e930ba2..10025c9 100644 --- a/testrig/db.go +++ b/testrig/db.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + package testrig import ( diff --git a/testrig/log.go b/testrig/log.go new file mode 100644 index 0000000..0bafc96 --- /dev/null +++ b/testrig/log.go @@ -0,0 +1,28 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package testrig + +import "github.com/sirupsen/logrus" + +// NewTestLog returns a trace level logger for testing +func NewTestLog() *logrus.Logger { + log := logrus.New() + log.SetLevel(logrus.TraceLevel) + return log +} diff --git a/testrig/mastoconverter.go b/testrig/mastoconverter.go new file mode 100644 index 0000000..10bdbdc --- /dev/null +++ b/testrig/mastoconverter.go @@ -0,0 +1,29 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package testrig + +import ( + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/mastotypes" +) + +// NewTestMastoConverter returned a mastotypes converter with the given db and the default test config +func NewTestMastoConverter(db db.DB) mastotypes.Converter { + return mastotypes.New(NewTestConfig(), db) +} diff --git a/testrig/media/welcome-original.jpeg b/testrig/media/welcome-original.jpeg new file mode 100755 index 0000000000000000000000000000000000000000..1a54437ea5cb921c05e20bf35d49959f7ba4beca GIT binary patch literal 62529 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 literal 0 HcmV?d00001 diff --git a/testrig/mediahandler.go b/testrig/mediahandler.go new file mode 100644 index 0000000..fd79866 --- /dev/null +++ b/testrig/mediahandler.go @@ -0,0 +1,31 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package testrig + +import ( + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/media" + "github.com/superseriousbusiness/gotosocial/internal/storage" +) + +// NewTestMediaHandler returns a media handler with the default test config, the default test logger, +// and the given db and storage. +func NewTestMediaHandler(db db.DB, storage storage.Storage) media.MediaHandler { + return media.New(NewTestConfig(), db, storage, NewTestLog()) +} diff --git a/testrig/oauthserver.go b/testrig/oauthserver.go new file mode 100644 index 0000000..49615ca --- /dev/null +++ b/testrig/oauthserver.go @@ -0,0 +1,29 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package testrig + +import ( + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/oauth" +) + +// NewTestOauthServer returns an oauth server with the given db, and the default test logger. +func NewTestOauthServer(db db.DB) oauth.Server { + return oauth.New(db, NewTestLog()) +} diff --git a/testrig/storage.go b/testrig/storage.go index 3786b06..a17f620 100644 --- a/testrig/storage.go +++ b/testrig/storage.go @@ -1,24 +1,79 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + package testrig import ( - "github.com/sirupsen/logrus" - "github.com/superseriousbusiness/gotosocial/internal/config" + "fmt" + "os" + "strings" + "github.com/superseriousbusiness/gotosocial/internal/storage" ) -// NewTestStorage returns a new in memory storage with the given config -func NewTestStorage(c *config.Config, log *logrus.Logger) storage.Storage { - s, err := storage.NewInMem(c, log) +// NewTestStorage returns a new in memory storage with the default test config +func NewTestStorage() storage.Storage { + s, err := storage.NewInMem(NewTestConfig(), NewTestLog()) if err != nil { panic(err) } return s } -func StandardStorageSetup(s storage.Storage) { - +// StandardStorageSetup populates the storage with standard test entries from the given directory. +func StandardStorageSetup(s storage.Storage, relativePath string) { + stored := NewTestStored() + a := NewTestAttachments() + for k, fileNameTemplate := range stored { + attachmentInfo, ok := a[k] + if !ok { + panic(fmt.Errorf("key %s not found in test attachments", k)) + } + filenameOriginal := strings.Replace(fileNameTemplate, "*", "original", 1) + filenameSmall := strings.Replace(fileNameTemplate, "*", "small", 1) + pathOriginal := attachmentInfo.File.Path + pathSmall := attachmentInfo.Thumbnail.Path + bOriginal, err := os.ReadFile(fmt.Sprintf("%s/%s", relativePath, filenameOriginal)) + if err != nil { + panic(err) + } + if err := s.StoreFileAt(pathOriginal, bOriginal); err != nil { + panic(err) + } + bSmall, err := os.ReadFile(fmt.Sprintf("%s/%s", relativePath, filenameSmall)) + if err != nil { + panic(err) + } + if err := s.StoreFileAt(pathSmall, bSmall); err != nil { + panic(err) + } + } } +// StandardStorageTeardown deletes everything in storage so that it's clean for the next test func StandardStorageTeardown(s storage.Storage) { - + keys, err := s.ListKeys() + if err != nil { + panic(err) + } + for _, k := range keys { + if err := s.RemoveFileAt(k); err != nil { + panic(err) + } + } } diff --git a/testrig/models.go b/testrig/testmodels.go similarity index 87% rename from testrig/models.go rename to testrig/testmodels.go index 9606199..65358eb 100644 --- a/testrig/models.go +++ b/testrig/testmodels.go @@ -1,3 +1,21 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + package testrig import ( @@ -10,6 +28,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/oauth" ) +// NewTestTokens returns a map of tokens keyed according to which account the token belongs to. func NewTestTokens() map[string]*oauth.Token { tokens := map[string]*oauth.Token{ "local_account_1": { @@ -26,6 +45,7 @@ func NewTestTokens() map[string]*oauth.Token { return tokens } +// NewTestClients returns a map of Clients keyed according to which account they are used by. func NewTestClients() map[string]*oauth.Client { clients := map[string]*oauth.Client{ "local_account_1": { @@ -38,6 +58,7 @@ func NewTestClients() map[string]*oauth.Client { return clients } +// NewTestApplications returns a map of applications keyed to which number application they are. func NewTestApplications() map[string]*gtsmodel.Application { apps := map[string]*gtsmodel.Application{ "application_1": { @@ -54,6 +75,7 @@ func NewTestApplications() map[string]*gtsmodel.Application { return apps } +// NewTestUsers returns a map of Users keyed by which account belongs to them. func NewTestUsers() map[string]*gtsmodel.User { users := map[string]*gtsmodel.User{ "unconfirmed_account": { @@ -181,6 +203,7 @@ func NewTestUsers() map[string]*gtsmodel.User { return users } +// NewTestAccounts returns a map of accounts keyed by what type of account they are. func NewTestAccounts() map[string]*gtsmodel.Account { accounts := map[string]*gtsmodel.Account{ "unconfirmed_account": { @@ -440,14 +463,66 @@ func NewTestAccounts() map[string]*gtsmodel.Account { return accounts } +// NewTestAttachments returns a map of attachments keyed according to which account +// and status they belong to, and which attachment number of that status they are. func NewTestAttachments() map[string]*gtsmodel.MediaAttachment { return map[string]*gtsmodel.MediaAttachment{ - // "admin_account_status_1": { - - // }, + "admin_account_status_1_attachment_1": { + ID: "b052241b-f30f-4dc6-92fc-2bad0be1f8d8", + StatusID: "502ccd6f-0edf-48d7-9016-2dfa4d3714cd", + URL: "http://localhost:8080/fileserver/8020dbb4-1e7b-4d99-a872-4cf94e64210f/attachment/original/b052241b-f30f-4dc6-92fc-2bad0be1f8d8.jpeg", + RemoteURL: "", + CreatedAt: time.Now().Add(-71 * time.Hour), + UpdatedAt: time.Now().Add(-71 * time.Hour), + Type: gtsmodel.FileTypeImage, + FileMeta: gtsmodel.FileMeta{ + Original: gtsmodel.Original{ + Width: 1200, + Height: 630, + Size: 756000, + Aspect: 1.9047619047619047, + }, + Small: gtsmodel.Small{ + Width: 256, + Height: 134, + Size: 34304, + Aspect: 1.9104477611940298, + }, + }, + AccountID: "8020dbb4-1e7b-4d99-a872-4cf94e64210f", + Description: "Black and white image of some 50's style text saying: Welcome On Board", + ScheduledStatusID: "", + Blurhash: "LNJRdVM{00Rj%Mayt7j[4nWBofRj", + Processing: 2, + File: gtsmodel.File{ + Path: "/gotosocial/storage/8020dbb4-1e7b-4d99-a872-4cf94e64210f/attachment/original/b052241b-f30f-4dc6-92fc-2bad0be1f8d8.jpeg", + ContentType: "image/jpeg", + FileSize: 62529, + UpdatedAt: time.Now().Add(-71 * time.Hour), + }, + Thumbnail: gtsmodel.Thumbnail{ + Path: "/gotosocial/storage/8020dbb4-1e7b-4d99-a872-4cf94e64210f/attachment/small/b052241b-f30f-4dc6-92fc-2bad0be1f8d8.jpeg", + ContentType: "image/jpeg", + FileSize: 6872, + UpdatedAt: time.Now().Add(-71 * time.Hour), + URL: "http://localhost:8080/fileserver/8020dbb4-1e7b-4d99-a872-4cf94e64210f/attachment/small/b052241b-f30f-4dc6-92fc-2bad0be1f8d8.jpeg", + RemoteURL: "", + }, + Avatar: false, + Header: false, + }, } } +// NewTestStored returns a map of filenames, keyed according to which attachment they pertain to. +func NewTestStored() map[string]string { + return map[string]string { + "admin_account_status_1_attachment_1": "welcome-*.jpeg", + } +} + +// NewTestStatuses returns a map of statuses keyed according to which account +// and status they are. func NewTestStatuses() map[string]*gtsmodel.Status { return map[string]*gtsmodel.Status{ "admin_account_status_1": {