Skip to content

Commit

Permalink
[feature] Implement filters_changed stream event (superseriousbusines…
Browse files Browse the repository at this point in the history
  • Loading branch information
VyrCossont authored and nyarla committed Jun 19, 2024
1 parent c1862fc commit cbdf873
Show file tree
Hide file tree
Showing 31 changed files with 303 additions and 12 deletions.
3 changes: 2 additions & 1 deletion docs/api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8651,7 +8651,7 @@ paths:
`update`: a new status has been received.
`notification`: a new notification has been received.
`delete`: a status has been deleted.
`filters_changed`: not implemented.
`filters_changed`: filters (including keywords and statuses) have changed.
enum:
- update
- notification
Expand All @@ -8668,6 +8668,7 @@ paths:
If `event` = `update`, then the payload will be a JSON string of a status.
If `event` = `notification`, then the payload will be a JSON string of a notification.
If `event` = `delete`, then the payload will be a status ID.
If `event` = `filters_changed`, then there is no payload.
example: '{"id":"01FC3TZ5CFG6H65GCKCJRKA669","created_at":"2021-08-02T16:25:52Z","sensitive":false,"spoiler_text":"","visibility":"public","language":"en","uri":"https://gts.superseriousbusiness.org/users/dumpsterqueer/statuses/01FC3TZ5CFG6H65GCKCJRKA669","url":"https://gts.superseriousbusiness.org/@dumpsterqueer/statuses/01FC3TZ5CFG6H65GCKCJRKA669","replies_count":0,"reblogs_count":0,"favourites_count":0,"favourited":false,"reblogged":false,"muted":false,"bookmarked":fals…//gts.superseriousbusiness.org/fileserver/01JNN207W98SGG3CBJ76R5MVDN/header/original/019036W043D8FXPJKSKCX7G965.png","header_static":"https://gts.superseriousbusiness.org/fileserver/01JNN207W98SGG3CBJ76R5MVDN/header/small/019036W043D8FXPJKSKCX7G965.png","followers_count":33,"following_count":28,"statuses_count":126,"last_status_at":"2021-08-02T16:25:52Z","emojis":[],"fields":[]},"media_attachments":[],"mentions":[],"tags":[],"emojis":[],"card":null,"poll":null,"text":"a"}'
type: string
stream:
Expand Down
44 changes: 43 additions & 1 deletion internal/api/client/filters/v1/filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
package v1_test

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/suite"
filtersV1 "github.com/superseriousbusiness/gotosocial/internal/api/client/filters/v1"
"github.com/superseriousbusiness/gotosocial/internal/config"
Expand All @@ -30,9 +34,9 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/processing"
"github.com/superseriousbusiness/gotosocial/internal/state"
"github.com/superseriousbusiness/gotosocial/internal/storage"
"github.com/superseriousbusiness/gotosocial/internal/stream"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
"github.com/superseriousbusiness/gotosocial/testrig"
"testing"
)

type FiltersTestSuite struct {
Expand Down Expand Up @@ -112,6 +116,44 @@ func (suite *FiltersTestSuite) TearDownTest() {
testrig.StopWorkers(&suite.state)
}

func (suite *FiltersTestSuite) openHomeStream(account *gtsmodel.Account) *stream.Stream {
stream, err := suite.processor.Stream().Open(context.Background(), account, stream.TimelineHome)
if err != nil {
suite.FailNow(err.Error())
}
return stream
}

func (suite *FiltersTestSuite) checkStreamed(
str *stream.Stream,
expectMessage bool,
expectPayload string,
expectEventType string,
) {
// Set a 5s timeout on context.
ctx := context.Background()
ctx, cncl := context.WithTimeout(ctx, time.Second*5)
defer cncl()

msg, ok := str.Recv(ctx)

if expectMessage && !ok {
suite.FailNow("expected a message but message was not received")
}

if !expectMessage && ok {
suite.FailNow("expected no message but message was received")
}

if expectPayload != "" && msg.Payload != expectPayload {
suite.FailNow("", "expected payload %s but payload was: %s", expectPayload, msg.Payload)
}

if expectEventType != "" && msg.Event != expectEventType {
suite.FailNow("", "expected event type %s but event type was: %s", expectEventType, msg.Event)
}
}

func TestFiltersTestSuite(t *testing.T) {
suite.Run(t, new(FiltersTestSuite))
}
5 changes: 5 additions & 0 deletions internal/api/client/filters/v1/filterdelete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/stream"
"github.com/superseriousbusiness/gotosocial/testrig"
)

