diff --git a/internal/apimodule/mock_ClientAPIModule.go b/internal/apimodule/mock_ClientAPIModule.go index 85c7b6a..2d4293d 100644 --- a/internal/apimodule/mock_ClientAPIModule.go +++ b/internal/apimodule/mock_ClientAPIModule.go @@ -4,6 +4,8 @@ package apimodule import ( mock "github.com/stretchr/testify/mock" + db "github.com/superseriousbusiness/gotosocial/internal/db" + router "github.com/superseriousbusiness/gotosocial/internal/router" ) @@ -12,6 +14,20 @@ type MockClientAPIModule struct { mock.Mock } +// CreateTables provides a mock function with given fields: _a0 +func (_m *MockClientAPIModule) CreateTables(_a0 db.DB) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(db.DB) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // Route provides a mock function with given fields: s func (_m *MockClientAPIModule) Route(s router.Router) error { ret := _m.Called(s) diff --git a/internal/apimodule/status/statuscreate.go b/internal/apimodule/status/statuscreate.go index 4a39615..fd20280 100644 --- a/internal/apimodule/status/statuscreate.go +++ b/internal/apimodule/status/statuscreate.go @@ -99,12 +99,15 @@ func (m *statusModule) statusCreatePOSTHandler(c *gin.Context) { ID: thisStatusID, URI: thisStatusURI, URL: thisStatusURL, + Content: util.HTMLFormat(form.Status), CreatedAt: time.Now(), UpdatedAt: time.Now(), Local: true, AccountID: authed.Account.ID, ContentWarning: form.SpoilerText, ActivityStreamsType: model.ActivityStreamsNote, + Sensitive: form.Sensitive, + Language: form.Language, } // check if replyToID is ok @@ -166,12 +169,28 @@ func (m *statusModule) statusCreatePOSTHandler(c *gin.Context) { } // return populated status to submitter - // mastoStatus := &mastotypes.Status{ - // ID: newStatus.ID, - // CreatedAt: time.Now().Format(time.RFC3339), - // InReplyToID: newStatus.InReplyToID, - // // InReplyToAccountID: newStatus., - // } + mastoAccount, err := m.db.AccountToMastoPublic(authed.Account) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + mastoStatus := &mastotypes.Status{ + ID: newStatus.ID, + CreatedAt: newStatus.CreatedAt.Format(time.RFC3339), + InReplyToID: newStatus.InReplyToID, + // InReplyToAccountID: newStatus.ReplyToAccount.ID, + Sensitive: newStatus.Sensitive, + SpoilerText: newStatus.ContentWarning, + Visibility: util.ParseMastoVisFromGTSVis(newStatus.Visibility), + Language: newStatus.Language, + URI: newStatus.URI, + URL: newStatus.URL, + Content: newStatus.Content, + Application: authed.Application.ToMasto(), + Account: mastoAccount, + Text: form.Status, + } + c.JSON(http.StatusOK, mastoStatus) } func validateCreateStatus(form *advancedStatusCreateForm, config *config.StatusesConfig) error { diff --git a/internal/apimodule/status/statuscreate_test.go b/internal/apimodule/status/statuscreate_test.go new file mode 100644 index 0000000..e447f8b --- /dev/null +++ b/internal/apimodule/status/statuscreate_test.go @@ -0,0 +1,214 @@ +/* + 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 status + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/db/model" + "github.com/superseriousbusiness/gotosocial/internal/distributor" + "github.com/superseriousbusiness/gotosocial/internal/media" + "github.com/superseriousbusiness/gotosocial/internal/oauth" + "github.com/superseriousbusiness/gotosocial/internal/storage" + "github.com/superseriousbusiness/gotosocial/pkg/mastotypes" + "github.com/superseriousbusiness/gotosocial/testrig" +) + +type StatusCreateTestSuite struct { + suite.Suite + config *config.Config + mockOauthServer *oauth.MockServer + mockStorage *storage.MockStorage + mediaHandler media.MediaHandler + distributor *distributor.MockDistributor + testTokens map[string]*oauth.Token + testClients map[string]*oauth.Client + testApplications map[string]*model.Application + testUsers map[string]*model.User + testAccounts map[string]*model.Account + log *logrus.Logger + db db.DB + statusModule *statusModule +} + +/* + TEST INFRASTRUCTURE +*/ + +// SetupSuite sets some variables on the suite that we can use as consts (more or less) throughout +func (suite *StatusCreateTestSuite) 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 + c := config.Empty() + c.Protocol = "http" + c.Host = "localhost" + c.DBConfig = &config.DBConfig{ + Type: "postgres", + Address: "localhost", + Port: 5432, + User: "postgres", + Password: "postgres", + Database: "postgres", + ApplicationName: "gotosocial", + } + c.MediaConfig = &config.MediaConfig{ + MaxImageSize: 2 << 20, + } + c.StorageConfig = &config.StorageConfig{ + Backend: "local", + BasePath: "/tmp", + ServeProtocol: "http", + ServeHost: "localhost", + ServeBasePath: "/fileserver/media", + } + c.StatusesConfig = &config.StatusesConfig{ + MaxChars: 500, + CWMaxChars: 50, + PollMaxOptions: 4, + PollOptionMaxChars: 50, + MaxMediaFiles: 4, + } + suite.config = c + + // use an actual database for this, because it's just easier than mocking one out + database, err := db.New(context.Background(), c, log) + if err != nil { + suite.FailNow(err.Error()) + } + suite.db = database + + suite.mockOauthServer = &oauth.MockServer{} + suite.mockStorage = &storage.MockStorage{} + suite.mediaHandler = media.New(suite.config, suite.db, suite.mockStorage, log) + suite.distributor = &distributor.MockDistributor{} + suite.distributor.On("FromClientAPI").Return(make(chan distributor.FromClientAPI, 100)) + + suite.statusModule = New(suite.config, suite.db, suite.mockOauthServer, suite.mediaHandler, suite.distributor, suite.log).(*statusModule) +} + +func (suite *StatusCreateTestSuite) TearDownSuite() { + if err := suite.db.Stop(context.Background()); err != nil { + logrus.Panicf("error closing db connection: %s", err) + } +} + +func (suite *StatusCreateTestSuite) SetupTest() { + if err := testrig.StandardDBSetup(suite.db); err != nil { + panic(err) + } + suite.testTokens = testrig.TestTokens() + suite.testClients = testrig.TestClients() + suite.testApplications = testrig.TestApplications() + suite.testUsers = testrig.TestUsers() + suite.testAccounts = testrig.TestAccounts() +} + +// TearDownTest drops tables to make sure there's no data in the db +func (suite *StatusCreateTestSuite) TearDownTest() { + if err := testrig.StandardDBTeardown(suite.db); err != nil { + panic(err) + } +} + +/* + ACTUAL TESTS +*/ + +/* + TESTING: StatusCreatePOSTHandler +*/ + +func (suite *StatusCreateTestSuite) TestStatusCreatePOSTHandlerSuccessful() { + + 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"]) + ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", basePath), nil) // the endpoint we're hitting + ctx.Request.Form = url.Values{ + "status": {"this is a brand new status!"}, + "spoiler_text": {"hello hello"}, + "sensitive": {"true"}, + "visibility": {"public"}, + // Status string `form:"status"` + // // Array of Attachment ids to be attached as media. If provided, status becomes optional, and poll cannot be used. + // MediaIDs []string `form:"media_ids"` + // // Poll to include with this status. + // Poll *PollRequest `form:"poll"` + // // ID of the status being replied to, if status is a reply + // InReplyToID string `form:"in_reply_to_id"` + // // Mark status and attached media as sensitive? + // Sensitive bool `form:"sensitive"` + // // Text to be shown as a warning or subject before the actual content. Statuses are generally collapsed behind this field. + // SpoilerText string `form:"spoiler_text"` + // // Visibility of the posted status. Enumerable oneOf public, unlisted, private, direct. + // Visibility Visibility `form:"visibility"` + // // ISO 8601 Datetime at which to schedule a status. Providing this paramter will cause ScheduledStatus to be returned instead of Status. Must be at least 5 minutes in the future. + // ScheduledAt string `form:"scheduled_at"` + // // ISO 639 language code for this status. + // Language string `form:"language"` + } + suite.statusModule.statusCreatePOSTHandler(ctx) + + // check response + + // 1. we should have OK from our call to the function + suite.EqualValues(http.StatusOK, recorder.Code) + + result := recorder.Result() + defer result.Body.Close() + b, err := ioutil.ReadAll(result.Body) + assert.NoError(suite.T(), err) + + statusReply := &mastotypes.Status{} + err = json.Unmarshal(b, statusReply) + assert.NoError(suite.T(), err) + + assert.Equal(suite.T(), "hello hello", statusReply.SpoilerText) + assert.Equal(suite.T(), "this is a brand new status!", statusReply.Content) + assert.True(suite.T(), statusReply.Sensitive) + assert.Equal(suite.T(), mastotypes.VisibilityPublic, statusReply.Visibility) +} + +func TestStatusCreateTestSuite(t *testing.T) { + suite.Run(t, new(StatusCreateTestSuite)) +} diff --git a/internal/db/mock_DB.go b/internal/db/mock_DB.go index d4c25bb..8d0932c 100644 --- a/internal/db/mock_DB.go +++ b/internal/db/mock_DB.go @@ -20,6 +20,29 @@ type MockDB struct { mock.Mock } +// AccountToMastoPublic provides a mock function with given fields: account +func (_m *MockDB) AccountToMastoPublic(account *model.Account) (*mastotypes.Account, error) { + ret := _m.Called(account) + + var r0 *mastotypes.Account + if rf, ok := ret.Get(0).(func(*model.Account) *mastotypes.Account); ok { + r0 = rf(account) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*mastotypes.Account) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*model.Account) error); ok { + r1 = rf(account) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // AccountToMastoSensitive provides a mock function with given fields: account func (_m *MockDB) AccountToMastoSensitive(account *model.Account) (*mastotypes.Account, error) { ret := _m.Called(account) @@ -43,6 +66,27 @@ func (_m *MockDB) AccountToMastoSensitive(account *model.Account) (*mastotypes.A return r0, r1 } +// Blocked provides a mock function with given fields: account1, account2 +func (_m *MockDB) Blocked(account1 string, account2 string) (bool, error) { + ret := _m.Called(account1, account2) + + var r0 bool + if rf, ok := ret.Get(0).(func(string, string) bool); ok { + r0 = rf(account1, account2) + } else { + r0 = ret.Get(0).(bool) + } + + var r1 error + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(account1, account2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // CreateTable provides a mock function with given fields: i func (_m *MockDB) CreateTable(i interface{}) error { ret := _m.Called(i) @@ -99,6 +143,29 @@ func (_m *MockDB) DropTable(i interface{}) error { return r0 } +// EmojiStringsToEmojis provides a mock function with given fields: emojis, originAccountID, statusID +func (_m *MockDB) EmojiStringsToEmojis(emojis []string, originAccountID string, statusID string) ([]*model.Emoji, error) { + ret := _m.Called(emojis, originAccountID, statusID) + + var r0 []*model.Emoji + if rf, ok := ret.Get(0).(func([]string, string, string) []*model.Emoji); ok { + r0 = rf(emojis, originAccountID, statusID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*model.Emoji) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func([]string, string, string) error); ok { + r1 = rf(emojis, originAccountID, statusID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // Federation provides a mock function with given fields: func (_m *MockDB) Federation() pub.Database { ret := _m.Called() @@ -143,6 +210,20 @@ func (_m *MockDB) GetAll(i interface{}) error { return r0 } +// GetAvatarForAccountID provides a mock function with given fields: avatar, accountID +func (_m *MockDB) GetAvatarForAccountID(avatar *model.MediaAttachment, accountID string) error { + ret := _m.Called(avatar, accountID) + + var r0 error + if rf, ok := ret.Get(0).(func(*model.MediaAttachment, string) error); ok { + r0 = rf(avatar, accountID) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // GetByID provides a mock function with given fields: id, i func (_m *MockDB) GetByID(id string, i interface{}) error { ret := _m.Called(id, i) @@ -199,6 +280,20 @@ func (_m *MockDB) GetFollowingByAccountID(accountID string, following *[]model.F return r0 } +// GetHeaderForAccountID provides a mock function with given fields: header, accountID +func (_m *MockDB) GetHeaderForAccountID(header *model.MediaAttachment, accountID string) error { + ret := _m.Called(header, accountID) + + var r0 error + if rf, ok := ret.Get(0).(func(*model.MediaAttachment, string) error); ok { + r0 = rf(header, accountID) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // GetLastStatusForAccountID provides a mock function with given fields: accountID, status func (_m *MockDB) GetLastStatusForAccountID(accountID string, status *model.Status) error { ret := _m.Called(accountID, status) @@ -297,6 +392,29 @@ func (_m *MockDB) IsUsernameAvailable(username string) error { return r0 } +// MentionStringsToMentions provides a mock function with given fields: targetAccounts, originAccountID, statusID +func (_m *MockDB) MentionStringsToMentions(targetAccounts []string, originAccountID string, statusID string) ([]*model.Mention, error) { + ret := _m.Called(targetAccounts, originAccountID, statusID) + + var r0 []*model.Mention + if rf, ok := ret.Get(0).(func([]string, string, string) []*model.Mention); ok { + r0 = rf(targetAccounts, originAccountID, statusID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*model.Mention) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func([]string, string, string) error); ok { + r1 = rf(targetAccounts, originAccountID, statusID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewSignup provides a mock function with given fields: username, reason, requireApproval, email, password, signUpIP, locale, appID func (_m *MockDB) NewSignup(username string, reason string, requireApproval bool, email string, password string, signUpIP net.IP, locale string, appID string) (*model.User, error) { ret := _m.Called(username, reason, requireApproval, email, password, signUpIP, locale, appID) @@ -334,6 +452,20 @@ func (_m *MockDB) Put(i interface{}) error { return r0 } +// SetHeaderOrAvatarForAccountID provides a mock function with given fields: mediaAttachment, accountID +func (_m *MockDB) SetHeaderOrAvatarForAccountID(mediaAttachment *model.MediaAttachment, accountID string) error { + ret := _m.Called(mediaAttachment, accountID) + + var r0 error + if rf, ok := ret.Get(0).(func(*model.MediaAttachment, string) error); ok { + r0 = rf(mediaAttachment, accountID) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // Stop provides a mock function with given fields: ctx func (_m *MockDB) Stop(ctx context.Context) error { ret := _m.Called(ctx) @@ -348,6 +480,29 @@ func (_m *MockDB) Stop(ctx context.Context) error { return r0 } +// TagStringsToTags provides a mock function with given fields: tags, originAccountID, statusID +func (_m *MockDB) TagStringsToTags(tags []string, originAccountID string, statusID string) ([]*model.Tag, error) { + ret := _m.Called(tags, originAccountID, statusID) + + var r0 []*model.Tag + if rf, ok := ret.Get(0).(func([]string, string, string) []*model.Tag); ok { + r0 = rf(tags, originAccountID, statusID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*model.Tag) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func([]string, string, string) error); ok { + r1 = rf(tags, originAccountID, statusID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // UpdateByID provides a mock function with given fields: id, i func (_m *MockDB) UpdateByID(id string, i interface{}) error { ret := _m.Called(id, i) @@ -361,3 +516,17 @@ func (_m *MockDB) UpdateByID(id string, i interface{}) error { return r0 } + +// UpdateOneByID provides a mock function with given fields: id, key, value, i +func (_m *MockDB) UpdateOneByID(id string, key string, value interface{}, i interface{}) error { + ret := _m.Called(id, key, value, i) + + var r0 error + if rf, ok := ret.Get(0).(func(string, string, interface{}, interface{}) error); ok { + r0 = rf(id, key, value, i) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/internal/db/model/status.go b/internal/db/model/status.go index 702f95a..b0e9ab0 100644 --- a/internal/db/model/status.go +++ b/internal/db/model/status.go @@ -46,6 +46,10 @@ type Status struct { ContentWarning string // visibility entry for this status Visibility Visibility + // mark the status as sensitive? + Sensitive bool + // what language is this status written in? + Language string // advanced visibility for this status VisibilityAdvanced *VisibilityAdvanced // What is the activitystreams type of this status? See: https://www.w3.org/TR/activitystreams-vocabulary/#object-types diff --git a/internal/distributor/mock_Distributor.go b/internal/distributor/mock_Distributor.go index 93d7dd8..42248c3 100644 --- a/internal/distributor/mock_Distributor.go +++ b/internal/distributor/mock_Distributor.go @@ -9,32 +9,16 @@ type MockDistributor struct { mock.Mock } -// ClientAPIIn provides a mock function with given fields: -func (_m *MockDistributor) ClientAPIIn() chan interface{} { +// FromClientAPI provides a mock function with given fields: +func (_m *MockDistributor) FromClientAPI() chan FromClientAPI { ret := _m.Called() - var r0 chan interface{} - if rf, ok := ret.Get(0).(func() chan interface{}); ok { + var r0 chan FromClientAPI + if rf, ok := ret.Get(0).(func() chan FromClientAPI); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(chan interface{}) - } - } - - return r0 -} - -// ClientAPIOut provides a mock function with given fields: -func (_m *MockDistributor) ClientAPIOut() chan interface{} { - ret := _m.Called() - - var r0 chan interface{} - if rf, ok := ret.Get(0).(func() chan interface{}); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(chan interface{}) + r0 = ret.Get(0).(chan FromClientAPI) } } @@ -68,3 +52,19 @@ func (_m *MockDistributor) Stop() error { return r0 } + +// ToClientAPI provides a mock function with given fields: +func (_m *MockDistributor) ToClientAPI() chan ToClientAPI { + ret := _m.Called() + + var r0 chan ToClientAPI + if rf, ok := ret.Get(0).(func() chan ToClientAPI); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(chan ToClientAPI) + } + } + + return r0 +} diff --git a/internal/gotosocial/mock_Gotosocial.go b/internal/gotosocial/mock_Gotosocial.go index 8aca69b..66f776e 100644 --- a/internal/gotosocial/mock_Gotosocial.go +++ b/internal/gotosocial/mock_Gotosocial.go @@ -26,3 +26,17 @@ func (_m *MockGotosocial) Start(_a0 context.Context) error { return r0 } + +// Stop provides a mock function with given fields: _a0 +func (_m *MockGotosocial) Stop(_a0 context.Context) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/internal/oauth/tokenstore.go b/internal/oauth/tokenstore.go index c4c9ff1..14caa65 100644 --- a/internal/oauth/tokenstore.go +++ b/internal/oauth/tokenstore.go @@ -98,7 +98,7 @@ func (pts *tokenStore) Create(ctx context.Context, info oauth2.TokenInfo) error if !ok { return errors.New("info param was not a models.Token") } - if err := pts.db.Put(oauthTokenToPGToken(t)); err != nil { + if err := pts.db.Put(OAuthTokenToPGToken(t)); err != nil { return fmt.Errorf("error in tokenstore create: %s", err) } return nil @@ -130,7 +130,7 @@ func (pts *tokenStore) GetByCode(ctx context.Context, code string) (oauth2.Token if err := pts.db.GetWhere("code", code, pgt); err != nil { return nil, err } - return pgTokenToOauthToken(pgt), nil + return PGTokenToOauthToken(pgt), nil } // GetByAccess selects a token from the DB based on the Access field @@ -144,7 +144,7 @@ func (pts *tokenStore) GetByAccess(ctx context.Context, access string) (oauth2.T if err := pts.db.GetWhere("access", access, pgt); err != nil { return nil, err } - return pgTokenToOauthToken(pgt), nil + return PGTokenToOauthToken(pgt), nil } // GetByRefresh selects a token from the DB based on the Refresh field @@ -158,7 +158,7 @@ func (pts *tokenStore) GetByRefresh(ctx context.Context, refresh string) (oauth2 if err := pts.db.GetWhere("refresh", refresh, pgt); err != nil { return nil, err } - return pgTokenToOauthToken(pgt), nil + return PGTokenToOauthToken(pgt), nil } /* @@ -194,8 +194,8 @@ type Token struct { RefreshExpiresAt time.Time `pg:"type:timestamp"` } -// oauthTokenToPGToken is a lil util function that takes a gotosocial token and gives back a token for inserting into postgres -func oauthTokenToPGToken(tkn *models.Token) *Token { +// OAuthTokenToPGToken is a lil util function that takes a gotosocial token and gives back a token for inserting into postgres +func OAuthTokenToPGToken(tkn *models.Token) *Token { now := time.Now() // For the following, we want to make sure we're not adding a time.Now() to an *empty* ExpiresIn, otherwise that's @@ -236,8 +236,8 @@ func oauthTokenToPGToken(tkn *models.Token) *Token { } } -// pgTokenToOauthToken is a lil util function that takes a postgres token and gives back a gotosocial token -func pgTokenToOauthToken(pgt *Token) *models.Token { +// PGTokenToOauthToken is a lil util function that takes a postgres token and gives back a gotosocial token +func PGTokenToOauthToken(pgt *Token) *models.Token { now := time.Now() return &models.Token{ diff --git a/testrig/db.go b/testrig/db.go index 8f3aee0..fc2401e 100644 --- a/testrig/db.go +++ b/testrig/db.go @@ -30,6 +30,37 @@ func StandardDBSetup(db db.DB) error { return err } } + + for _, v := range TestTokens() { + if err := db.Put(v); err != nil { + return err + } + } + + for _, v := range TestClients() { + if err := db.Put(v); err != nil { + return err + } + } + + for _, v := range TestApplications() { + if err := db.Put(v); err != nil { + return err + } + } + + for _, v := range TestUsers() { + if err := db.Put(v); err != nil { + return err + } + } + + for _, v := range TestAccounts() { + if err := db.Put(v); err != nil { + return err + } + } + return nil } diff --git a/testrig/models.go b/testrig/models.go index 4fb2b25..7a59ba8 100644 --- a/testrig/models.go +++ b/testrig/models.go @@ -13,7 +13,14 @@ import ( func TestTokens() map[string]*oauth.Token { tokens := map[string]*oauth.Token{ "local_account_1": { - + ID: "64cf4214-33ab-4220-b5ca-4a6a12263b20", + ClientID: "73b48d42-029d-4487-80fc-329a5cf67869", + UserID: "44e36b79-44a4-4bd8-91e9-097f477fe97b", + RedirectURI: "http://localhost:8080", + Scope: "read write follow push", + Access: "NZAZOTC0OWITMDU0NC0ZODG4LWE4NJITMWUXM2M4MTRHZDEX", + AccessCreateAt: time.Now(), + AccessExpiresAt: time.Now().Add(72 * time.Hour), }, } return tokens @@ -126,7 +133,7 @@ func TestUsers() map[string]*model.User { ChosenLanguages: []string{"en"}, FilteredLanguages: []string{}, Locale: "en", - CreatedByApplicationID: "", + CreatedByApplicationID: "f88697b8-ee3d-46c2-ac3f-dbb85566c3cc", LastEmailedAt: time.Now().Add(-55 * time.Minute), ConfirmationToken: "", ConfirmedAt: time.Now().Add(-34 * time.Hour), @@ -203,14 +210,14 @@ func TestAccounts() map[string]*model.Account { Privacy: model.VisibilityPublic, Sensitive: false, Language: "en", - URI: "http://localhost:8080/users/admin", - URL: "http://localhost:8080/@admin", + URI: "http://localhost:8080/users/weed_lord420", + URL: "http://localhost:8080/@weed_lord420", LastWebfingeredAt: time.Time{}, - InboxURL: "http://localhost:8080/users/admin/inbox", - OutboxURL: "http://localhost:8080/users/admin/outbox", + InboxURL: "http://localhost:8080/users/weed_lord420/inbox", + OutboxURL: "http://localhost:8080/users/weed_lord420/outbox", SharedInboxURL: "", - FollowersURL: "http://localhost:8080/users/admin/followers", - FeaturedCollectionURL: "http://localhost:8080/users/admin/collections/featured", + FollowersURL: "http://localhost:8080/users/weed_lord420/followers", + FeaturedCollectionURL: "http://localhost:8080/users/weed_lord420/collections/featured", ActorType: model.ActivityStreamsPerson, AlsoKnownAs: "", PrivateKey: &rsa.PrivateKey{}, @@ -360,21 +367,61 @@ func TestAccounts() map[string]*model.Account { ID: "c2c6e647-e2a9-4286-883b-e4a188186664", Username: "foss_satan", Domain: "fossbros-anonymous.io", + // AvatarFileName: "http://localhost:8080/fileserver/media/eecaad73-5703-426d-9312-276641daa31e/avatar/original/d5e7c265-91a6-4d84-8c27-7e1efe5720da.jpeg", + // AvatarContentType: "image/jpeg", + // AvatarFileSize: 0, + // AvatarUpdatedAt: time.Time{}, + // AvatarRemoteURL: "", + // HeaderFileName: "http://localhost:8080/fileserver/media/eecaad73-5703-426d-9312-276641daa31e/header/original/e75d4117-21b6-4315-a428-eb3944235996.jpeg", + // HeaderContentType: "image/jpeg", + // HeaderFileSize: 0, + // HeaderUpdatedAt: time.Time{}, + // HeaderRemoteURL: "", + DisplayName: "big gerald", + Fields: []model.Field{}, + Note: "", + Memorial: false, + MovedToAccountID: "", + CreatedAt: time.Now().Add(-190 * time.Hour), + UpdatedAt: time.Now().Add(-36 * time.Hour), + Bot: false, + Reason: "", + Locked: false, + Discoverable: true, + Sensitive: false, + Language: "en", + URI: "https://fossbros-anonymous.io/users/foss_satan", + URL: "https://fossbros-anonymous.io/@foss_satan", + LastWebfingeredAt: time.Time{}, + InboxURL: "https://fossbros-anonymous.io/users/foss_satan/inbox", + OutboxURL: "https://fossbros-anonymous.io/users/foss_satan/outbox", + SharedInboxURL: "", + FollowersURL: "https://fossbros-anonymous.io/users/foss_satan/followers", + FeaturedCollectionURL: "https://fossbros-anonymous.io/users/foss_satan/collections/featured", + ActorType: model.ActivityStreamsPerson, + AlsoKnownAs: "", + PrivateKey: &rsa.PrivateKey{}, + PublicKey: nil, + SensitizedAt: time.Time{}, + SilencedAt: time.Time{}, + SuspendedAt: time.Time{}, + HideCollections: false, + SuspensionOrigin: "", }, - "remote_account_2": { - ID: "93287988-76c4-460f-9e68-a45b578bb6b2", - Username: "dailycatpics", - Domain: "uwu.social", - }, - "suspended_local_account": { - ID: "e8a5cf4e-4b10-45a4-ad82-b6e37a09100d", - Username: "jeffbadman", - }, - "suspended_remote_account": { - ID: "17e6e09e-855d-4bf8-a1c3-7e780269f215", - Username: "ipfreely", - Domain: "a-very-bad-website.com", - }, + // "remote_account_2": { + // ID: "93287988-76c4-460f-9e68-a45b578bb6b2", + // Username: "dailycatpics", + // Domain: "uwu.social", + // }, + // "suspended_local_account": { + // ID: "e8a5cf4e-4b10-45a4-ad82-b6e37a09100d", + // Username: "jeffbadman", + // }, + // "suspended_remote_account": { + // ID: "17e6e09e-855d-4bf8-a1c3-7e780269f215", + // Username: "ipfreely", + // Domain: "a-very-bad-website.com", + // }, } // generate keys for each account