forked from mirrors/gotosocial
[feature] Implemented notification clear (#720)
* Implemented notification clear * Added the cache clear mechanism * added multi user check test
This commit is contained in:
parent
8fdc9ed552
commit
4fdbef04b4
7 changed files with 109 additions and 1 deletions
|
@ -34,6 +34,7 @@ const (
|
||||||
// BasePathWithID is just the base path with the ID key in it.
|
// BasePathWithID is just the base path with the ID key in it.
|
||||||
// Use this anywhere you need to know the ID of the notification being queried.
|
// Use this anywhere you need to know the ID of the notification being queried.
|
||||||
BasePathWithID = BasePath + "/:" + IDKey
|
BasePathWithID = BasePath + "/:" + IDKey
|
||||||
|
BasePathWithClear = BasePath + "/clear"
|
||||||
|
|
||||||
// MaxIDKey is the url query for setting a max notification ID to return
|
// MaxIDKey is the url query for setting a max notification ID to return
|
||||||
MaxIDKey = "max_id"
|
MaxIDKey = "max_id"
|
||||||
|
@ -58,5 +59,6 @@ func New(processor processing.Processor) api.ClientModule {
|
||||||
// Route attaches all routes from this module to the given router
|
// Route attaches all routes from this module to the given router
|
||||||
func (m *Module) Route(r router.Router) error {
|
func (m *Module) Route(r router.Router) error {
|
||||||
r.AttachHandler(http.MethodGet, BasePath, m.NotificationsGETHandler)
|
r.AttachHandler(http.MethodGet, BasePath, m.NotificationsGETHandler)
|
||||||
|
r.AttachHandler(http.MethodPost, BasePathWithClear, m.NotificationsClearPOSTHandler)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
50
internal/api/client/notification/notificationsclear.go
Normal file
50
internal/api/client/notification/notificationsclear.go
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
GoToSocial
|
||||||
|
Copyright (C) 2021-2022 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 notification
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NotificationsClearPOSTHandler clears all the notifications
|
||||||
|
func (m *Module) NotificationsClearPOSTHandler(c *gin.Context) {
|
||||||
|
authed, err := oauth.Authed(c, true, true, true, true)
|
||||||
|
if err != nil {
|
||||||
|
api.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGet)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := api.NegotiateAccept(c, api.JSONAcceptHeaders...); err != nil {
|
||||||
|
api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
errWithCode := m.processor.NotificationsClear(c.Request.Context(), authed)
|
||||||
|
if errWithCode != nil {
|
||||||
|
api.ErrorHandler(c, errWithCode, m.processor.InstanceGet)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, struct{}{})
|
||||||
|
}
|
|
@ -108,3 +108,17 @@ func (n *notificationDB) GetNotifications(ctx context.Context, accountID string,
|
||||||
|
|
||||||
return notifs, nil
|
return notifs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *notificationDB) ClearNotifications(ctx context.Context, accountID string) db.Error {
|
||||||
|
if _, err := n.conn.
|
||||||
|
NewDelete().
|
||||||
|
Table("notifications").
|
||||||
|
Where("target_account_id = ?", accountID).
|
||||||
|
Exec(ctx); err != nil {
|
||||||
|
return n.conn.ProcessError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
n.cache.Clear()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -118,6 +118,35 @@ func (suite *NotificationTestSuite) TestGetNotificationsWithoutSpam() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *NotificationTestSuite) TestClearNotificationsWithSpam() {
|
||||||
|
suite.spamNotifs()
|
||||||
|
testAccount := suite.testAccounts["local_account_1"]
|
||||||
|
err := suite.db.ClearNotifications(context.Background(), testAccount.ID)
|
||||||
|
suite.NoError(err)
|
||||||
|
|
||||||
|
notifications, err := suite.db.GetNotifications(context.Background(), testAccount.ID, 20, "ZZZZZZZZZZZZZZZZZZZZZZZZZZ", "00000000000000000000000000")
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.NotNil(notifications)
|
||||||
|
suite.Empty(notifications)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *NotificationTestSuite) TestClearNotificationsWithTwoAccounts() {
|
||||||
|
suite.spamNotifs()
|
||||||
|
testAccount := suite.testAccounts["local_account_1"]
|
||||||
|
err := suite.db.ClearNotifications(context.Background(), testAccount.ID)
|
||||||
|
suite.NoError(err)
|
||||||
|
|
||||||
|
notifications, err := suite.db.GetNotifications(context.Background(), testAccount.ID, 20, "ZZZZZZZZZZZZZZZZZZZZZZZZZZ", "00000000000000000000000000")
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.NotNil(notifications)
|
||||||
|
suite.Empty(notifications)
|
||||||
|
|
||||||
|
notif := []*gtsmodel.Notification{}
|
||||||
|
err = suite.db.GetAll(context.Background(), ¬if)
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.NotEmpty(notif)
|
||||||
|
}
|
||||||
|
|
||||||
func TestNotificationTestSuite(t *testing.T) {
|
func TestNotificationTestSuite(t *testing.T) {
|
||||||
suite.Run(t, new(NotificationTestSuite))
|
suite.Run(t, new(NotificationTestSuite))
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,4 +32,6 @@ type Notification interface {
|
||||||
GetNotifications(ctx context.Context, accountID string, limit int, maxID string, sinceID string) ([]*gtsmodel.Notification, Error)
|
GetNotifications(ctx context.Context, accountID string, limit int, maxID string, sinceID string) ([]*gtsmodel.Notification, Error)
|
||||||
// GetNotification returns one notification according to its id.
|
// GetNotification returns one notification according to its id.
|
||||||
GetNotification(ctx context.Context, id string) (*gtsmodel.Notification, Error)
|
GetNotification(ctx context.Context, id string) (*gtsmodel.Notification, Error)
|
||||||
|
// ClearNotifications deletes every notification that pertain to the given accountID.
|
||||||
|
ClearNotifications(ctx context.Context, accountID string) Error
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,3 +58,12 @@ func (p *processor) NotificationsGet(ctx context.Context, authed *oauth.Auth, li
|
||||||
Limit: limit,
|
Limit: limit,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *processor) NotificationsClear(ctx context.Context, authed *oauth.Auth) gtserror.WithCode {
|
||||||
|
err := p.db.ClearNotifications(ctx, authed.Account.ID)
|
||||||
|
if err != nil {
|
||||||
|
return gtserror.NewErrorInternalError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -155,6 +155,8 @@ type Processor interface {
|
||||||
|
|
||||||
// NotificationsGet
|
// NotificationsGet
|
||||||
NotificationsGet(ctx context.Context, authed *oauth.Auth, limit int, maxID string, sinceID string) (*apimodel.TimelineResponse, gtserror.WithCode)
|
NotificationsGet(ctx context.Context, authed *oauth.Auth, limit int, maxID string, sinceID string) (*apimodel.TimelineResponse, gtserror.WithCode)
|
||||||
|
// NotificationsClear
|
||||||
|
NotificationsClear(ctx context.Context, authed *oauth.Auth) gtserror.WithCode
|
||||||
|
|
||||||
OAuthHandleTokenRequest(r *http.Request) (map[string]interface{}, gtserror.WithCode)
|
OAuthHandleTokenRequest(r *http.Request) (map[string]interface{}, gtserror.WithCode)
|
||||||
OAuthHandleAuthorizeRequest(w http.ResponseWriter, r *http.Request) error
|
OAuthHandleAuthorizeRequest(w http.ResponseWriter, r *http.Request) error
|
||||||
|
|
Loading…
Reference in a new issue