Expand Down Expand Up @@ -88,12 +89,16 @@ func (suite *FiltersTestSuite) deleteFilter(
}

func (suite *FiltersTestSuite) TestDeleteFilter() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

id := suite.testFilterKeywords["local_account_1_filter_1_keyword_1"].ID

err := suite.deleteFilter(id, http.StatusOK, "")
if err != nil {
suite.FailNow(err.Error())
}

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestDeleteAnotherAccountsFilter() {
Expand Down
13 changes: 13 additions & 0 deletions internal/api/client/filters/v1/filterpost_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/stream"
"github.com/superseriousbusiness/gotosocial/testrig"
)

Expand Down Expand Up @@ -116,6 +117,8 @@ func (suite *FiltersTestSuite) postFilter(
}

func (suite *FiltersTestSuite) TestPostFilterFull() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

phrase := "GNU/Linux"
context := []string{"home", "public"}
irreversible := false
Expand All @@ -137,9 +140,13 @@ func (suite *FiltersTestSuite) TestPostFilterFull() {
if suite.NotNil(filter.ExpiresAt) {
suite.NotEmpty(*filter.ExpiresAt)
}

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestPostFilterFullJSON() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

// Use a numeric literal with a fractional part to test the JSON-specific handling for non-integer "expires_in".
requestJson := `{
"phrase":"GNU/Linux",
Expand All @@ -166,9 +173,13 @@ func (suite *FiltersTestSuite) TestPostFilterFullJSON() {
if suite.NotNil(filter.ExpiresAt) {
suite.NotEmpty(*filter.ExpiresAt)
}

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestPostFilterMinimal() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

phrase := "GNU/Linux"
context := []string{"home"}
filter, err := suite.postFilter(&phrase, &context, nil, nil, nil, nil, http.StatusOK, "")
Expand All @@ -185,6 +196,8 @@ func (suite *FiltersTestSuite) TestPostFilterMinimal() {
suite.False(filter.Irreversible)
suite.False(filter.WholeWord)
suite.Nil(filter.ExpiresAt)

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestPostFilterEmptyPhrase() {
Expand Down
13 changes: 13 additions & 0 deletions internal/api/client/filters/v1/filterput_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/stream"
"github.com/superseriousbusiness/gotosocial/testrig"
)

Expand Down Expand Up @@ -119,6 +120,8 @@ func (suite *FiltersTestSuite) putFilter(
}

func (suite *FiltersTestSuite) TestPutFilterFull() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

id := suite.testFilterKeywords["local_account_1_filter_1_keyword_1"].ID
phrase := "GNU/Linux"
context := []string{"home", "public"}
Expand All @@ -141,9 +144,13 @@ func (suite *FiltersTestSuite) TestPutFilterFull() {
if suite.NotNil(filter.ExpiresAt) {
suite.NotEmpty(*filter.ExpiresAt)
}

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestPutFilterFullJSON() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

id := suite.testFilterKeywords["local_account_1_filter_1_keyword_1"].ID
// Use a numeric literal with a fractional part to test the JSON-specific handling for non-integer "expires_in".
requestJson := `{
Expand Down Expand Up @@ -171,9 +178,13 @@ func (suite *FiltersTestSuite) TestPutFilterFullJSON() {
if suite.NotNil(filter.ExpiresAt) {
suite.NotEmpty(*filter.ExpiresAt)
}

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestPutFilterMinimal() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

id := suite.testFilterKeywords["local_account_1_filter_1_keyword_1"].ID
phrase := "GNU/Linux"
context := []string{"home"}
Expand All @@ -191,6 +202,8 @@ func (suite *FiltersTestSuite) TestPutFilterMinimal() {
suite.False(filter.Irreversible)
suite.False(filter.WholeWord)
suite.Nil(filter.ExpiresAt)

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestPutFilterEmptyPhrase() {
Expand Down
41 changes: 41 additions & 0 deletions internal/api/client/filters/v2/filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
package v2_test

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/suite"
filtersV2 "github.com/superseriousbusiness/gotosocial/internal/api/client/filters/v2"
Expand All @@ -32,6 +34,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/processing"
"github.com/superseriousbusiness/gotosocial/internal/state"
"github.com/superseriousbusiness/gotosocial/internal/storage"
"github.com/superseriousbusiness/gotosocial/internal/stream"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
"github.com/superseriousbusiness/gotosocial/testrig"
)
Expand Down Expand Up @@ -113,6 +116,44 @@ func (suite *FiltersTestSuite) TearDownTest() {
testrig.StopWorkers(&suite.state)
}

func (suite *FiltersTestSuite) openHomeStream(account *gtsmodel.Account) *stream.Stream {
stream, err := suite.processor.Stream().Open(context.Background(), account, stream.TimelineHome)
if err != nil {
suite.FailNow(err.Error())
}
return stream
}

func (suite *FiltersTestSuite) checkStreamed(
str *stream.Stream,
expectMessage bool,
expectPayload string,
expectEventType string,
) {
// Set a 5s timeout on context.
ctx := context.Background()
ctx, cncl := context.WithTimeout(ctx, time.Second*5)
defer cncl()

msg, ok := str.Recv(ctx)

if expectMessage && !ok {
suite.FailNow("expected a message but message was not received")
}

if !expectMessage && ok {
suite.FailNow("expected no message but message was received")
}

if expectPayload != "" && msg.Payload != expectPayload {
suite.FailNow("", "expected payload %s but payload was: %s", expectPayload, msg.Payload)
}

if expectEventType != "" && msg.Event != expectEventType {
suite.FailNow("", "expected event type %s but event type was: %s", expectEventType, msg.Event)
}
}

func TestFiltersTestSuite(t *testing.T) {
suite.Run(t, new(FiltersTestSuite))
}
5 changes: 5 additions & 0 deletions internal/api/client/filters/v2/filterdelete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/stream"
"github.com/superseriousbusiness/gotosocial/testrig"
)

Expand Down Expand Up @@ -88,12 +89,16 @@ func (suite *FiltersTestSuite) deleteFilter(
}

func (suite *FiltersTestSuite) TestDeleteFilter() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

id := suite.testFilters["local_account_1_filter_1"].ID

err := suite.deleteFilter(id, http.StatusOK, "")
if err != nil {
suite.FailNow(err.Error())
}

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestDeleteAnotherAccountsFilter() {
Expand Down
5 changes: 5 additions & 0 deletions internal/api/client/filters/v2/filterkeyworddelete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/stream"
"github.com/superseriousbusiness/gotosocial/testrig"
)

Expand Down Expand Up @@ -88,12 +89,16 @@ func (suite *FiltersTestSuite) deleteFilterKeyword(
}

func (suite *FiltersTestSuite) TestDeleteFilterKeyword() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

id := suite.testFilterKeywords["local_account_1_filter_1_keyword_1"].ID

err := suite.deleteFilterKeyword(id, http.StatusOK, "")
if err != nil {
suite.FailNow(err.Error())
}

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestDeleteAnotherAccountsFilterKeyword() {
Expand Down
13 changes: 13 additions & 0 deletions internal/api/client/filters/v2/filterkeywordpost_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/stream"
"github.com/superseriousbusiness/gotosocial/testrig"
)

Expand Down Expand Up @@ -107,6 +108,8 @@ func (suite *FiltersTestSuite) postFilterKeyword(
}

func (suite *FiltersTestSuite) TestPostFilterKeywordFull() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

filterID := suite.testFilters["local_account_1_filter_1"].ID
keyword := "fnords"
wholeWord := true
Expand All @@ -117,9 +120,13 @@ func (suite *FiltersTestSuite) TestPostFilterKeywordFull() {

suite.Equal(keyword, filterKeyword.Keyword)
suite.Equal(wholeWord, filterKeyword.WholeWord)

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestPostFilterKeywordFullJSON() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

filterID := suite.testFilters["local_account_1_filter_1"].ID
requestJson := `{
"keyword": "fnords",
Expand All @@ -132,9 +139,13 @@ func (suite *FiltersTestSuite) TestPostFilterKeywordFullJSON() {

suite.Equal("fnords", filterKeyword.Keyword)
suite.True(filterKeyword.WholeWord)

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestPostFilterKeywordMinimal() {
homeStream := suite.openHomeStream(suite.testAccounts["local_account_1"])

filterID := suite.testFilters["local_account_1_filter_1"].ID
keyword := "fnords"
filterKeyword, err := suite.postFilterKeyword(filterID, &keyword, nil, nil, http.StatusOK, "")
Expand All @@ -144,6 +155,8 @@ func (suite *FiltersTestSuite) TestPostFilterKeywordMinimal() {

suite.Equal(keyword, filterKeyword.Keyword)
suite.False(filterKeyword.WholeWord)

suite.checkStreamed(homeStream, true, "", stream.EventTypeFiltersChanged)
}

func (suite *FiltersTestSuite) TestPostFilterKeywordEmptyKeyword() {
Expand Down
Loading

0 comments on commit cbdf873

Please sign in to comment.