mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-10 11:28:06 -06:00
phew
This commit is contained in:
parent
82437a768b
commit
ba84852d3e
19 changed files with 999 additions and 262 deletions
|
|
@ -21,7 +21,9 @@ package status
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/apimodule"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
|
@ -77,7 +79,7 @@ func New(config *config.Config, db db.DB, oauthServer oauth.Server, mediaHandler
|
|||
// Route attaches all routes from this module to the given router
|
||||
func (m *statusModule) Route(r router.Router) error {
|
||||
r.AttachHandler(http.MethodPost, basePath, m.statusCreatePOSTHandler)
|
||||
// r.AttachHandler(http.MethodGet, basePathWithID, m.muxHandler)
|
||||
r.AttachHandler(http.MethodGet, basePathWithID, m.muxHandler)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +91,10 @@ func (m *statusModule) CreateTables(db db.DB) error {
|
|||
>smodel.Follow{},
|
||||
>smodel.FollowRequest{},
|
||||
>smodel.Status{},
|
||||
>smodel.StatusFave{},
|
||||
>smodel.StatusBookmark{},
|
||||
>smodel.StatusMute{},
|
||||
>smodel.StatusPin{},
|
||||
>smodel.Application{},
|
||||
>smodel.EmailDomainBlock{},
|
||||
>smodel.MediaAttachment{},
|
||||
|
|
@ -105,13 +111,14 @@ func (m *statusModule) CreateTables(db db.DB) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// func (m *statusModule) muxHandler(c *gin.Context) {
|
||||
// ru := c.Request.RequestURI
|
||||
// if strings.HasPrefix(ru, verifyPath) {
|
||||
// m.accountVerifyGETHandler(c)
|
||||
// } else if strings.HasPrefix(ru, updateCredentialsPath) {
|
||||
// m.accountUpdateCredentialsPATCHHandler(c)
|
||||
// } else {
|
||||
// m.accountGETHandler(c)
|
||||
// }
|
||||
// }
|
||||
func (m *statusModule) muxHandler(c *gin.Context) {
|
||||
m.log.Debug("entering mux handler")
|
||||
ru := c.Request.RequestURI
|
||||
if strings.HasPrefix(ru, contextPath) {
|
||||
// TODO
|
||||
} else if strings.HasPrefix(ru, rebloggedPath) {
|
||||
// TODO
|
||||
} else {
|
||||
m.statusGETHandler(c)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,18 +97,20 @@ func (m *statusModule) statusCreatePOSTHandler(c *gin.Context) {
|
|||
thisStatusURI := fmt.Sprintf("%s/%s", uris.StatusesURI, thisStatusID)
|
||||
thisStatusURL := fmt.Sprintf("%s/%s", uris.StatusesURL, thisStatusID)
|
||||
newStatus := >smodel.Status{
|
||||
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: gtsmodel.ActivityStreamsNote,
|
||||
Sensitive: form.Sensitive,
|
||||
Language: form.Language,
|
||||
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: gtsmodel.ActivityStreamsNote,
|
||||
Sensitive: form.Sensitive,
|
||||
Language: form.Language,
|
||||
CreatedWithApplicationID: authed.Application.ID,
|
||||
Text: form.Status,
|
||||
}
|
||||
|
||||
// check if replyToID is ok
|
||||
|
|
@ -181,80 +183,11 @@ func (m *statusModule) statusCreatePOSTHandler(c *gin.Context) {
|
|||
/*
|
||||
FROM THIS POINT ONWARDS WE ARE JUST CREATING THE FRONTEND REPRESENTATION OF THE STATUS TO RETURN TO THE SUBMITTER
|
||||
*/
|
||||
mastoVis := util.ParseMastoVisFromGTSVis(newStatus.Visibility)
|
||||
|
||||
mastoAccount, err := m.mastoConverter.AccountToMastoPublic(authed.Account)
|
||||
mastoStatus, err := m.mastoConverter.StatusToMasto(newStatus, authed.Account, authed.Account, nil, newStatus.GTSReplyToAccount, newStatus.GTSReplyToStatus)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
mastoAttachments := []mastotypes.Attachment{}
|
||||
for _, a := range newStatus.GTSMediaAttachments {
|
||||
ma, err := m.mastoConverter.AttachmentToMasto(a)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
mastoAttachments = append(mastoAttachments, ma)
|
||||
}
|
||||
|
||||
mastoMentions := []mastotypes.Mention{}
|
||||
for _, gtsm := range newStatus.GTSMentions {
|
||||
mm, err := m.mastoConverter.MentionToMasto(gtsm)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
mastoMentions = append(mastoMentions, mm)
|
||||
}
|
||||
|
||||
mastoApplication, err := m.mastoConverter.AppToMastoPublic(authed.Application)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
mastoTags := []mastotypes.Tag{}
|
||||
for _, gtst := range newStatus.GTSTags {
|
||||
mt, err := m.mastoConverter.TagToMasto(gtst)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
mastoTags = append(mastoTags, mt)
|
||||
}
|
||||
|
||||
mastoEmojis := []mastotypes.Emoji{}
|
||||
for _, gtse := range newStatus.GTSEmojis {
|
||||
me, err := m.mastoConverter.EmojiToMasto(gtse)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
mastoEmojis = append(mastoEmojis, me)
|
||||
}
|
||||
|
||||
mastoStatus := &mastotypes.Status{
|
||||
ID: newStatus.ID,
|
||||
CreatedAt: newStatus.CreatedAt.Format(time.RFC3339),
|
||||
InReplyToID: newStatus.InReplyToID,
|
||||
InReplyToAccountID: newStatus.InReplyToAccountID,
|
||||
Sensitive: newStatus.Sensitive,
|
||||
SpoilerText: newStatus.ContentWarning,
|
||||
Visibility: mastoVis,
|
||||
Language: newStatus.Language,
|
||||
URI: newStatus.URI,
|
||||
URL: newStatus.URL,
|
||||
Content: newStatus.Content,
|
||||
Application: mastoApplication,
|
||||
Account: mastoAccount,
|
||||
MediaAttachments: mastoAttachments,
|
||||
Mentions: mastoMentions,
|
||||
Tags: mastoTags,
|
||||
Emojis: mastoEmojis,
|
||||
Text: form.Status,
|
||||
}
|
||||
c.JSON(http.StatusOK, mastoStatus)
|
||||
}
|
||||
|
||||
|
|
@ -487,7 +420,7 @@ func (m *statusModule) parseMentions(form *advancedStatusCreateForm, accountID s
|
|||
if err := m.db.Put(menchie); err != nil {
|
||||
return fmt.Errorf("error putting mentions in db: %s", err)
|
||||
}
|
||||
menchies = append(menchies, menchie.ID)
|
||||
menchies = append(menchies, menchie.TargetAccountID)
|
||||
}
|
||||
// add full populated gts menchies to the status for passing them around conveniently
|
||||
status.GTSMentions = gtsMenchies
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ func (suite *StatusCreateTestSuite) TestPostNewStatus() {
|
|||
assert.Len(suite.T(), statusReply.Tags, 1)
|
||||
assert.Equal(suite.T(), mastomodel.Tag{
|
||||
Name: "helloworld",
|
||||
URL: "http://localhost:8080/tags/helloworld",
|
||||
URL: "http://localhost:8080/tags/helloworld",
|
||||
}, statusReply.Tags[0])
|
||||
|
||||
gtsTag := >smodel.Tag{}
|
||||
|
|
@ -185,7 +185,7 @@ func (suite *StatusCreateTestSuite) TestPostNewStatusWithEmoji() {
|
|||
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": {"here is a rainbow emoji a few times! :rainbow: :rainbow: :rainbow: \n here's an emoji that isn't in the db: :test_emoji: "},
|
||||
"status": {"here is a rainbow emoji a few times! :rainbow: :rainbow: :rainbow: \n here's an emoji that isn't in the db: :test_emoji: "},
|
||||
}
|
||||
suite.statusModule.statusCreatePOSTHandler(ctx)
|
||||
|
||||
|
|
|
|||
111
internal/apimodule/status/statusget.go
Normal file
111
internal/apimodule/status/statusget.go
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package status
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||
)
|
||||
|
||||
func (m *statusModule) statusGETHandler(c *gin.Context) {
|
||||
l := m.log.WithFields(logrus.Fields{
|
||||
"func": "statusGETHandler",
|
||||
"request_uri": c.Request.RequestURI,
|
||||
"user_agent": c.Request.UserAgent(),
|
||||
"origin_ip": c.ClientIP(),
|
||||
})
|
||||
l.Debugf("entering function")
|
||||
|
||||
var requestingAccount *gtsmodel.Account
|
||||
authed, err := oauth.MustAuth(c, true, false, true, true) // we don't really need an app here but we want everything else
|
||||
if err != nil {
|
||||
l.Debug("not authed but will continue to serve anyway if public status")
|
||||
requestingAccount = nil
|
||||
} else {
|
||||
requestingAccount = authed.Account
|
||||
}
|
||||
|
||||
targetStatusID := c.Param(idKey)
|
||||
if targetStatusID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "no status id provided"})
|
||||
return
|
||||
}
|
||||
|
||||
l.Tracef("going to search for target status %s", targetStatusID)
|
||||
targetStatus := >smodel.Status{}
|
||||
if err := m.db.GetByID(targetStatusID, targetStatus); err != nil {
|
||||
l.Errorf("error fetching status %s: %s", targetStatusID, err)
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("status %s not found", targetStatusID)})
|
||||
return
|
||||
}
|
||||
|
||||
l.Tracef("going to search for target account %s", targetStatus.AccountID)
|
||||
targetAccount := >smodel.Account{}
|
||||
if err := m.db.GetByID(targetStatus.AccountID, targetAccount); err != nil {
|
||||
l.Errorf("error fetching target account %s: %s", targetStatus.AccountID, err)
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("status %s not found", targetStatusID)})
|
||||
return
|
||||
}
|
||||
|
||||
l.Trace("going to get relevant accounts")
|
||||
relevantAccounts, err := m.db.PullRelevantAccountsFromStatus(targetStatus)
|
||||
if err != nil {
|
||||
l.Errorf("error fetching related accounts for status %s: %s", targetStatusID, err)
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("status %s not found", targetStatusID)})
|
||||
return
|
||||
}
|
||||
|
||||
l.Trace("going to see if status is visible")
|
||||
visible, err := m.db.StatusVisible(targetStatus, targetAccount, requestingAccount, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
|
||||
if err != nil {
|
||||
l.Errorf("error seeing if status %s is visible: %s", targetStatus.ID, err)
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("status %s not found", targetStatusID)})
|
||||
return
|
||||
}
|
||||
|
||||
if !visible {
|
||||
l.Trace("status is not visible")
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("status %s not found", targetStatusID)})
|
||||
return
|
||||
}
|
||||
|
||||
var boostOfStatus *gtsmodel.Status
|
||||
if targetStatus.BoostOfID != "" {
|
||||
boostOfStatus = >smodel.Status{}
|
||||
if err := m.db.GetByID(targetStatus.BoostOfID, boostOfStatus); err != nil {
|
||||
l.Errorf("error fetching boosted status %s: %s", targetStatus.BoostOfID, err)
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("status %s not found", targetStatusID)})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
mastoStatus, err := m.mastoConverter.StatusToMasto(targetStatus, targetAccount, requestingAccount, relevantAccounts.BoostedAccount, relevantAccounts.ReplyToAccount, boostOfStatus)
|
||||
if err != nil {
|
||||
l.Errorf("error converting status %s to frontend representation: %s", targetStatus.ID, err)
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("status %s not found", targetStatusID)})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, mastoStatus)
|
||||
}
|
||||
167
internal/apimodule/status/statusget_test.go
Normal file
167
internal/apimodule/status/statusget_test.go
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package status
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/distributor"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/mastotypes"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/storage"
|
||||
"github.com/superseriousbusiness/gotosocial/testrig"
|
||||
)
|
||||
|
||||
type StatusGetTestSuite struct {
|
||||
// standard suite interfaces
|
||||
suite.Suite
|
||||
config *config.Config
|
||||
db db.DB
|
||||
log *logrus.Logger
|
||||
storage storage.Storage
|
||||
mastoConverter mastotypes.Converter
|
||||
mediaHandler media.MediaHandler
|
||||
oauthServer oauth.Server
|
||||
distributor distributor.Distributor
|
||||
|
||||
// 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
|
||||
testAttachments map[string]*gtsmodel.MediaAttachment
|
||||
|
||||
// module being tested
|
||||
statusModule *statusModule
|
||||
}
|
||||
|
||||
/*
|
||||
TEST INFRASTRUCTURE
|
||||
*/
|
||||
|
||||
// SetupSuite sets some variables on the suite that we can use as consts (more or less) throughout
|
||||
func (suite *StatusGetTestSuite) SetupSuite() {
|
||||
// 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)
|
||||
suite.distributor = testrig.NewTestDistributor()
|
||||
|
||||
// setup module being tested
|
||||
suite.statusModule = New(suite.config, suite.db, suite.oauthServer, suite.mediaHandler, suite.mastoConverter, suite.distributor, suite.log).(*statusModule)
|
||||
}
|
||||
|
||||
func (suite *StatusGetTestSuite) TearDownSuite() {
|
||||
testrig.StandardDBTeardown(suite.db)
|
||||
testrig.StandardStorageTeardown(suite.storage)
|
||||
}
|
||||
|
||||
func (suite *StatusGetTestSuite) 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 *StatusGetTestSuite) TearDownTest() {
|
||||
testrig.StandardDBTeardown(suite.db)
|
||||
}
|
||||
|
||||
/*
|
||||
ACTUAL TESTS
|
||||
*/
|
||||
|
||||
/*
|
||||
TESTING: StatusGetPOSTHandler
|
||||
*/
|
||||
|
||||
// Post a new status with some custom visibility settings
|
||||
func (suite *StatusGetTestSuite) TestPostNewStatus() {
|
||||
|
||||
// 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! #helloworld"},
|
||||
// "spoiler_text": {"hello hello"},
|
||||
// "sensitive": {"true"},
|
||||
// "visibility_advanced": {"mutuals_only"},
|
||||
// "likeable": {"false"},
|
||||
// "replyable": {"false"},
|
||||
// "federated": {"false"},
|
||||
// }
|
||||
// suite.statusModule.statusGETHandler(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 := &mastomodel.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! #helloworld", statusReply.Content)
|
||||
// assert.True(suite.T(), statusReply.Sensitive)
|
||||
// assert.Equal(suite.T(), mastomodel.VisibilityPrivate, statusReply.Visibility)
|
||||
// assert.Len(suite.T(), statusReply.Tags, 1)
|
||||
// assert.Equal(suite.T(), mastomodel.Tag{
|
||||
// Name: "helloworld",
|
||||
// URL: "http://localhost:8080/tags/helloworld",
|
||||
// }, statusReply.Tags[0])
|
||||
|
||||
// gtsTag := >smodel.Tag{}
|
||||
// err = suite.db.GetWhere("name", "helloworld", gtsTag)
|
||||
// assert.NoError(suite.T(), err)
|
||||
// assert.Equal(suite.T(), statusReply.Account.ID, gtsTag.FirstSeenFromAccountID)
|
||||
}
|
||||
|
||||
func TestStatusGetTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(StatusGetTestSuite))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue