diff options
author | 2024-07-04 19:29:28 -0700 | |
---|---|---|
committer | 2024-07-04 19:29:28 -0700 | |
commit | be5e532cd21fdbdfd1589186ed66a495ed5b8b35 (patch) | |
tree | d70eb05166f08225c484474bbef4bbbdc04bdf2b /internal/processing/timeline/home_test.go | |
parent | [feature] Set some security related headers (#3065) (diff) | |
download | gotosocial-be5e532cd21fdbdfd1589186ed66a495ed5b8b35.tar.xz |
[bugfix] Handle ErrHideStatus when preparing timeline statuses (#3071)
Diffstat (limited to 'internal/processing/timeline/home_test.go')
-rw-r--r-- | internal/processing/timeline/home_test.go | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/internal/processing/timeline/home_test.go b/internal/processing/timeline/home_test.go new file mode 100644 index 000000000..c73c209a3 --- /dev/null +++ b/internal/processing/timeline/home_test.go @@ -0,0 +1,154 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package timeline_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/suite" + apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" + "github.com/superseriousbusiness/gotosocial/internal/filter/visibility" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/id" + "github.com/superseriousbusiness/gotosocial/internal/oauth" + tlprocessor "github.com/superseriousbusiness/gotosocial/internal/processing/timeline" + "github.com/superseriousbusiness/gotosocial/internal/timeline" + "github.com/superseriousbusiness/gotosocial/internal/typeutils" + "github.com/superseriousbusiness/gotosocial/internal/util" +) + +type HomeTestSuite struct { + TimelineStandardTestSuite +} + +func (suite *HomeTestSuite) SetupTest() { + suite.TimelineStandardTestSuite.SetupTest() + + suite.state.Timelines.Home = timeline.NewManager( + tlprocessor.HomeTimelineGrab(&suite.state), + tlprocessor.HomeTimelineFilter(&suite.state, visibility.NewFilter(&suite.state)), + tlprocessor.HomeTimelineStatusPrepare(&suite.state, typeutils.NewConverter(&suite.state)), + tlprocessor.SkipInsert(), + ) + if err := suite.state.Timelines.Home.Start(); err != nil { + suite.FailNow(err.Error()) + } +} + +func (suite *HomeTestSuite) TearDownTest() { + if err := suite.state.Timelines.Home.Stop(); err != nil { + suite.FailNow(err.Error()) + } + + suite.TimelineStandardTestSuite.TearDownTest() +} + +// A timeline containing a status hidden due to filtering should return other statuses with no error. +func (suite *HomeTestSuite) TestHomeTimelineGetHideFiltered() { + var ( + ctx = context.Background() + requester = suite.testAccounts["local_account_1"] + authed = &oauth.Auth{Account: requester} + maxID = "" + sinceID = "" + minID = "01F8MHAAY43M6RJ473VQFCVH36" // 1 before filteredStatus + limit = 40 + local = false + filteredStatus = suite.testStatuses["admin_account_status_2"] + filteredStatusFound = false + filterID = id.NewULID() + filter = >smodel.Filter{ + ID: filterID, + AccountID: requester.ID, + Title: "timeline filtering test", + Action: gtsmodel.FilterActionHide, + Statuses: []*gtsmodel.FilterStatus{ + { + ID: id.NewULID(), + AccountID: requester.ID, + FilterID: filterID, + StatusID: filteredStatus.ID, + }, + }, + ContextHome: util.Ptr(true), + ContextNotifications: util.Ptr(false), + ContextPublic: util.Ptr(false), + ContextThread: util.Ptr(false), + ContextAccount: util.Ptr(false), + } + ) + + // Fetch the timeline to make sure the status we're going to filter is in that section of it. + resp, errWithCode := suite.timeline.HomeTimelineGet( + ctx, + authed, + maxID, + sinceID, + minID, + limit, + local, + ) + suite.NoError(errWithCode) + for _, item := range resp.Items { + if item.(*apimodel.Status).ID == filteredStatus.ID { + filteredStatusFound = true + break + } + } + if !filteredStatusFound { + suite.FailNow("precondition failed: status we would filter isn't present in unfiltered timeline") + } + // Prune the timeline to drop cached prepared statuses, a side effect of this precondition check. + if _, err := suite.state.Timelines.Home.Prune(ctx, requester.ID, 0, 0); err != nil { + suite.FailNow(err.Error()) + } + + // Create a filter to hide one status on the timeline. + if err := suite.db.PutFilter(ctx, filter); err != nil { + suite.FailNow(err.Error()) + } + + // Fetch the timeline again with the filter in place. + resp, errWithCode = suite.timeline.HomeTimelineGet( + ctx, + authed, + maxID, + sinceID, + minID, + limit, + local, + ) + + // We should have some statuses even though one status was filtered out. + suite.NoError(errWithCode) + suite.NotEmpty(resp.Items) + // The filtered status should not be there. + filteredStatusFound = false + for _, item := range resp.Items { + if item.(*apimodel.Status).ID == filteredStatus.ID { + filteredStatusFound = true + break + } + } + suite.False(filteredStatusFound) +} + +func TestHomeTestSuite(t *testing.T) { + suite.Run(t, new(HomeTestSuite)) +} |