diff options
Diffstat (limited to 'internal/processing/workers')
-rw-r--r-- | internal/processing/workers/fromclientapi.go | 5 | ||||
-rw-r--r-- | internal/processing/workers/fromclientapi_test.go | 109 | ||||
-rw-r--r-- | internal/processing/workers/fromfediapi.go | 5 | ||||
-rw-r--r-- | internal/processing/workers/surfacenotify.go | 74 | ||||
-rw-r--r-- | internal/processing/workers/surfacetimeline.go | 2 |
5 files changed, 190 insertions, 5 deletions
diff --git a/internal/processing/workers/fromclientapi.go b/internal/processing/workers/fromclientapi.go index ff316b1f4..789145226 100644 --- a/internal/processing/workers/fromclientapi.go +++ b/internal/processing/workers/fromclientapi.go @@ -260,6 +260,11 @@ func (p *clientAPI) CreateLike(ctx context.Context, cMsg messages.FromClientAPI) return gtserror.Newf("%T not parseable as *gtsmodel.StatusFave", cMsg.GTSModel) } + // Ensure fave populated. + if err := p.state.DB.PopulateStatusFave(ctx, fave); err != nil { + return gtserror.Newf("error populating status fave: %w", err) + } + if err := p.surface.notifyFave(ctx, fave); err != nil { return gtserror.Newf("error notifying fave: %w", err) } diff --git a/internal/processing/workers/fromclientapi_test.go b/internal/processing/workers/fromclientapi_test.go index e5a098c31..05526f437 100644 --- a/internal/processing/workers/fromclientapi_test.go +++ b/internal/processing/workers/fromclientapi_test.go @@ -75,6 +75,7 @@ func (suite *FromClientAPITestSuite) newStatus( newStatus.InReplyToAccountID = replyToStatus.AccountID newStatus.InReplyToID = replyToStatus.ID newStatus.InReplyToURI = replyToStatus.URI + newStatus.ThreadID = replyToStatus.ThreadID // Mention the replied-to account. mention := >smodel.Mention{ @@ -324,6 +325,114 @@ func (suite *FromClientAPITestSuite) TestProcessCreateStatusReply() { ) } +func (suite *FromClientAPITestSuite) TestProcessCreateStatusReplyMuted() { + var ( + ctx = context.Background() + postingAccount = suite.testAccounts["admin_account"] + receivingAccount = suite.testAccounts["local_account_1"] + + // Admin account posts a reply to zork. + // Normally zork would get a notification + // for this, but zork mutes this thread. + status = suite.newStatus( + ctx, + postingAccount, + gtsmodel.VisibilityPublic, + suite.testStatuses["local_account_1_status_1"], + nil, + ) + threadMute = >smodel.ThreadMute{ + ID: "01HD3KRMBB1M85QRWHD912QWRE", + ThreadID: suite.testStatuses["local_account_1_status_1"].ThreadID, + AccountID: receivingAccount.ID, + } + ) + + // Store the thread mute before processing new status. + if err := suite.db.PutThreadMute(ctx, threadMute); err != nil { + suite.FailNow(err.Error()) + } + + // Process the new status. + if err := suite.processor.Workers().ProcessFromClientAPI( + ctx, + messages.FromClientAPI{ + APObjectType: ap.ObjectNote, + APActivityType: ap.ActivityCreate, + GTSModel: status, + OriginAccount: postingAccount, + }, + ); err != nil { + suite.FailNow(err.Error()) + } + + // Ensure no notification received. + notif, err := suite.db.GetNotification( + ctx, + gtsmodel.NotificationMention, + receivingAccount.ID, + postingAccount.ID, + status.ID, + ) + + suite.ErrorIs(err, db.ErrNoEntries) + suite.Nil(notif) +} + +func (suite *FromClientAPITestSuite) TestProcessCreateStatusBoostMuted() { + var ( + ctx = context.Background() + postingAccount = suite.testAccounts["admin_account"] + receivingAccount = suite.testAccounts["local_account_1"] + + // Admin account boosts a status by zork. + // Normally zork would get a notification + // for this, but zork mutes this thread. + status = suite.newStatus( + ctx, + postingAccount, + gtsmodel.VisibilityPublic, + nil, + suite.testStatuses["local_account_1_status_1"], + ) + threadMute = >smodel.ThreadMute{ + ID: "01HD3KRMBB1M85QRWHD912QWRE", + ThreadID: suite.testStatuses["local_account_1_status_1"].ThreadID, + AccountID: receivingAccount.ID, + } + ) + + // Store the thread mute before processing new status. + if err := suite.db.PutThreadMute(ctx, threadMute); err != nil { + suite.FailNow(err.Error()) + } + + // Process the new status. + if err := suite.processor.Workers().ProcessFromClientAPI( + ctx, + messages.FromClientAPI{ + APObjectType: ap.ActivityAnnounce, + APActivityType: ap.ActivityCreate, + GTSModel: status, + OriginAccount: postingAccount, + }, + ); err != nil { + suite.FailNow(err.Error()) + } + + // Ensure no notification received. + notif, err := suite.db.GetNotification( + ctx, + gtsmodel.NotificationReblog, + receivingAccount.ID, + postingAccount.ID, + status.ID, + ) + + suite.ErrorIs(err, db.ErrNoEntries) + suite.Nil(notif) +} + func (suite *FromClientAPITestSuite) TestProcessCreateStatusListRepliesPolicyListOnlyOK() { // We're modifying the test list so take a copy. testList := new(gtsmodel.List) diff --git a/internal/processing/workers/fromfediapi.go b/internal/processing/workers/fromfediapi.go index 598480cfb..f57235bf1 100644 --- a/internal/processing/workers/fromfediapi.go +++ b/internal/processing/workers/fromfediapi.go @@ -315,6 +315,11 @@ func (p *fediAPI) CreateLike(ctx context.Context, fMsg messages.FromFediAPI) err return gtserror.Newf("%T not parseable as *gtsmodel.StatusFave", fMsg.GTSModel) } + // Ensure fave populated. + if err := p.state.DB.PopulateStatusFave(ctx, fave); err != nil { + return gtserror.Newf("error populating status fave: %w", err) + } + if err := p.surface.notifyFave(ctx, fave); err != nil { return gtserror.Newf("error notifying fave: %w", err) } diff --git a/internal/processing/workers/surfacenotify.go b/internal/processing/workers/surfacenotify.go index 5a4f77a64..b99fa3ad3 100644 --- a/internal/processing/workers/surfacenotify.go +++ b/internal/processing/workers/surfacenotify.go @@ -28,15 +28,39 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/id" ) -// notifyMentions notifies each targeted account in -// the given mentions that they have a new mention. +// notifyMentions iterates through mentions on the +// given status, and notifies each mentioned account +// that they have a new mention. func (s *surface) notifyMentions( ctx context.Context, - mentions []*gtsmodel.Mention, + status *gtsmodel.Status, ) error { - errs := gtserror.NewMultiError(len(mentions)) + var ( + mentions = status.Mentions + errs = gtserror.NewMultiError(len(mentions)) + ) for _, mention := range mentions { + // Ensure thread not muted + // by mentioned account. + muted, err := s.state.DB.IsThreadMutedByAccount( + ctx, + status.ThreadID, + mention.TargetAccountID, + ) + + if err != nil { + errs.Append(err) + continue + } + + if muted { + // This mentioned account + // has muted the thread. + // Don't pester them. + continue + } + if err := s.notify( ctx, gtsmodel.NotificationMention, @@ -114,6 +138,24 @@ func (s *surface) notifyFave( return nil } + // Ensure favee hasn't + // muted the thread. + muted, err := s.state.DB.IsThreadMutedByAccount( + ctx, + fave.Status.ThreadID, + fave.TargetAccountID, + ) + + if err != nil { + return err + } + + if muted { + // Boostee doesn't want + // notifs for this thread. + return nil + } + return s.notify( ctx, gtsmodel.NotificationFave, @@ -134,11 +176,35 @@ func (s *surface) notifyAnnounce( return nil } + if status.BoostOf == nil { + // No boosted status + // set, nothing to do. + return nil + } + if status.BoostOfAccountID == status.AccountID { // Self-boost, nothing to do. return nil } + // Ensure boostee hasn't + // muted the thread. + muted, err := s.state.DB.IsThreadMutedByAccount( + ctx, + status.BoostOf.ThreadID, + status.BoostOfAccountID, + ) + + if err != nil { + return err + } + + if muted { + // Boostee doesn't want + // notifs for this thread. + return nil + } + return s.notify( ctx, gtsmodel.NotificationReblog, diff --git a/internal/processing/workers/surfacetimeline.go b/internal/processing/workers/surfacetimeline.go index a45c83188..15263cf78 100644 --- a/internal/processing/workers/surfacetimeline.go +++ b/internal/processing/workers/surfacetimeline.go @@ -67,7 +67,7 @@ func (s *surface) timelineAndNotifyStatus(ctx context.Context, status *gtsmodel. } // Notify each local account that's mentioned by this status. - if err := s.notifyMentions(ctx, status.Mentions); err != nil { + if err := s.notifyMentions(ctx, status); err != nil { return gtserror.Newf("error notifying status mentions for status %s: %w", status.ID, err) } |