mirror of
https://codeberg.org/superseriousbusiness/gotosocial.git
synced 2024-12-20 08:01:50 +03:00
[bugfix] Log + ignore unknown notification types (#3577)
* [bugfix] Log + ignore unknown notification types * pass context to ParseNotificationTypes
This commit is contained in:
parent
61f8f1e0e3
commit
65917f5bb9
4 changed files with 106 additions and 63 deletions
|
@ -18,11 +18,14 @@
|
||||||
package notifications
|
package notifications
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/log"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/paging"
|
"github.com/superseriousbusiness/gotosocial/internal/paging"
|
||||||
)
|
)
|
||||||
|
@ -151,18 +154,6 @@ func (m *Module) NotificationsGETHandler(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
types, errWithCode := apiutil.ParseNotificationTypes(c.QueryArray(TypesKey))
|
|
||||||
if errWithCode != nil {
|
|
||||||
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
exclTypes, errWithCode := apiutil.ParseNotificationTypes(c.QueryArray(ExcludeTypesKey))
|
|
||||||
if errWithCode != nil {
|
|
||||||
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
page, errWithCode := paging.ParseIDPage(c,
|
page, errWithCode := paging.ParseIDPage(c,
|
||||||
1, // min limit
|
1, // min limit
|
||||||
80, // max limit
|
80, // max limit
|
||||||
|
@ -173,12 +164,13 @@ func (m *Module) NotificationsGETHandler(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx := c.Request.Context()
|
||||||
resp, errWithCode := m.processor.Timeline().NotificationsGet(
|
resp, errWithCode := m.processor.Timeline().NotificationsGet(
|
||||||
c.Request.Context(),
|
ctx,
|
||||||
authed,
|
authed,
|
||||||
page,
|
page,
|
||||||
types,
|
ParseNotificationTypes(ctx, c.QueryArray(TypesKey)), // Include types.
|
||||||
exclTypes,
|
ParseNotificationTypes(ctx, c.QueryArray(ExcludeTypesKey)), // Exclude types.
|
||||||
)
|
)
|
||||||
if errWithCode != nil {
|
if errWithCode != nil {
|
||||||
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
|
@ -191,3 +183,28 @@ func (m *Module) NotificationsGETHandler(c *gin.Context) {
|
||||||
|
|
||||||
apiutil.JSON(c, http.StatusOK, resp.Items)
|
apiutil.JSON(c, http.StatusOK, resp.Items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseNotificationTypes converts the given slice of string values
|
||||||
|
// to gtsmodel notification types, logging + skipping unknown types.
|
||||||
|
func ParseNotificationTypes(
|
||||||
|
ctx context.Context,
|
||||||
|
values []string,
|
||||||
|
) []gtsmodel.NotificationType {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ntypes := make([]gtsmodel.NotificationType, 0, len(values))
|
||||||
|
for _, value := range values {
|
||||||
|
ntype := gtsmodel.NewNotificationType(value)
|
||||||
|
if ntype == gtsmodel.NotificationUnknown {
|
||||||
|
// Type we don't know about (yet), log and ignore it.
|
||||||
|
log.Debugf(ctx, "ignoring unknown type %s", value)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ntypes = append(ntypes, ntype)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ntypes
|
||||||
|
}
|
||||||
|
|
|
@ -248,6 +248,45 @@ func (suite *NotificationsTestSuite) TestGetNotificationsIncludeOneType() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test including an unknown notification type, it should be ignored.
|
||||||
|
func (suite *NotificationsTestSuite) TestGetNotificationsIncludeUnknownType() {
|
||||||
|
testAccount := suite.testAccounts["local_account_1"]
|
||||||
|
testToken := suite.testTokens["local_account_1"]
|
||||||
|
testUser := suite.testUsers["local_account_1"]
|
||||||
|
|
||||||
|
suite.addMoreNotifications(testAccount)
|
||||||
|
|
||||||
|
maxID := ""
|
||||||
|
minID := ""
|
||||||
|
limit := 10
|
||||||
|
types := []string{"favourite", "something.weird"}
|
||||||
|
excludeTypes := []string(nil)
|
||||||
|
expectedHTTPStatus := http.StatusOK
|
||||||
|
expectedBody := ""
|
||||||
|
|
||||||
|
notifications, _, err := suite.getNotifications(
|
||||||
|
testAccount,
|
||||||
|
testToken,
|
||||||
|
testUser,
|
||||||
|
maxID,
|
||||||
|
minID,
|
||||||
|
limit,
|
||||||
|
types,
|
||||||
|
excludeTypes,
|
||||||
|
expectedHTTPStatus,
|
||||||
|
expectedBody,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
suite.FailNow(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should only include the fav notification.
|
||||||
|
suite.Len(notifications, 1)
|
||||||
|
for _, notification := range notifications {
|
||||||
|
suite.Equal("favourite", notification.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBookmarkTestSuite(t *testing.T) {
|
func TestBookmarkTestSuite(t *testing.T) {
|
||||||
suite.Run(t, new(NotificationsTestSuite))
|
suite.Run(t, new(NotificationsTestSuite))
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,11 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -218,51 +216,6 @@ func ParseInteractionReblogs(value string, defaultValue bool) (bool, gtserror.Wi
|
||||||
return parseBool(value, defaultValue, InteractionReblogsKey)
|
return parseBool(value, defaultValue, InteractionReblogsKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseNotificationType(value string) (gtsmodel.NotificationType, gtserror.WithCode) {
|
|
||||||
switch strings.ToLower(value) {
|
|
||||||
case "follow":
|
|
||||||
return gtsmodel.NotificationFollow, nil
|
|
||||||
case "follow_request":
|
|
||||||
return gtsmodel.NotificationFollowRequest, nil
|
|
||||||
case "mention":
|
|
||||||
return gtsmodel.NotificationMention, nil
|
|
||||||
case "reblog":
|
|
||||||
return gtsmodel.NotificationReblog, nil
|
|
||||||
case "favourite":
|
|
||||||
return gtsmodel.NotificationFave, nil
|
|
||||||
case "poll":
|
|
||||||
return gtsmodel.NotificationPoll, nil
|
|
||||||
case "status":
|
|
||||||
return gtsmodel.NotificationStatus, nil
|
|
||||||
case "admin.sign_up":
|
|
||||||
return gtsmodel.NotificationSignup, nil
|
|
||||||
case "pending.favourite":
|
|
||||||
return gtsmodel.NotificationPendingFave, nil
|
|
||||||
case "pending.reply":
|
|
||||||
return gtsmodel.NotificationPendingReply, nil
|
|
||||||
case "pending.reblog":
|
|
||||||
return gtsmodel.NotificationPendingReblog, nil
|
|
||||||
default:
|
|
||||||
text := fmt.Sprintf("unrecognized notification type %s", value)
|
|
||||||
return 0, gtserror.NewErrorBadRequest(errors.New(text), text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseNotificationTypes(values []string) ([]gtsmodel.NotificationType, gtserror.WithCode) {
|
|
||||||
if len(values) == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
ntypes := make([]gtsmodel.NotificationType, len(values))
|
|
||||||
for i, value := range values {
|
|
||||||
ntype, errWithCode := ParseNotificationType(value)
|
|
||||||
if errWithCode != nil {
|
|
||||||
return nil, errWithCode
|
|
||||||
}
|
|
||||||
ntypes[i] = ntype
|
|
||||||
}
|
|
||||||
return ntypes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parse functions for *REQUIRED* parameters.
|
Parse functions for *REQUIRED* parameters.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -17,7 +17,10 @@
|
||||||
|
|
||||||
package gtsmodel
|
package gtsmodel
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// Notification models an alert/notification sent to an account about something like a reblog, like, new follow request, etc.
|
// Notification models an alert/notification sent to an account about something like a reblog, like, new follow request, etc.
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
|
@ -40,6 +43,7 @@ type Notification struct {
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Notification Types
|
// Notification Types
|
||||||
|
NotificationUnknown NotificationType = 0 // NotificationUnknown -- unknown notification type, error if this occurs
|
||||||
NotificationFollow NotificationType = 1 // NotificationFollow -- someone followed you
|
NotificationFollow NotificationType = 1 // NotificationFollow -- someone followed you
|
||||||
NotificationFollowRequest NotificationType = 2 // NotificationFollowRequest -- someone requested to follow you
|
NotificationFollowRequest NotificationType = 2 // NotificationFollowRequest -- someone requested to follow you
|
||||||
NotificationMention NotificationType = 3 // NotificationMention -- someone mentioned you in their status
|
NotificationMention NotificationType = 3 // NotificationMention -- someone mentioned you in their status
|
||||||
|
@ -82,3 +86,33 @@ func (t NotificationType) String() string {
|
||||||
panic("invalid notification type")
|
panic("invalid notification type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewNotificationType returns a notification type from the given value.
|
||||||
|
func NewNotificationType(in string) NotificationType {
|
||||||
|
switch strings.ToLower(in) {
|
||||||
|
case "follow":
|
||||||
|
return NotificationFollow
|
||||||
|
case "follow_request":
|
||||||
|
return NotificationFollowRequest
|
||||||
|
case "mention":
|
||||||
|
return NotificationMention
|
||||||
|
case "reblog":
|
||||||
|
return NotificationReblog
|
||||||
|
case "favourite":
|
||||||
|
return NotificationFave
|
||||||
|
case "poll":
|
||||||
|
return NotificationPoll
|
||||||
|
case "status":
|
||||||
|
return NotificationStatus
|
||||||
|
case "admin.sign_up":
|
||||||
|
return NotificationSignup
|
||||||
|
case "pending.favourite":
|
||||||
|
return NotificationPendingFave
|
||||||
|
case "pending.reply":
|
||||||
|
return NotificationPendingReply
|
||||||
|
case "pending.reblog":
|
||||||
|
return NotificationPendingReblog
|
||||||
|
default:
|
||||||
|
return NotificationUnknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue