[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
|
@ -33,7 +33,8 @@ const (
|
|||
BasePath = "/api/v1/notifications"
|
||||
// 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.
|
||||
BasePathWithID = BasePath + "/:" + IDKey
|
||||
BasePathWithID = BasePath + "/:" + IDKey
|
||||
BasePathWithClear = BasePath + "/clear"
|
||||
|
||||
// MaxIDKey is the url query for setting a max notification ID to return
|
||||
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
|
||||
func (m *Module) Route(r router.Router) error {
|
||||
r.AttachHandler(http.MethodGet, BasePath, m.NotificationsGETHandler)
|
||||
r.AttachHandler(http.MethodPost, BasePathWithClear, m.NotificationsClearPOSTHandler)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
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) {
|
||||
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)
|
||||
// GetNotification returns one notification according to its id.
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
||||
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(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)
|
||||
OAuthHandleAuthorizeRequest(w http.ResponseWriter, r *http.Request) error
|
||||
|
|
Loading…
Reference in New Issue