Increase side effect actor test coverage.
Introduce DefaultCallback to the protocol interfaces.
このコミットが含まれているのは:
コミット
36a38b74b0
|
@ -64,7 +64,18 @@ type FederatingProtocol interface {
|
|||
// To override the default behavior, instead supply the function in
|
||||
// 'other', which does not guarantee the application will be compliant
|
||||
// with the ActivityPub Social Protocol.
|
||||
//
|
||||
// Applications are not expected to handle every single ActivityStreams
|
||||
// type and extension. The unhandled ones are passed to DefaultCallback.
|
||||
Callbacks(c context.Context) (wrapped FederatingWrappedCallbacks, other []interface{})
|
||||
// DefaultCallback is called for types that go-fed can deserialize but
|
||||
// are not handled by the application's callbacks returned in the
|
||||
// Callbacks method.
|
||||
//
|
||||
// Applications are not expected to handle every single ActivityStreams
|
||||
// type and extension, so the unhandled ones are passed to
|
||||
// DefaultCallback.
|
||||
DefaultCallback(c context.Context, activity Activity) error
|
||||
// MaxInboxForwardingRecursionDepth determines how deep to search within
|
||||
// an activity to determine if inbox forwarding needs to occur.
|
||||
//
|
||||
|
|
|
@ -250,7 +250,7 @@ func (w FederatingWrappedCallbacks) create(c context.Context, a vocab.ActivitySt
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
} else if t == nil {
|
||||
return fmt.Errorf("cannot handle federated create: object is neither a value nor IRI")
|
||||
}
|
||||
id, err := GetId(t)
|
||||
|
@ -509,7 +509,7 @@ func (w FederatingWrappedCallbacks) accept(c context.Context, a vocab.ActivitySt
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
} else if t == nil {
|
||||
return fmt.Errorf("cannot handle federated create: object is neither a value nor IRI")
|
||||
}
|
||||
// Ensure it is a Follow.
|
||||
|
|
|
@ -81,6 +81,20 @@ func (mr *MockFederatingProtocolMockRecorder) Callbacks(c interface{}) *gomock.C
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Callbacks", reflect.TypeOf((*MockFederatingProtocol)(nil).Callbacks), c)
|
||||
}
|
||||
|
||||
// DefaultCallback mocks base method
|
||||
func (m *MockFederatingProtocol) DefaultCallback(c context.Context, activity Activity) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DefaultCallback", c, activity)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DefaultCallback indicates an expected call of DefaultCallback
|
||||
func (mr *MockFederatingProtocolMockRecorder) DefaultCallback(c, activity interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DefaultCallback", reflect.TypeOf((*MockFederatingProtocol)(nil).DefaultCallback), c, activity)
|
||||
}
|
||||
|
||||
// MaxInboxForwardingRecursionDepth mocks base method
|
||||
func (m *MockFederatingProtocol) MaxInboxForwardingRecursionDepth(c context.Context) int {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -65,6 +65,20 @@ func (mr *MockSocialProtocolMockRecorder) Callbacks(c interface{}) *gomock.Call
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Callbacks", reflect.TypeOf((*MockSocialProtocol)(nil).Callbacks), c)
|
||||
}
|
||||
|
||||
// DefaultCallback mocks base method
|
||||
func (m *MockSocialProtocol) DefaultCallback(c context.Context, activity Activity) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DefaultCallback", c, activity)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DefaultCallback indicates an expected call of DefaultCallback
|
||||
func (mr *MockSocialProtocolMockRecorder) DefaultCallback(c, activity interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DefaultCallback", reflect.TypeOf((*MockSocialProtocol)(nil).DefaultCallback), c, activity)
|
||||
}
|
||||
|
||||
// GetOutbox mocks base method
|
||||
func (m *MockSocialProtocol) GetOutbox(c context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -15,14 +15,15 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
testMyInboxIRI = "https://example.com/addison/inbox"
|
||||
testMyOutboxIRI = "https://example.com/addison/outbox"
|
||||
testFederatedActivityIRI = "https://other.example.com/activity/1"
|
||||
testFederatedActorIRI = "https://other.example.com/dakota"
|
||||
testFederatedActorIRI2 = "https://other.example.com/addison"
|
||||
testNoteId1 = "https://example.com/note/1"
|
||||
testNoteId2 = "https://example.com/note/2"
|
||||
testNewActivityIRI = "https://example.com/new/1"
|
||||
testMyInboxIRI = "https://example.com/addison/inbox"
|
||||
testMyOutboxIRI = "https://example.com/addison/outbox"
|
||||
testFederatedActivityIRI = "https://other.example.com/activity/1"
|
||||
testFederatedActivityIRI2 = "https://other.example.com/activity/2"
|
||||
testFederatedActorIRI = "https://other.example.com/dakota"
|
||||
testFederatedActorIRI2 = "https://other.example.com/addison"
|
||||
testNoteId1 = "https://example.com/note/1"
|
||||
testNoteId2 = "https://example.com/note/2"
|
||||
testNewActivityIRI = "https://example.com/new/1"
|
||||
)
|
||||
|
||||
// mustParse parses a URL or panics.
|
||||
|
@ -79,6 +80,17 @@ var (
|
|||
// testOrderedCollectionDedupedElemsString is the JSON-LD version of the
|
||||
// testOrderedCollectionDedupedElems value with duplicates removed
|
||||
testOrderedCollectionDedupedElemsString string
|
||||
// testEmptyOrderedCollection is an empty OrderedCollectionPage.
|
||||
testEmptyOrderedCollection vocab.ActivityStreamsOrderedCollectionPage
|
||||
// testOrderedCollectionWithFederatedId has the federated Activity id.
|
||||
testOrderedCollectionWithFederatedId vocab.ActivityStreamsOrderedCollectionPage
|
||||
// testListen is a test Listen Activity.
|
||||
testListen vocab.ActivityStreamsListen
|
||||
// testOrderedCollectionWithFederatedId2 has the second federated
|
||||
// Activity id.
|
||||
testOrderedCollectionWithFederatedId2 vocab.ActivityStreamsOrderedCollectionPage
|
||||
// testOrderedCollectionWithBothFederatedIds has both federated Activity id.
|
||||
testOrderedCollectionWithBothFederatedIds vocab.ActivityStreamsOrderedCollectionPage
|
||||
)
|
||||
|
||||
// The test data cannot be created at init time since that is when the hooks of
|
||||
|
@ -94,6 +106,9 @@ func setupData() {
|
|||
content := streams.NewActivityStreamsContentProperty()
|
||||
content.AppendXMLSchemaString("This is a simple note being federated.")
|
||||
testFederatedNote.SetActivityStreamsContent(content)
|
||||
id := streams.NewActivityStreamsIdProperty()
|
||||
id.Set(mustParse(testNoteId1))
|
||||
testFederatedNote.SetActivityStreamsId(id)
|
||||
}()
|
||||
// testMyNote
|
||||
func() {
|
||||
|
@ -162,6 +177,45 @@ func setupData() {
|
|||
testOrderedCollectionDupedElems.SetActivityStreamsOrderedItems(oi)
|
||||
testOrderedCollectionDedupedElemsString = `{"@context":"https://www.w3.org/TR/activitystreams-vocabulary","orderedItems":"https://example.com/note/1","type":"OrderedCollectionPage"}`
|
||||
}()
|
||||
// testEmptyOrderedCollection
|
||||
func() {
|
||||
testEmptyOrderedCollection = streams.NewActivityStreamsOrderedCollectionPage()
|
||||
}()
|
||||
// testOrderedCollectionWithFederatedId
|
||||
func() {
|
||||
testOrderedCollectionWithFederatedId = streams.NewActivityStreamsOrderedCollectionPage()
|
||||
oi := streams.NewActivityStreamsOrderedItemsProperty()
|
||||
oi.AppendIRI(mustParse(testFederatedActivityIRI))
|
||||
testOrderedCollectionWithFederatedId.SetActivityStreamsOrderedItems(oi)
|
||||
}()
|
||||
// testListen
|
||||
func() {
|
||||
testListen = streams.NewActivityStreamsListen()
|
||||
id := streams.NewActivityStreamsIdProperty()
|
||||
id.Set(mustParse(testFederatedActivityIRI))
|
||||
testListen.SetActivityStreamsId(id)
|
||||
actor := streams.NewActivityStreamsActorProperty()
|
||||
actor.AppendIRI(mustParse(testFederatedActorIRI))
|
||||
testListen.SetActivityStreamsActor(actor)
|
||||
op := streams.NewActivityStreamsObjectProperty()
|
||||
op.AppendActivityStreamsNote(testFederatedNote)
|
||||
testListen.SetActivityStreamsObject(op)
|
||||
}()
|
||||
// testOrderedCollectionWithFederatedId2
|
||||
func() {
|
||||
testOrderedCollectionWithFederatedId2 = streams.NewActivityStreamsOrderedCollectionPage()
|
||||
oi := streams.NewActivityStreamsOrderedItemsProperty()
|
||||
oi.AppendIRI(mustParse(testFederatedActivityIRI2))
|
||||
testOrderedCollectionWithFederatedId2.SetActivityStreamsOrderedItems(oi)
|
||||
}()
|
||||
// testOrderedCollectionWithBothFederatedIds
|
||||
func() {
|
||||
testOrderedCollectionWithBothFederatedIds = streams.NewActivityStreamsOrderedCollectionPage()
|
||||
oi := streams.NewActivityStreamsOrderedItemsProperty()
|
||||
oi.AppendIRI(mustParse(testFederatedActivityIRI))
|
||||
oi.AppendIRI(mustParse(testFederatedActivityIRI2))
|
||||
testOrderedCollectionWithBothFederatedIds.SetActivityStreamsOrderedItems(oi)
|
||||
}()
|
||||
}
|
||||
|
||||
// wrappedInCreate returns a Create activity wrapping the given type.
|
||||
|
|
|
@ -105,12 +105,17 @@ func (a *sideEffectActor) PostInbox(c context.Context, inboxIRI *url.URL, activi
|
|||
wrapped.db = a.db
|
||||
wrapped.inboxIRI = inboxIRI
|
||||
wrapped.newTransport = a.common.NewTransport
|
||||
res, err := streams.NewTypeResolver(wrapped.callbacks(other))
|
||||
res, err := streams.NewTypeResolver(wrapped.callbacks(other)...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = res.Resolve(c, activity); err != nil {
|
||||
if err = res.Resolve(c, activity); err != nil && !streams.IsUnmatchedErr(err) {
|
||||
return err
|
||||
} else if streams.IsUnmatchedErr(err) {
|
||||
err = a.s2s.DefaultCallback(c, activity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -291,7 +296,7 @@ func (a *sideEffectActor) InboxForwarding(c context.Context, inboxIRI *url.URL,
|
|||
//
|
||||
// This implementation assumes all types are meant to be delivered except for
|
||||
// the ActivityStreams Block type.
|
||||
func (a *sideEffectActor) PostOutbox(c context.Context, activity Activity, outboxIRI *url.URL, rawJSON map[string]interface{}) (deliverable bool, e error) {
|
||||
func (a *sideEffectActor) PostOutbox(c context.Context, activity Activity, outboxIRI *url.URL, rawJSON map[string]interface{}) (deliverable bool, err error) {
|
||||
wrapped, other := a.c2s.Callbacks(c)
|
||||
// Populate side channels.
|
||||
wrapped.db = a.db
|
||||
|
@ -300,12 +305,19 @@ func (a *sideEffectActor) PostOutbox(c context.Context, activity Activity, outbo
|
|||
wrapped.clock = a.clock
|
||||
wrapped.newTransport = a.common.NewTransport
|
||||
wrapped.deliverable = &deliverable
|
||||
res, err := streams.NewTypeResolver(wrapped.callbacks(other))
|
||||
var res *streams.TypeResolver
|
||||
res, err = streams.NewTypeResolver(wrapped.callbacks(other)...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err = res.Resolve(c, activity); err != nil {
|
||||
if err = res.Resolve(c, activity); err != nil && !streams.IsUnmatchedErr(err) {
|
||||
return
|
||||
} else if streams.IsUnmatchedErr(err) {
|
||||
deliverable = true
|
||||
err = a.c2s.DefaultCallback(c, activity)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
err = a.addToOutbox(c, outboxIRI, activity)
|
||||
return
|
||||
|
|
|
@ -2,6 +2,7 @@ package pub
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/go-fed/activity/streams/vocab"
|
||||
"github.com/golang/mock/gomock"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
|
@ -11,10 +12,10 @@ import (
|
|||
// TestPassThroughMethods tests the methods that pass-through to other
|
||||
// dependency-injected types.
|
||||
func TestPassThroughMethods(t *testing.T) {
|
||||
setupData()
|
||||
ctx := context.Background()
|
||||
resp := httptest.NewRecorder()
|
||||
setupFn := func(ctl *gomock.Controller) (c *MockCommonBehavior, fp *MockFederatingProtocol, sp *MockSocialProtocol, db *MockDatabase, cl *MockClock, a DelegateActor) {
|
||||
setupData()
|
||||
c = NewMockCommonBehavior(ctl)
|
||||
fp = NewMockFederatingProtocol(ctl)
|
||||
sp = NewMockSocialProtocol(ctl)
|
||||
|
@ -22,10 +23,10 @@ func TestPassThroughMethods(t *testing.T) {
|
|||
cl = NewMockClock(ctl)
|
||||
a = &sideEffectActor{
|
||||
common: c,
|
||||
s2s: fp,
|
||||
c2s: sp,
|
||||
db: db,
|
||||
clock: cl,
|
||||
s2s: fp,
|
||||
c2s: sp,
|
||||
db: db,
|
||||
clock: cl,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -113,10 +114,10 @@ func TestPassThroughMethods(t *testing.T) {
|
|||
// TestAuthorizePostInbox tests the Authorization for a federated message, which
|
||||
// is only based on blocks.
|
||||
func TestAuthorizePostInbox(t *testing.T) {
|
||||
setupData()
|
||||
ctx := context.Background()
|
||||
resp := httptest.NewRecorder()
|
||||
setupFn := func(ctl *gomock.Controller) (c *MockCommonBehavior, fp *MockFederatingProtocol, sp *MockSocialProtocol, db *MockDatabase, cl *MockClock, a DelegateActor) {
|
||||
setupData()
|
||||
c = NewMockCommonBehavior(ctl)
|
||||
fp = NewMockFederatingProtocol(ctl)
|
||||
sp = NewMockSocialProtocol(ctl)
|
||||
|
@ -124,10 +125,10 @@ func TestAuthorizePostInbox(t *testing.T) {
|
|||
cl = NewMockClock(ctl)
|
||||
a = &sideEffectActor{
|
||||
common: c,
|
||||
s2s: fp,
|
||||
c2s: sp,
|
||||
db: db,
|
||||
clock: cl,
|
||||
s2s: fp,
|
||||
c2s: sp,
|
||||
db: db,
|
||||
clock: cl,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -185,23 +186,160 @@ func TestAuthorizePostInbox(t *testing.T) {
|
|||
// TestPostInbox ensures that the main application side effects of receiving a
|
||||
// federated message occur.
|
||||
func TestPostInbox(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
setupFn := func(ctl *gomock.Controller) (c *MockCommonBehavior, fp *MockFederatingProtocol, sp *MockSocialProtocol, db *MockDatabase, cl *MockClock, a DelegateActor) {
|
||||
setupData()
|
||||
c = NewMockCommonBehavior(ctl)
|
||||
fp = NewMockFederatingProtocol(ctl)
|
||||
sp = NewMockSocialProtocol(ctl)
|
||||
db = NewMockDatabase(ctl)
|
||||
cl = NewMockClock(ctl)
|
||||
a = &sideEffectActor{
|
||||
common: c,
|
||||
s2s: fp,
|
||||
c2s: sp,
|
||||
db: db,
|
||||
clock: cl,
|
||||
}
|
||||
return
|
||||
}
|
||||
// Run tests
|
||||
t.Run("AddsToEmptyInbox", func(t *testing.T) {
|
||||
t.Fail()
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, fp, _, db, _, a := setupFn(ctl)
|
||||
inboxIRI := mustParse(testMyInboxIRI)
|
||||
gomock.InOrder(
|
||||
db.EXPECT().Lock(ctx, inboxIRI),
|
||||
db.EXPECT().InboxContains(ctx, inboxIRI, mustParse(testFederatedActivityIRI)).Return(false, nil),
|
||||
db.EXPECT().GetInbox(ctx, inboxIRI).Return(testEmptyOrderedCollection, nil),
|
||||
db.EXPECT().SetInbox(ctx, testOrderedCollectionWithFederatedId).Return(nil),
|
||||
db.EXPECT().Unlock(ctx, inboxIRI),
|
||||
)
|
||||
fp.EXPECT().Callbacks(ctx).Return(FederatingWrappedCallbacks{}, nil)
|
||||
fp.EXPECT().DefaultCallback(ctx, testListen).Return(nil)
|
||||
// Run
|
||||
err := a.PostInbox(ctx, inboxIRI, testListen)
|
||||
// Verify
|
||||
assertEqual(t, err, nil)
|
||||
})
|
||||
t.Run("DoesNotAddToInboxIfDuplicate", func(t *testing.T) {
|
||||
t.Fail()
|
||||
t.Run("DoesNotAddToInboxNorDoSideEffectsIfDuplicate", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, _, db, _, a := setupFn(ctl)
|
||||
inboxIRI := mustParse(testMyInboxIRI)
|
||||
gomock.InOrder(
|
||||
db.EXPECT().Lock(ctx, inboxIRI),
|
||||
db.EXPECT().InboxContains(ctx, inboxIRI, mustParse(testFederatedActivityIRI)).Return(true, nil),
|
||||
db.EXPECT().Unlock(ctx, inboxIRI),
|
||||
)
|
||||
// Run
|
||||
err := a.PostInbox(ctx, inboxIRI, testListen)
|
||||
// Verify
|
||||
assertEqual(t, err, nil)
|
||||
})
|
||||
t.Run("AddsToInbox", func(t *testing.T) {
|
||||
t.Fail()
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, fp, _, db, _, a := setupFn(ctl)
|
||||
inboxIRI := mustParse(testMyInboxIRI)
|
||||
gomock.InOrder(
|
||||
db.EXPECT().Lock(ctx, inboxIRI),
|
||||
db.EXPECT().InboxContains(ctx, inboxIRI, mustParse(testFederatedActivityIRI)).Return(false, nil),
|
||||
db.EXPECT().GetInbox(ctx, inboxIRI).Return(testOrderedCollectionWithFederatedId2, nil),
|
||||
db.EXPECT().SetInbox(ctx, testOrderedCollectionWithBothFederatedIds).Return(nil),
|
||||
db.EXPECT().Unlock(ctx, inboxIRI),
|
||||
)
|
||||
fp.EXPECT().Callbacks(ctx).Return(FederatingWrappedCallbacks{}, nil)
|
||||
fp.EXPECT().DefaultCallback(ctx, testListen).Return(nil)
|
||||
// Run
|
||||
err := a.PostInbox(ctx, inboxIRI, testListen)
|
||||
// Verify
|
||||
assertEqual(t, err, nil)
|
||||
})
|
||||
t.Run("ResolvesToCustomFunction", func(t *testing.T) {
|
||||
t.Fail()
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, fp, _, db, _, a := setupFn(ctl)
|
||||
inboxIRI := mustParse(testMyInboxIRI)
|
||||
gomock.InOrder(
|
||||
db.EXPECT().Lock(ctx, inboxIRI),
|
||||
db.EXPECT().InboxContains(ctx, inboxIRI, mustParse(testFederatedActivityIRI)).Return(false, nil),
|
||||
db.EXPECT().GetInbox(ctx, inboxIRI).Return(testEmptyOrderedCollection, nil),
|
||||
db.EXPECT().SetInbox(ctx, testOrderedCollectionWithFederatedId).Return(nil),
|
||||
db.EXPECT().Unlock(ctx, inboxIRI),
|
||||
)
|
||||
pass := false
|
||||
fp.EXPECT().Callbacks(ctx).Return(FederatingWrappedCallbacks{}, []interface{}{
|
||||
func(c context.Context, a vocab.ActivityStreamsListen) error {
|
||||
pass = true
|
||||
return nil
|
||||
},
|
||||
})
|
||||
// Run
|
||||
err := a.PostInbox(ctx, inboxIRI, testListen)
|
||||
// Verify
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, pass, true)
|
||||
})
|
||||
t.Run("ResolvesToOverriddenFunction", func(t *testing.T) {
|
||||
t.Fail()
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, fp, _, db, _, a := setupFn(ctl)
|
||||
inboxIRI := mustParse(testMyInboxIRI)
|
||||
gomock.InOrder(
|
||||
db.EXPECT().Lock(ctx, inboxIRI),
|
||||
db.EXPECT().InboxContains(ctx, inboxIRI, mustParse(testFederatedActivityIRI)).Return(false, nil),
|
||||
db.EXPECT().GetInbox(ctx, inboxIRI).Return(testEmptyOrderedCollection, nil),
|
||||
db.EXPECT().SetInbox(ctx, testOrderedCollectionWithFederatedId).Return(nil),
|
||||
db.EXPECT().Unlock(ctx, inboxIRI),
|
||||
)
|
||||
pass := false
|
||||
fp.EXPECT().Callbacks(ctx).Return(FederatingWrappedCallbacks{}, []interface{}{
|
||||
func(c context.Context, a vocab.ActivityStreamsCreate) error {
|
||||
pass = true
|
||||
return nil
|
||||
},
|
||||
})
|
||||
// Run
|
||||
err := a.PostInbox(ctx, inboxIRI, testCreate)
|
||||
// Verify
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, pass, true)
|
||||
})
|
||||
t.Run("ResolvesToDefaultFunction", func(t *testing.T) {
|
||||
t.Fail()
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, fp, _, db, _, a := setupFn(ctl)
|
||||
inboxIRI := mustParse(testMyInboxIRI)
|
||||
gomock.InOrder(
|
||||
db.EXPECT().Lock(ctx, inboxIRI),
|
||||
db.EXPECT().InboxContains(ctx, inboxIRI, mustParse(testFederatedActivityIRI)).Return(false, nil),
|
||||
db.EXPECT().GetInbox(ctx, inboxIRI).Return(testEmptyOrderedCollection, nil),
|
||||
db.EXPECT().SetInbox(ctx, testOrderedCollectionWithFederatedId).Return(nil),
|
||||
db.EXPECT().Unlock(ctx, inboxIRI),
|
||||
)
|
||||
pass := false
|
||||
fp.EXPECT().Callbacks(ctx).Return(FederatingWrappedCallbacks{
|
||||
Create: func(c context.Context, a vocab.ActivityStreamsCreate) error {
|
||||
pass = true
|
||||
return nil
|
||||
},
|
||||
}, nil)
|
||||
db.EXPECT().Lock(ctx, mustParse(testNoteId1))
|
||||
db.EXPECT().Create(ctx, testFederatedNote)
|
||||
db.EXPECT().Unlock(ctx, mustParse(testNoteId1))
|
||||
// Run
|
||||
err := a.PostInbox(ctx, inboxIRI, testCreate)
|
||||
// Verify
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, pass, true)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,18 @@ type SocialProtocol interface {
|
|||
// To override the default behavior, instead supply the function in
|
||||
// 'other', which does not guarantee the application will be compliant
|
||||
// with the ActivityPub Social Protocol.
|
||||
//
|
||||
// Applications are not expected to handle every single ActivityStreams
|
||||
// type and extension. The unhandled ones are passed to DefaultCallback.
|
||||
Callbacks(c context.Context) (wrapped SocialWrappedCallbacks, other []interface{})
|
||||
// DefaultCallback is called for types that go-fed can deserialize but
|
||||
// are not handled by the application's callbacks returned in the
|
||||
// Callbacks method.
|
||||
//
|
||||
// Applications are not expected to handle every single ActivityStreams
|
||||
// type and extension, so the unhandled ones are passed to
|
||||
// DefaultCallback.
|
||||
DefaultCallback(c context.Context, activity Activity) error
|
||||
// GetOutbox returns the OrderedCollection inbox of the actor for this
|
||||
// context. It is up to the implementation to provide the correct
|
||||
// collection for the kind of authorization given in the request.
|
||||
|
|
読み込み中…
新しいイシューから参照