diff options
| author | 2025-01-24 16:36:34 +0000 | |
|---|---|---|
| committer | 2025-01-24 17:36:34 +0100 | |
| commit | 71b50353ebb9dd844dc6a04590d191123a332a58 (patch) | |
| tree | 11c848a4bd23f39981f01d3927064194b0590578 /internal/processing/workers | |
| parent | [feature] show status edits on frontend (#3678) (diff) | |
| download | gotosocial-71b50353ebb9dd844dc6a04590d191123a332a58.tar.xz | |
[feature] Process incoming Undo Announce properly (#3676)
* [feature] Process incoming Undo Announce properly
* test undo announce
Diffstat (limited to 'internal/processing/workers')
| -rw-r--r-- | internal/processing/workers/fromfediapi.go | 39 | ||||
| -rw-r--r-- | internal/processing/workers/fromfediapi_test.go | 56 | 
2 files changed, 95 insertions, 0 deletions
diff --git a/internal/processing/workers/fromfediapi.go b/internal/processing/workers/fromfediapi.go index 096e285f6..cf93a5ec5 100644 --- a/internal/processing/workers/fromfediapi.go +++ b/internal/processing/workers/fromfediapi.go @@ -189,6 +189,14 @@ func (p *Processor) ProcessFromFediAPI(ctx context.Context, fMsg *messages.FromF  		if fMsg.APObjectType == ap.ActorPerson {  			return p.fediAPI.MoveAccount(ctx, fMsg)  		} + +	// UNDO SOMETHING +	case ap.ActivityUndo: + +		// UNDO ANNOUNCE +		if fMsg.APObjectType == ap.ActivityAnnounce { +			return p.fediAPI.UndoAnnounce(ctx, fMsg) +		}  	}  	return gtserror.Newf("unhandled: %s %s", fMsg.APActivityType, fMsg.APObjectType) @@ -1159,3 +1167,34 @@ func (p *fediAPI) RejectAnnounce(ctx context.Context, fMsg *messages.FromFediAPI  	return nil  } + +func (p *fediAPI) UndoAnnounce( +	ctx context.Context, +	fMsg *messages.FromFediAPI, +) error { +	boost, ok := fMsg.GTSModel.(*gtsmodel.Status) +	if !ok { +		return gtserror.Newf("%T not parseable as *gtsmodel.Status", fMsg.GTSModel) +	} + +	// Delete the boost wrapper itself. +	if err := p.state.DB.DeleteStatusByID(ctx, boost.ID); err != nil { +		return gtserror.Newf("db error deleting boost: %w", err) +	} + +	// Update statuses count for the requesting account. +	if err := p.utils.decrementStatusesCount(ctx, fMsg.Requesting, boost); err != nil { +		log.Errorf(ctx, "error updating account stats: %v", err) +	} + +	// Remove the boost wrapper from all timelines. +	if err := p.surface.deleteStatusFromTimelines(ctx, boost.ID); err != nil { +		log.Errorf(ctx, "error removing timelined boost: %v", err) +	} + +	// Interaction counts changed on the boosted status; +	// uncache the prepared version from all timelines. +	p.surface.invalidateStatusFromTimelines(ctx, boost.BoostOfID) + +	return nil +} diff --git a/internal/processing/workers/fromfediapi_test.go b/internal/processing/workers/fromfediapi_test.go index 70886d698..f3e719890 100644 --- a/internal/processing/workers/fromfediapi_test.go +++ b/internal/processing/workers/fromfediapi_test.go @@ -20,6 +20,7 @@ package workers_test  import (  	"context"  	"encoding/json" +	"errors"  	"fmt"  	"io"  	"testing" @@ -29,6 +30,7 @@ import (  	"github.com/superseriousbusiness/gotosocial/internal/ap"  	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"  	"github.com/superseriousbusiness/gotosocial/internal/db" +	"github.com/superseriousbusiness/gotosocial/internal/gtscontext"  	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"  	"github.com/superseriousbusiness/gotosocial/internal/messages"  	"github.com/superseriousbusiness/gotosocial/internal/stream" @@ -679,6 +681,60 @@ func (suite *FromFediAPITestSuite) TestMoveAccount() {  	suite.WithinDuration(time.Now(), move.SucceededAt, 1*time.Minute)  } +func (suite *FromFediAPITestSuite) TestUndoAnnounce() { +	var ( +		ctx            = context.Background() +		testStructs    = testrig.SetupTestStructs(rMediaPath, rTemplatePath) +		requestingAcct = suite.testAccounts["remote_account_1"] +		receivingAcct  = suite.testAccounts["local_account_1"] +		boostedStatus  = suite.testStatuses["admin_account_status_1"] +	) +	defer testrig.TearDownTestStructs(testStructs) + +	// Have remote_account_1 boost admin_account. +	boost, err := testStructs.TypeConverter.StatusToBoost( +		ctx, +		boostedStatus, +		requestingAcct, +		"", +	) +	if err != nil { +		suite.FailNow(err.Error()) +	} + +	// Set the boost URI + URL to +	// fossbros-anonymous.io. +	boost.URI = "https://fossbros-anonymous.io/users/foss_satan/" + boost.ID +	boost.URL = boost.URI + +	// Store the boost. +	if err := testStructs.State.DB.PutStatus(ctx, boost); err != nil { +		suite.FailNow(err.Error()) +	} + +	// Process the Undo. +	err = testStructs.Processor.Workers().ProcessFromFediAPI(ctx, &messages.FromFediAPI{ +		APObjectType:   ap.ActivityAnnounce, +		APActivityType: ap.ActivityUndo, +		GTSModel:       boost, +		Receiving:      receivingAcct, +		Requesting:     requestingAcct, +	}) +	suite.NoError(err) + +	// Wait for side effects to trigger: +	// the boost should be deleted. +	if !testrig.WaitFor(func() bool { +		_, err := testStructs.State.DB.GetStatusByID( +			gtscontext.SetBarebones(ctx), +			boost.ID, +		) +		return errors.Is(err, db.ErrNoEntries) +	}) { +		suite.FailNow("timed out waiting for boost to be removed") +	} +} +  func TestFromFederatorTestSuite(t *testing.T) {  	suite.Run(t, &FromFediAPITestSuite{})  }  | 
