Fix mentioned accounts visibility bug (#323)

* update other tests

* set test status to followers_only

* add test dm

* fix mentioned accounts not being added to relevantAccounts

* add some visibility tests for statuses
This commit is contained in:
tobi 2021-11-22 14:40:23 +01:00 committed by GitHub
parent b46e5fb65d
commit 79ccd8fd8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 245 additions and 17 deletions

View file

@ -43,7 +43,7 @@ func (suite *BasicTestSuite) TestGetAllStatuses() {
s := []*gtsmodel.Status{} s := []*gtsmodel.Status{}
err := suite.db.GetAll(context.Background(), &s) err := suite.db.GetAll(context.Background(), &s)
suite.NoError(err) suite.NoError(err)
suite.Len(s, 13) suite.Len(s, 14)
} }
func (suite *BasicTestSuite) TestGetAllNotNull() { func (suite *BasicTestSuite) TestGetAllNotNull() {

View file

@ -73,8 +73,8 @@ func (suite *GetTestSuite) TestGetDefault() {
suite.FailNow(err.Error()) suite.FailNow(err.Error())
} }
// we only have 13 statuses in the test suite // we only have 14 statuses in the test suite
suite.Len(statuses, 13) suite.Len(statuses, 14)
// statuses should be sorted highest to lowest ID // statuses should be sorted highest to lowest ID
var highest string var highest string
@ -166,8 +166,8 @@ func (suite *GetTestSuite) TestGetMinID() {
suite.FailNow(err.Error()) suite.FailNow(err.Error())
} }
// we should only get 6 statuses back, since we asked for a min ID that excludes some of our entries // we should only get 7 statuses back, since we asked for a min ID that excludes some of our entries
suite.Len(statuses, 6) suite.Len(statuses, 7)
// statuses should be sorted highest to lowest ID // statuses should be sorted highest to lowest ID
var highest string var highest string
@ -188,8 +188,8 @@ func (suite *GetTestSuite) TestGetSinceID() {
suite.FailNow(err.Error()) suite.FailNow(err.Error())
} }
// we should only get 6 statuses back, since we asked for a since ID that excludes some of our entries // we should only get 7 statuses back, since we asked for a since ID that excludes some of our entries
suite.Len(statuses, 6) suite.Len(statuses, 7)
// statuses should be sorted highest to lowest ID // statuses should be sorted highest to lowest ID
var highest string var highest string
@ -210,8 +210,8 @@ func (suite *GetTestSuite) TestGetSinceIDPrepareNext() {
suite.FailNow(err.Error()) suite.FailNow(err.Error())
} }
// we should only get 6 statuses back, since we asked for a since ID that excludes some of our entries // we should only get 7 statuses back, since we asked for a since ID that excludes some of our entries
suite.Len(statuses, 6) suite.Len(statuses, 7)
// statuses should be sorted highest to lowest ID // statuses should be sorted highest to lowest ID
var highest string var highest string

View file

@ -66,7 +66,7 @@ func (suite *IndexTestSuite) TestIndexBeforeLowID() {
// the oldest indexed post should be the lowest one we have in our testrig // the oldest indexed post should be the lowest one we have in our testrig
postID, err := suite.timeline.OldestIndexedPostID(context.Background()) postID, err := suite.timeline.OldestIndexedPostID(context.Background())
suite.NoError(err) suite.NoError(err)
suite.Equal("01F8MHAMCHF6Y650WCRSCP4WMY", postID) suite.Equal("01F8MHAYFKS4KMXF8K5Y1C0KRN", postID)
indexLength := suite.timeline.PostIndexLength(context.Background()) indexLength := suite.timeline.PostIndexLength(context.Background())
suite.Equal(10, indexLength) suite.Equal(10, indexLength)
@ -95,7 +95,7 @@ func (suite *IndexTestSuite) TestIndexBehindHighID() {
// the newest indexed post should be the highest one we have in our testrig // the newest indexed post should be the highest one we have in our testrig
postID, err := suite.timeline.NewestIndexedPostID(context.Background()) postID, err := suite.timeline.NewestIndexedPostID(context.Background())
suite.NoError(err) suite.NoError(err)
suite.Equal("01FF25D5Q0DH7CHD57CTRS6WK0", postID) suite.Equal("01FN3VJGFH10KR7S2PB0GFJZYG", postID)
// indexLength should be 10 because that's all this user has hometimelineable // indexLength should be 10 because that's all this user has hometimelineable
indexLength := suite.timeline.PostIndexLength(context.Background()) indexLength := suite.timeline.PostIndexLength(context.Background())

View file

@ -67,9 +67,9 @@ func (suite *ManagerTestSuite) TestManagerIntegration() {
err = suite.manager.PrepareXFromTop(context.Background(), testAccount.ID, 20) err = suite.manager.PrepareXFromTop(context.Background(), testAccount.ID, 20)
suite.NoError(err) suite.NoError(err)
// local_account_1 can see 13 statuses out of the testrig statuses in its home timeline // local_account_1 can see 14 statuses out of the testrig statuses in its home timeline
indexedLen = suite.manager.GetIndexedLength(context.Background(), testAccount.ID) indexedLen = suite.manager.GetIndexedLength(context.Background(), testAccount.ID)
suite.Equal(13, indexedLen) suite.Equal(14, indexedLen)
// oldest should now be set // oldest should now be set
oldestIndexed, err = suite.manager.GetOldestIndexedID(context.Background(), testAccount.ID) oldestIndexed, err = suite.manager.GetOldestIndexedID(context.Background(), testAccount.ID)
@ -79,7 +79,7 @@ func (suite *ManagerTestSuite) TestManagerIntegration() {
// get hometimeline // get hometimeline
statuses, err := suite.manager.HomeTimeline(context.Background(), testAccount.ID, "", "", "", 20, false) statuses, err := suite.manager.HomeTimeline(context.Background(), testAccount.ID, "", "", "", 20, false)
suite.NoError(err) suite.NoError(err)
suite.Len(statuses, 13) suite.Len(statuses, 14)
// now wipe the last status from all timelines, as though it had been deleted by the owner // now wipe the last status from all timelines, as though it had been deleted by the owner
err = suite.manager.WipeStatusFromAllTimelines(context.Background(), "01F8MH75CBF9JFX4ZAD54N0W0R") err = suite.manager.WipeStatusFromAllTimelines(context.Background(), "01F8MH75CBF9JFX4ZAD54N0W0R")
@ -87,7 +87,7 @@ func (suite *ManagerTestSuite) TestManagerIntegration() {
// timeline should be shorter // timeline should be shorter
indexedLen = suite.manager.GetIndexedLength(context.Background(), testAccount.ID) indexedLen = suite.manager.GetIndexedLength(context.Background(), testAccount.ID)
suite.Equal(12, indexedLen) suite.Equal(13, indexedLen)
// oldest should now be different // oldest should now be different
oldestIndexed, err = suite.manager.GetOldestIndexedID(context.Background(), testAccount.ID) oldestIndexed, err = suite.manager.GetOldestIndexedID(context.Background(), testAccount.ID)
@ -101,7 +101,7 @@ func (suite *ManagerTestSuite) TestManagerIntegration() {
// timeline should be shorter // timeline should be shorter
indexedLen = suite.manager.GetIndexedLength(context.Background(), testAccount.ID) indexedLen = suite.manager.GetIndexedLength(context.Background(), testAccount.ID)
suite.Equal(11, indexedLen) suite.Equal(12, indexedLen)
// oldest should now be different // oldest should now be different
oldestIndexed, err = suite.manager.GetOldestIndexedID(context.Background(), testAccount.ID) oldestIndexed, err = suite.manager.GetOldestIndexedID(context.Background(), testAccount.ID)

View file

@ -0,0 +1,74 @@
/*
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 visibility_test
import (
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/visibility"
"github.com/superseriousbusiness/gotosocial/testrig"
)
type FilterStandardTestSuite struct {
// standard suite interfaces
suite.Suite
config *config.Config
db db.DB
// standard suite models
testTokens map[string]*gtsmodel.Token
testClients map[string]*gtsmodel.Client
testApplications map[string]*gtsmodel.Application
testUsers map[string]*gtsmodel.User
testAccounts map[string]*gtsmodel.Account
testAttachments map[string]*gtsmodel.MediaAttachment
testStatuses map[string]*gtsmodel.Status
testTags map[string]*gtsmodel.Tag
testMentions map[string]*gtsmodel.Mention
filter visibility.Filter
}
func (suite *FilterStandardTestSuite) SetupSuite() {
suite.testTokens = testrig.NewTestTokens()
suite.testClients = testrig.NewTestClients()
suite.testApplications = testrig.NewTestApplications()
suite.testUsers = testrig.NewTestUsers()
suite.testAccounts = testrig.NewTestAccounts()
suite.testAttachments = testrig.NewTestAttachments()
suite.testStatuses = testrig.NewTestStatuses()
suite.testTags = testrig.NewTestTags()
suite.testMentions = testrig.NewTestMentions()
}
func (suite *FilterStandardTestSuite) SetupTest() {
testrig.InitTestLog()
suite.config = testrig.NewTestConfig()
suite.db = testrig.NewTestDB()
suite.filter = visibility.NewFilter(suite.db)
testrig.StandardDBSetup(suite.db, nil)
}
func (suite *FilterStandardTestSuite) TearDownTest() {
testrig.StandardDBTeardown(suite.db)
}

View file

@ -134,6 +134,7 @@ func (f *filter) relevantAccounts(ctx context.Context, status *gtsmodel.Status,
} }
if mentionIn(m, status.MentionIDs) { if mentionIn(m, status.MentionIDs) {
nm = append(nm, m) nm = append(nm, m)
relAccts.MentionedAccounts = append(relAccts.MentionedAccounts, m.TargetAccount)
} }
} }
status.Mentions = nm status.Mentions = nm

View file

@ -0,0 +1,115 @@
/*
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 visibility_test
import (
"context"
"testing"
"github.com/stretchr/testify/suite"
)
type StatusVisibleTestSuite struct {
FilterStandardTestSuite
}
func (suite *StatusVisibleTestSuite) TestOwnStatusVisible() {
testStatus := suite.testStatuses["local_account_1_status_1"]
testAccount := suite.testAccounts["local_account_1"]
ctx := context.Background()
visible, err := suite.filter.StatusVisible(ctx, testStatus, testAccount)
suite.NoError(err)
suite.True(visible)
}
func (suite *StatusVisibleTestSuite) TestOwnDMVisible() {
ctx := context.Background()
testStatusID := suite.testStatuses["local_account_2_status_6"].ID
testStatus, err := suite.db.GetStatusByID(ctx, testStatusID)
suite.NoError(err)
testAccount := suite.testAccounts["local_account_2"]
visible, err := suite.filter.StatusVisible(ctx, testStatus, testAccount)
suite.NoError(err)
suite.True(visible)
}
func (suite *StatusVisibleTestSuite) TestDMVisibleToTarget() {
ctx := context.Background()
testStatusID := suite.testStatuses["local_account_2_status_6"].ID
testStatus, err := suite.db.GetStatusByID(ctx, testStatusID)
suite.NoError(err)
testAccount := suite.testAccounts["local_account_1"]
visible, err := suite.filter.StatusVisible(ctx, testStatus, testAccount)
suite.NoError(err)
suite.True(visible)
}
func (suite *StatusVisibleTestSuite) TestDMNotVisibleIfNotMentioned() {
ctx := context.Background()
testStatusID := suite.testStatuses["local_account_2_status_6"].ID
testStatus, err := suite.db.GetStatusByID(ctx, testStatusID)
suite.NoError(err)
testAccount := suite.testAccounts["admin_account"]
visible, err := suite.filter.StatusVisible(ctx, testStatus, testAccount)
suite.NoError(err)
suite.False(visible)
}
func (suite *StatusVisibleTestSuite) TestStatusNotVisibleIfNotMutuals() {
ctx := context.Background()
testStatusID := suite.testStatuses["local_account_1_status_4"].ID
testStatus, err := suite.db.GetStatusByID(ctx, testStatusID)
suite.NoError(err)
testAccount := suite.testAccounts["local_account_2"]
visible, err := suite.filter.StatusVisible(ctx, testStatus, testAccount)
suite.NoError(err)
suite.False(visible)
}
func (suite *StatusVisibleTestSuite) TestStatusNotVisibleIfNotFollowing() {
ctx := context.Background()
testStatusID := suite.testStatuses["local_account_1_status_5"].ID
testStatus, err := suite.db.GetStatusByID(ctx, testStatusID)
suite.NoError(err)
testAccount := suite.testAccounts["admin_account"]
visible, err := suite.filter.StatusVisible(ctx, testStatus, testAccount)
suite.NoError(err)
suite.False(visible)
}
func TestStatusVisibleTestSuite(t *testing.T) {
suite.Run(t, new(StatusVisibleTestSuite))
}

View file

@ -1037,7 +1037,7 @@ func NewTestStatuses() map[string]*gtsmodel.Status {
InReplyToID: "", InReplyToID: "",
BoostOfID: "", BoostOfID: "",
ContentWarning: "", ContentWarning: "",
Visibility: gtsmodel.VisibilityMutualsOnly, Visibility: gtsmodel.VisibilityFollowersOnly,
Sensitive: false, Sensitive: false,
Language: "en", Language: "en",
CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG", CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG",
@ -1166,6 +1166,32 @@ func NewTestStatuses() map[string]*gtsmodel.Status {
Likeable: true, Likeable: true,
ActivityStreamsType: ap.ObjectNote, ActivityStreamsType: ap.ObjectNote,
}, },
"local_account_2_status_6": {
ID: "01FN3VJGFH10KR7S2PB0GFJZYG",
URI: "http://localhost:8080/users/1happyturtle/statuses/01FN3VJGFH10KR7S2PB0GFJZYG",
URL: "http://localhost:8080/@1happyturtle/statuses/01FN3VJGFH10KR7S2PB0GFJZYG",
Content: "🐢 @the_mighty_zork hi zork, this is a direct message, shhhhhh! 🐢",
CreatedAt: time.Now().Add(-1 * time.Minute),
UpdatedAt: time.Now().Add(-1 * time.Minute),
Local: true,
AccountURI: "http://localhost:8080/users/1happyturtle",
MentionIDs: []string{"01FDF2HM2NF6FSRZCDEDV451CN"},
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
InReplyToID: "",
InReplyToAccountID: "",
InReplyToURI: "",
BoostOfID: "",
ContentWarning: "",
Visibility: gtsmodel.VisibilityDirect,
Sensitive: false,
Language: "en",
CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ",
Federated: true,
Boostable: true,
Replyable: true,
Likeable: true,
ActivityStreamsType: ap.ObjectNote,
},
} }
} }
@ -1224,6 +1250,18 @@ func NewTestMentions() map[string]*gtsmodel.Mention {
TargetAccountURI: "http://localhost:8080/users/the_mighty_zork", TargetAccountURI: "http://localhost:8080/users/the_mighty_zork",
TargetAccountURL: "http://localhost:8080/@the_mighty_zork", TargetAccountURL: "http://localhost:8080/@the_mighty_zork",
}, },
"local_user_2_mention_zork_direct_message": {
ID: "01FN3VKDEF4CN2W9TKX339BEHB",
StatusID: "01FN3VJGFH10KR7S2PB0GFJZYG",
CreatedAt: time.Now().Add(-1 * time.Minute),
UpdatedAt: time.Now().Add(-1 * time.Minute),
OriginAccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
OriginAccountURI: "http://localhost:8080/users/1happyturtle",
TargetAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
NameString: "@the_mighty_zork",
TargetAccountURI: "http://localhost:8080/users/the_mighty_zork",
TargetAccountURL: "http://localhost:8080/@the_mighty_zork",
},
"admin_account_mention_zork": { "admin_account_mention_zork": {
ID: "01FF26A6BGEKCZFWNEHXB2ZZ6M", ID: "01FF26A6BGEKCZFWNEHXB2ZZ6M",
StatusID: "01FF25D5Q0DH7CHD57CTRS6WK0", StatusID: "01FF25D5Q0DH7CHD57CTRS6WK0",