go-fed-activity/pub/federating_wrapped_callback...

1835 lines
60 KiB
Go

package pub
import (
"context"
"net/url"
"testing"
"github.com/go-fed/activity/streams"
"github.com/go-fed/activity/streams/vocab"
"github.com/golang/mock/gomock"
)
// TestFederatedCallbacks tests the overriding functionality.
func TestFederatedCallbacks(t *testing.T) {
t.Run("ReturnsOtherCallback", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsListen) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsListen) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find extra function")
}
})
t.Run("OverridesCreate", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsCreate) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsCreate) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesUpdate", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsUpdate) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsUpdate) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesDelete", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsDelete) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsDelete) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesFollow", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsFollow) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsFollow) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesAccept", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsAccept) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsAccept) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesReject", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsReject) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsReject) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesAdd", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsAdd) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsAdd) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesRemove", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsRemove) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsRemove) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesLike", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsLike) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsLike) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesAnnounce", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsAnnounce) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsAnnounce) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesUndo", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsUndo) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsUndo) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
t.Run("OverridesBlock", func(t *testing.T) {
ok := false
o := func(context.Context, vocab.ActivityStreamsBlock) error {
ok = true
return nil
}
var w FederatingWrappedCallbacks
for _, f := range w.callbacks([]interface{}{o}) {
if fn, ok := f.(func(context.Context, vocab.ActivityStreamsBlock) error); ok {
fn(nil, nil)
}
}
if !ok {
t.Fatalf("could not find overridden function")
}
})
}
func TestFederatedCreate(t *testing.T) {
newCreateFn := func() vocab.ActivityStreamsCreate {
c := streams.NewActivityStreamsCreate()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testFederatedActivityIRI))
c.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
c.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendActivityStreamsNote(testFederatedNote)
c.SetActivityStreamsObject(op)
return c
}
ctx := context.Background()
setupFn := func(ctl *gomock.Controller) (w FederatingWrappedCallbacks, mockDB *MockDatabase, mockTp *MockTransport) {
mockDB = NewMockDatabase(ctl)
mockTp = NewMockTransport(ctl)
w.db = mockDB
w.newTransport = func(c context.Context, a *url.URL, s string) (Transport, error) {
return mockTp, nil
}
return
}
t.Run("ErrorIfNoObject", func(t *testing.T) {
c := newCreateFn()
c.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.create(ctx, c)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfObjectLengthZero", func(t *testing.T) {
c := newCreateFn()
c.GetActivityStreamsObject().Remove(0)
var w FederatingWrappedCallbacks
err := w.create(ctx, c)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("CreatesFederatedObject", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB, _ := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Create(ctx, testFederatedNote)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
c := newCreateFn()
err := w.create(ctx, c)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("CreatesAllFederatedObjects", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB, _ := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Create(ctx, testFederatedNote)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId2))
mockDB.EXPECT().Create(ctx, testFederatedNote2)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId2))
c := newCreateFn()
c.GetActivityStreamsObject().AppendActivityStreamsNote(testFederatedNote2)
err := w.create(ctx, c)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("DereferencesIRIObject", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB, mockTp := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Create(ctx, toDeserializedForm(testFederatedNote))
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
mockTp.EXPECT().Dereference(ctx, mustParse(testNoteId1)).Return(
mustSerializeToBytes(testFederatedNote), nil)
c := newCreateFn()
op := streams.NewActivityStreamsObjectProperty()
op.AppendIRI(mustParse(testNoteId1))
c.SetActivityStreamsObject(op)
err := w.create(ctx, c)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB, _ := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Create(ctx, testFederatedNote)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
c := newCreateFn()
var gotc context.Context
var got vocab.ActivityStreamsCreate
w.Create = func(ctx context.Context, v vocab.ActivityStreamsCreate) error {
gotc = ctx
got = v
return nil
}
err := w.create(ctx, c)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, c, got)
})
}
func TestFederatedUpdate(t *testing.T) {
newUpdateFn := func() vocab.ActivityStreamsUpdate {
u := streams.NewActivityStreamsUpdate()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testNewActivityIRI))
u.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
u.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendActivityStreamsNote(testFederatedNote)
u.SetActivityStreamsObject(op)
return u
}
ctx := context.Background()
setupFn := func(ctl *gomock.Controller) (w FederatingWrappedCallbacks, mockDB *MockDatabase) {
mockDB = NewMockDatabase(ctl)
w.db = mockDB
return
}
t.Run("ErrorIfNoObject", func(t *testing.T) {
u := newUpdateFn()
u.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.update(ctx, u)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfObjectLengthZero", func(t *testing.T) {
u := newUpdateFn()
u.GetActivityStreamsObject().Remove(0)
var w FederatingWrappedCallbacks
err := w.update(ctx, u)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfOriginMismatchesObject", func(t *testing.T) {
u := newUpdateFn()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testFederatedActivityIRI))
u.SetJSONLDId(id)
var w FederatingWrappedCallbacks
err := w.update(ctx, u)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("UpdatesFederatedObject", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Update(ctx, testFederatedNote)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
u := newUpdateFn()
err := w.update(ctx, u)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("UpdatesAllFederatedObjects", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Update(ctx, testFederatedNote)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId2))
mockDB.EXPECT().Update(ctx, testFederatedNote2)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId2))
u := newUpdateFn()
u.GetActivityStreamsObject().AppendActivityStreamsNote(testFederatedNote2)
err := w.update(ctx, u)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("ErrorIfObjectIsIRI", func(t *testing.T) {
u := newUpdateFn()
op := streams.NewActivityStreamsObjectProperty()
op.AppendIRI(mustParse(testNoteId1))
u.SetActivityStreamsObject(op)
var w FederatingWrappedCallbacks
err := w.update(ctx, u)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Update(ctx, testFederatedNote)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
u := newUpdateFn()
var gotc context.Context
var got vocab.ActivityStreamsUpdate
w.Update = func(ctx context.Context, v vocab.ActivityStreamsUpdate) error {
gotc = ctx
got = v
return nil
}
err := w.update(ctx, u)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, u, got)
})
}
func TestFederatedDelete(t *testing.T) {
newDeleteFn := func() vocab.ActivityStreamsDelete {
d := streams.NewActivityStreamsDelete()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testNewActivityIRI))
d.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
d.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendIRI(mustParse(testNoteId1))
d.SetActivityStreamsObject(op)
return d
}
ctx := context.Background()
setupFn := func(ctl *gomock.Controller) (w FederatingWrappedCallbacks, mockDB *MockDatabase) {
mockDB = NewMockDatabase(ctl)
w.db = mockDB
return
}
t.Run("ErrorIfNoObject", func(t *testing.T) {
d := newDeleteFn()
d.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.deleteFn(ctx, d)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfObjectLengthZero", func(t *testing.T) {
d := newDeleteFn()
d.GetActivityStreamsObject().Remove(0)
var w FederatingWrappedCallbacks
err := w.deleteFn(ctx, d)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfOriginMismatchesObject", func(t *testing.T) {
d := newDeleteFn()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testFederatedActivityIRI))
d.SetJSONLDId(id)
var w FederatingWrappedCallbacks
err := w.deleteFn(ctx, d)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("DeletesFederatedObject", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Delete(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
d := newDeleteFn()
err := w.deleteFn(ctx, d)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("DeletesAllFederatedObjects", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Delete(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId2))
mockDB.EXPECT().Delete(ctx, mustParse(testNoteId2))
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId2))
d := newDeleteFn()
d.GetActivityStreamsObject().AppendIRI(mustParse(testNoteId2))
err := w.deleteFn(ctx, d)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Delete(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
d := newDeleteFn()
var gotc context.Context
var got vocab.ActivityStreamsDelete
w.Delete = func(ctx context.Context, v vocab.ActivityStreamsDelete) error {
gotc = ctx
got = v
return nil
}
err := w.deleteFn(ctx, d)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, d, got)
})
}
func TestFederatedFollow(t *testing.T) {
newFollowFn := func() vocab.ActivityStreamsFollow {
f := streams.NewActivityStreamsFollow()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testNewActivityIRI))
f.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
f.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendIRI(mustParse(testFederatedActorIRI2))
f.SetActivityStreamsObject(op)
return f
}
ctx := context.Background()
setupFn := func(ctl *gomock.Controller) (w FederatingWrappedCallbacks, mockDB *MockDatabase) {
mockDB = NewMockDatabase(ctl)
w.db = mockDB
w.inboxIRI = mustParse(testMyInboxIRI)
return
}
t.Run("ErrorIfNoObject", func(t *testing.T) {
f := newFollowFn()
f.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.follow(ctx, f)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfObjectLengthZero", func(t *testing.T) {
f := newFollowFn()
f.GetActivityStreamsObject().Remove(0)
var w FederatingWrappedCallbacks
err := w.follow(ctx, f)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("OnFollowNothingDoesNothing", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
w.OnFollow = OnFollowDoNothing
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().ActorForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testFederatedActorIRI2), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
f := newFollowFn()
err := w.follow(ctx, f)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("OnFollowAutomaticallyAcceptUpdatesFollowers", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
w.OnFollow = OnFollowAutomaticallyAccept
w.addNewIds = func(c context.Context, activity Activity) error {
return nil
}
w.deliver = func(c context.Context, outboxIRI *url.URL, activity Activity) error {
return nil
}
followers := streams.NewActivityStreamsCollection()
expectFollowers := streams.NewActivityStreamsCollection()
expectItems := streams.NewActivityStreamsItemsProperty()
expectItems.AppendIRI(mustParse(testFederatedActorIRI))
expectFollowers.SetActivityStreamsItems(expectItems)
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().ActorForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testFederatedActorIRI2), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().Lock(ctx, mustParse(testFederatedActorIRI2))
mockDB.EXPECT().Followers(ctx, mustParse(testFederatedActorIRI2)).Return(
followers, nil)
mockDB.EXPECT().Update(ctx, expectFollowers)
mockDB.EXPECT().Unlock(ctx, mustParse(testFederatedActorIRI2))
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().OutboxForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testMyOutboxIRI), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
f := newFollowFn()
err := w.follow(ctx, f)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("OnFollowAutomaticallyAcceptDelivers", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
w.OnFollow = OnFollowAutomaticallyAccept
w.addNewIds = func(c context.Context, activity Activity) error {
return nil
}
w.deliver = func(c context.Context, outboxIRI *url.URL, activity Activity) error {
if !streams.IsOrExtendsActivityStreamsAccept(activity) {
t.Fatalf("expected Accept, got %T", activity)
}
return nil
}
followers := streams.NewActivityStreamsCollection()
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().ActorForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testFederatedActorIRI2), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().Lock(ctx, mustParse(testFederatedActorIRI2))
mockDB.EXPECT().Followers(ctx, mustParse(testFederatedActorIRI2)).Return(
followers, nil)
mockDB.EXPECT().Update(ctx, gomock.Any())
mockDB.EXPECT().Unlock(ctx, mustParse(testFederatedActorIRI2))
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().OutboxForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testMyOutboxIRI), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
f := newFollowFn()
err := w.follow(ctx, f)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("OnFollowAutomaticallyRejectDelivers", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
w.OnFollow = OnFollowAutomaticallyReject
w.addNewIds = func(c context.Context, activity Activity) error {
return nil
}
w.deliver = func(c context.Context, outboxIRI *url.URL, activity Activity) error {
if !streams.IsOrExtendsActivityStreamsReject(activity) {
t.Fatalf("expected Reject, got %T", activity)
}
return nil
}
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().ActorForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testFederatedActorIRI2), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().OutboxForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testMyOutboxIRI), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
f := newFollowFn()
err := w.follow(ctx, f)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
w.OnFollow = OnFollowDoNothing
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().ActorForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testFederatedActorIRI2), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
f := newFollowFn()
var gotc context.Context
var got vocab.ActivityStreamsFollow
w.Follow = func(ctx context.Context, v vocab.ActivityStreamsFollow) error {
gotc = ctx
got = v
return nil
}
err := w.follow(ctx, f)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, f, got)
})
}
func TestFederatedAccept(t *testing.T) {
newAcceptFn := func() vocab.ActivityStreamsAccept {
c := streams.NewActivityStreamsAccept()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testFederatedActivityIRI2))
c.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
c.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendActivityStreamsFollow(testFollow)
c.SetActivityStreamsObject(op)
return c
}
ctx := context.Background()
setupFn := func(ctl *gomock.Controller) (w FederatingWrappedCallbacks, mockDB *MockDatabase, mockTp *MockTransport) {
mockDB = NewMockDatabase(ctl)
mockTp = NewMockTransport(ctl)
w.inboxIRI = mustParse(testMyInboxIRI)
w.db = mockDB
w.newTransport = func(c context.Context, a *url.URL, s string) (Transport, error) {
return mockTp, nil
}
return
}
t.Run("DoesNothingIfNoObjects", func(t *testing.T) {
a := newAcceptFn()
a.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.accept(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("DereferencesObjectIRI", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB, mockTp := setupFn(ctl)
followers := streams.NewActivityStreamsCollection()
expectFollowers := streams.NewActivityStreamsCollection()
expectItems := streams.NewActivityStreamsItemsProperty()
expectItems.AppendIRI(mustParse(testFederatedActorIRI))
expectFollowers.SetActivityStreamsItems(expectItems)
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().ActorForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testFederatedActorIRI2), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
mockTp.EXPECT().Dereference(ctx, mustParse(testFederatedActivityIRI)).Return(
mustSerializeToBytes(testFollow), nil)
mockDB.EXPECT().Lock(ctx, mustParse(testFederatedActivityIRI))
mockDB.EXPECT().Get(ctx, mustParse(testFederatedActivityIRI)).Return(
testFollow, nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testFederatedActivityIRI))
mockDB.EXPECT().Lock(ctx, mustParse(testFederatedActorIRI2))
mockDB.EXPECT().Following(ctx, mustParse(testFederatedActorIRI2)).Return(
followers, nil)
mockDB.EXPECT().Update(ctx, expectFollowers)
mockDB.EXPECT().Unlock(ctx, mustParse(testFederatedActorIRI2))
a := newAcceptFn()
op := streams.NewActivityStreamsObjectProperty()
op.AppendIRI(mustParse(testFederatedActivityIRI))
a.SetActivityStreamsObject(op)
err := w.accept(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("IgnoresNonFollowObjects", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB, _ := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().ActorForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testFederatedActorIRI2), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
a := newAcceptFn()
op := streams.NewActivityStreamsObjectProperty()
op.AppendActivityStreamsListen(testListen)
a.SetActivityStreamsObject(op)
err := w.accept(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("IgnoresFollowObjectsNotContainingMe", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB, _ := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().ActorForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testFederatedActorIRI3), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
a := newAcceptFn()
err := w.accept(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("ErrorIfPeerLiedAboutOurFollowId", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB, _ := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().ActorForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testFederatedActorIRI2), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().Lock(ctx, mustParse(testFederatedActivityIRI))
mockDB.EXPECT().Get(ctx, mustParse(testFederatedActivityIRI)).Return(
testListen, nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testFederatedActivityIRI))
a := newAcceptFn()
err := w.accept(ctx, a)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("UpdatesFollowingCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB, _ := setupFn(ctl)
followers := streams.NewActivityStreamsCollection()
expectFollowers := streams.NewActivityStreamsCollection()
expectItems := streams.NewActivityStreamsItemsProperty()
expectItems.AppendIRI(mustParse(testFederatedActorIRI))
expectFollowers.SetActivityStreamsItems(expectItems)
mockDB.EXPECT().Lock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().ActorForInbox(ctx, mustParse(testMyInboxIRI)).Return(
mustParse(testFederatedActorIRI2), nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testMyInboxIRI))
mockDB.EXPECT().Lock(ctx, mustParse(testFederatedActivityIRI))
mockDB.EXPECT().Get(ctx, mustParse(testFederatedActivityIRI)).Return(
testFollow, nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testFederatedActivityIRI))
mockDB.EXPECT().Lock(ctx, mustParse(testFederatedActorIRI2))
mockDB.EXPECT().Following(ctx, mustParse(testFederatedActorIRI2)).Return(
followers, nil)
mockDB.EXPECT().Update(ctx, expectFollowers)
mockDB.EXPECT().Unlock(ctx, mustParse(testFederatedActorIRI2))
a := newAcceptFn()
err := w.accept(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
a := newAcceptFn()
a.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
var gotc context.Context
var got vocab.ActivityStreamsAccept
w.Accept = func(ctx context.Context, v vocab.ActivityStreamsAccept) error {
gotc = ctx
got = v
return nil
}
err := w.accept(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, a, got)
})
}
func TestFederatedReject(t *testing.T) {
ctx := context.Background()
t.Run("CallsCustomCallback", func(t *testing.T) {
r := streams.NewActivityStreamsReject()
var w FederatingWrappedCallbacks
var gotc context.Context
var got vocab.ActivityStreamsReject
w.Reject = func(ctx context.Context, v vocab.ActivityStreamsReject) error {
gotc = ctx
got = v
return nil
}
err := w.reject(ctx, r)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, r, got)
})
}
func TestFederatedAdd(t *testing.T) {
newAddFn := func() vocab.ActivityStreamsAdd {
a := streams.NewActivityStreamsAdd()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testFederatedActivityIRI))
a.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
a.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendActivityStreamsNote(testFederatedNote)
a.SetActivityStreamsObject(op)
tp := streams.NewActivityStreamsTargetProperty()
tp.AppendIRI(mustParse(testAudienceIRI))
a.SetActivityStreamsTarget(tp)
return a
}
ctx := context.Background()
setupFn := func(ctl *gomock.Controller) (w FederatingWrappedCallbacks, mockDB *MockDatabase) {
mockDB = NewMockDatabase(ctl)
w.db = mockDB
return
}
t.Run("ErrorIfNoObject", func(t *testing.T) {
a := newAddFn()
a.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.add(ctx, a)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfObjectLengthZero", func(t *testing.T) {
a := newAddFn()
a.GetActivityStreamsObject().Remove(0)
var w FederatingWrappedCallbacks
err := w.add(ctx, a)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfNoTarget", func(t *testing.T) {
a := newAddFn()
a.SetActivityStreamsTarget(nil)
var w FederatingWrappedCallbacks
err := w.add(ctx, a)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfTargetLengthZero", func(t *testing.T) {
a := newAddFn()
a.GetActivityStreamsTarget().Remove(0)
var w FederatingWrappedCallbacks
err := w.add(ctx, a)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("AddsAllObjectIdsToCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
col1 := streams.NewActivityStreamsCollection()
expectCol1 := streams.NewActivityStreamsCollection()
items1 := streams.NewActivityStreamsItemsProperty()
items1.AppendIRI(mustParse(testNoteId1))
items1.AppendIRI(mustParse(testNoteId2))
expectCol1.SetActivityStreamsItems(items1)
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI)).Return(
col1, nil)
mockDB.EXPECT().Update(ctx, expectCol1).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI))
a := newAddFn()
a.GetActivityStreamsObject().AppendActivityStreamsNote(testFederatedNote2)
err := w.add(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("AddsAllObjectIdsToOrderedCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
col1 := streams.NewActivityStreamsOrderedCollection()
expectCol1 := streams.NewActivityStreamsOrderedCollection()
items1 := streams.NewActivityStreamsOrderedItemsProperty()
items1.AppendIRI(mustParse(testNoteId1))
items1.AppendIRI(mustParse(testNoteId2))
expectCol1.SetActivityStreamsOrderedItems(items1)
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI)).Return(
col1, nil)
mockDB.EXPECT().Update(ctx, expectCol1).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI))
a := newAddFn()
a.GetActivityStreamsObject().AppendActivityStreamsNote(testFederatedNote2)
err := w.add(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("AddsAllObjectIdsToEachTarget", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
col1 := streams.NewActivityStreamsCollection()
expectCol1 := streams.NewActivityStreamsCollection()
items1 := streams.NewActivityStreamsItemsProperty()
items1.AppendIRI(mustParse(testNoteId1))
expectCol1.SetActivityStreamsItems(items1)
col2 := streams.NewActivityStreamsCollection()
expectCol2 := streams.NewActivityStreamsCollection()
items2 := streams.NewActivityStreamsItemsProperty()
items2.AppendIRI(mustParse(testNoteId1))
expectCol2.SetActivityStreamsItems(items2)
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI)).Return(
col1, nil)
mockDB.EXPECT().Update(ctx, expectCol1).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI2))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI2)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI2)).Return(
col2, nil)
mockDB.EXPECT().Update(ctx, expectCol2).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI2))
a := newAddFn()
a.GetActivityStreamsTarget().AppendIRI(mustParse(testAudienceIRI2))
err := w.add(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("ReturnsErrorIfTargetIsNotCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
notCol := streams.NewActivityStreamsNote()
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI)).Return(
notCol, nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI))
a := newAddFn()
err := w.add(ctx, a)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
col1 := streams.NewActivityStreamsCollection()
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI)).Return(
col1, nil)
mockDB.EXPECT().Update(ctx, gomock.Any()).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI))
var gotc context.Context
var got vocab.ActivityStreamsAdd
w.Add = func(ctx context.Context, v vocab.ActivityStreamsAdd) error {
gotc = ctx
got = v
return nil
}
a := newAddFn()
err := w.add(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, a, got)
})
}
func TestFederatedRemove(t *testing.T) {
newRemoveFn := func() vocab.ActivityStreamsRemove {
r := streams.NewActivityStreamsRemove()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testFederatedActivityIRI))
r.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
r.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendActivityStreamsNote(testFederatedNote)
r.SetActivityStreamsObject(op)
tp := streams.NewActivityStreamsTargetProperty()
tp.AppendIRI(mustParse(testAudienceIRI))
r.SetActivityStreamsTarget(tp)
return r
}
ctx := context.Background()
setupFn := func(ctl *gomock.Controller) (w FederatingWrappedCallbacks, mockDB *MockDatabase) {
mockDB = NewMockDatabase(ctl)
w.db = mockDB
return
}
t.Run("ErrorIfNoObject", func(t *testing.T) {
r := newRemoveFn()
r.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.remove(ctx, r)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfObjectLengthZero", func(t *testing.T) {
r := newRemoveFn()
r.GetActivityStreamsObject().Remove(0)
var w FederatingWrappedCallbacks
err := w.remove(ctx, r)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfNoTarget", func(t *testing.T) {
r := newRemoveFn()
r.SetActivityStreamsTarget(nil)
var w FederatingWrappedCallbacks
err := w.remove(ctx, r)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfTargetLengthZero", func(t *testing.T) {
r := newRemoveFn()
r.GetActivityStreamsTarget().Remove(0)
var w FederatingWrappedCallbacks
err := w.remove(ctx, r)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("RemovesAllObjectIdsFromCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
col1 := streams.NewActivityStreamsCollection()
items := streams.NewActivityStreamsItemsProperty()
items.AppendIRI(mustParse(testAudienceIRI))
items.AppendIRI(mustParse(testAudienceIRI2))
items.AppendIRI(mustParse(testNoteId1))
items.AppendIRI(mustParse(testNoteId2))
col1.SetActivityStreamsItems(items)
expectCol1 := streams.NewActivityStreamsCollection()
items1 := streams.NewActivityStreamsItemsProperty()
items1.AppendIRI(mustParse(testAudienceIRI))
items1.AppendIRI(mustParse(testAudienceIRI2))
expectCol1.SetActivityStreamsItems(items1)
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI)).Return(
col1, nil)
mockDB.EXPECT().Update(ctx, expectCol1).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI))
r := newRemoveFn()
r.GetActivityStreamsObject().AppendActivityStreamsNote(testFederatedNote2)
err := w.remove(ctx, r)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("RemovesAllObjectIdsFromOrderedCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
col1 := streams.NewActivityStreamsOrderedCollection()
items := streams.NewActivityStreamsOrderedItemsProperty()
items.AppendIRI(mustParse(testAudienceIRI))
items.AppendIRI(mustParse(testAudienceIRI2))
items.AppendIRI(mustParse(testNoteId1))
items.AppendIRI(mustParse(testNoteId2))
col1.SetActivityStreamsOrderedItems(items)
expectCol1 := streams.NewActivityStreamsOrderedCollection()
items1 := streams.NewActivityStreamsOrderedItemsProperty()
items1.AppendIRI(mustParse(testAudienceIRI))
items1.AppendIRI(mustParse(testAudienceIRI2))
expectCol1.SetActivityStreamsOrderedItems(items1)
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI)).Return(
col1, nil)
mockDB.EXPECT().Update(ctx, expectCol1).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI))
r := newRemoveFn()
r.GetActivityStreamsObject().AppendActivityStreamsNote(testFederatedNote2)
err := w.remove(ctx, r)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("RemovesAllObjectIdsFromEachTarget", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
col1 := streams.NewActivityStreamsCollection()
items := streams.NewActivityStreamsItemsProperty()
items.AppendIRI(mustParse(testFederatedActorIRI3))
items.AppendIRI(mustParse(testFederatedActorIRI4))
items.AppendIRI(mustParse(testNoteId1))
col1.SetActivityStreamsItems(items)
expectCol1 := streams.NewActivityStreamsCollection()
items1 := streams.NewActivityStreamsItemsProperty()
items1.AppendIRI(mustParse(testFederatedActorIRI3))
items1.AppendIRI(mustParse(testFederatedActorIRI4))
expectCol1.SetActivityStreamsItems(items1)
col2 := streams.NewActivityStreamsCollection()
items0 := streams.NewActivityStreamsItemsProperty()
items0.AppendIRI(mustParse(testFederatedActorIRI))
items0.AppendIRI(mustParse(testNoteId1))
items0.AppendIRI(mustParse(testFederatedActorIRI2))
col2.SetActivityStreamsItems(items0)
expectCol2 := streams.NewActivityStreamsCollection()
items2 := streams.NewActivityStreamsItemsProperty()
items2.AppendIRI(mustParse(testFederatedActorIRI))
items2.AppendIRI(mustParse(testFederatedActorIRI2))
expectCol2.SetActivityStreamsItems(items2)
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI)).Return(
col1, nil)
mockDB.EXPECT().Update(ctx, expectCol1).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI2))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI2)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI2)).Return(
col2, nil)
mockDB.EXPECT().Update(ctx, expectCol2).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI2))
r := newRemoveFn()
r.GetActivityStreamsTarget().AppendIRI(mustParse(testAudienceIRI2))
err := w.remove(ctx, r)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("ReturnsErrorIfTargetIsNotCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
notCol := streams.NewActivityStreamsNote()
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI)).Return(
notCol, nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI))
r := newRemoveFn()
err := w.remove(ctx, r)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
col1 := streams.NewActivityStreamsCollection()
mockDB.EXPECT().Lock(ctx, mustParse(testAudienceIRI))
mockDB.EXPECT().Owns(ctx, mustParse(testAudienceIRI)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testAudienceIRI)).Return(
col1, nil)
mockDB.EXPECT().Update(ctx, gomock.Any()).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testAudienceIRI))
var gotc context.Context
var got vocab.ActivityStreamsRemove
w.Remove = func(ctx context.Context, v vocab.ActivityStreamsRemove) error {
gotc = ctx
got = v
return nil
}
r := newRemoveFn()
err := w.remove(ctx, r)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, r, got)
})
}
func TestFederatedLike(t *testing.T) {
newLikeFn := func() vocab.ActivityStreamsLike {
l := streams.NewActivityStreamsLike()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testFederatedActivityIRI))
l.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
l.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendActivityStreamsNote(testFederatedNote)
l.SetActivityStreamsObject(op)
return l
}
ctx := context.Background()
setupFn := func(ctl *gomock.Controller) (w FederatingWrappedCallbacks, mockDB *MockDatabase) {
mockDB = NewMockDatabase(ctl)
w.db = mockDB
return
}
t.Run("ErrorIfNoObject", func(t *testing.T) {
l := newLikeFn()
l.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.like(ctx, l)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfObjectLengthZero", func(t *testing.T) {
l := newLikeFn()
l.GetActivityStreamsObject().Remove(0)
var w FederatingWrappedCallbacks
err := w.like(ctx, l)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("SkipsUnownedObjects", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Owns(ctx, mustParse(testNoteId1)).Return(false, nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
l := newLikeFn()
err := w.like(ctx, l)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("AddsToNewLikesCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
note := streams.NewActivityStreamsNote()
expectNote := streams.NewActivityStreamsNote()
expectLikes := streams.NewActivityStreamsLikesProperty()
expectCol := streams.NewActivityStreamsCollection()
expectItems := streams.NewActivityStreamsItemsProperty()
expectItems.AppendIRI(mustParse(testFederatedActivityIRI))
expectCol.SetActivityStreamsItems(expectItems)
expectLikes.SetActivityStreamsCollection(expectCol)
expectNote.SetActivityStreamsLikes(expectLikes)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Owns(ctx, mustParse(testNoteId1)).Return(true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(
note, nil)
mockDB.EXPECT().Update(ctx, expectNote).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
l := newLikeFn()
err := w.like(ctx, l)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("AddsToExistingLikesCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
note := streams.NewActivityStreamsNote()
likes := streams.NewActivityStreamsLikesProperty()
col := streams.NewActivityStreamsCollection()
items := streams.NewActivityStreamsItemsProperty()
items.AppendIRI(mustParse(testFederatedActivityIRI2))
col.SetActivityStreamsItems(items)
likes.SetActivityStreamsCollection(col)
note.SetActivityStreamsLikes(likes)
expectNote := streams.NewActivityStreamsNote()
expectLikes := streams.NewActivityStreamsLikesProperty()
expectCol := streams.NewActivityStreamsCollection()
expectItems := streams.NewActivityStreamsItemsProperty()
expectItems.AppendIRI(mustParse(testFederatedActivityIRI))
expectItems.AppendIRI(mustParse(testFederatedActivityIRI2))
expectCol.SetActivityStreamsItems(expectItems)
expectLikes.SetActivityStreamsCollection(expectCol)
expectNote.SetActivityStreamsLikes(expectLikes)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Owns(ctx, mustParse(testNoteId1)).Return(true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(
note, nil)
mockDB.EXPECT().Update(ctx, expectNote).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
l := newLikeFn()
err := w.like(ctx, l)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("AddsToExistingLikesOrderedCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
note := streams.NewActivityStreamsNote()
likes := streams.NewActivityStreamsLikesProperty()
col := streams.NewActivityStreamsOrderedCollection()
items := streams.NewActivityStreamsOrderedItemsProperty()
items.AppendIRI(mustParse(testFederatedActivityIRI2))
col.SetActivityStreamsOrderedItems(items)
likes.SetActivityStreamsOrderedCollection(col)
note.SetActivityStreamsLikes(likes)
expectNote := streams.NewActivityStreamsNote()
expectLikes := streams.NewActivityStreamsLikesProperty()
expectCol := streams.NewActivityStreamsOrderedCollection()
expectItems := streams.NewActivityStreamsOrderedItemsProperty()
expectItems.AppendIRI(mustParse(testFederatedActivityIRI))
expectItems.AppendIRI(mustParse(testFederatedActivityIRI2))
expectCol.SetActivityStreamsOrderedItems(expectItems)
expectLikes.SetActivityStreamsOrderedCollection(expectCol)
expectNote.SetActivityStreamsLikes(expectLikes)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Owns(ctx, mustParse(testNoteId1)).Return(true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(
note, nil)
mockDB.EXPECT().Update(ctx, expectNote).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
l := newLikeFn()
err := w.like(ctx, l)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
note := streams.NewActivityStreamsNote()
expectNote := streams.NewActivityStreamsNote()
expectLikes := streams.NewActivityStreamsLikesProperty()
expectCol := streams.NewActivityStreamsCollection()
expectItems := streams.NewActivityStreamsItemsProperty()
expectItems.AppendIRI(mustParse(testFederatedActivityIRI))
expectCol.SetActivityStreamsItems(expectItems)
expectLikes.SetActivityStreamsCollection(expectCol)
expectNote.SetActivityStreamsLikes(expectLikes)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Owns(ctx, mustParse(testNoteId1)).Return(true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(
note, nil)
mockDB.EXPECT().Update(ctx, expectNote).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
var gotc context.Context
var got vocab.ActivityStreamsLike
w.Like = func(ctx context.Context, v vocab.ActivityStreamsLike) error {
gotc = ctx
got = v
return nil
}
l := newLikeFn()
err := w.like(ctx, l)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, l, got)
})
}
func TestFederatedAnnounce(t *testing.T) {
newAnnounceFn := func() vocab.ActivityStreamsAnnounce {
a := streams.NewActivityStreamsAnnounce()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testFederatedActivityIRI))
a.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
a.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendActivityStreamsNote(testFederatedNote)
a.SetActivityStreamsObject(op)
return a
}
ctx := context.Background()
setupFn := func(ctl *gomock.Controller) (w FederatingWrappedCallbacks, mockDB *MockDatabase) {
mockDB = NewMockDatabase(ctl)
w.db = mockDB
return
}
t.Run("DoesNothingWhenNoObjects", func(t *testing.T) {
a := newAnnounceFn()
a.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.announce(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("SkipsUnownedObjects", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Owns(ctx, mustParse(testNoteId1)).Return(
false, nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
a := newAnnounceFn()
err := w.announce(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("AddsToNewSharesCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
note := streams.NewActivityStreamsNote()
expectNote := streams.NewActivityStreamsNote()
expectShares := streams.NewActivityStreamsSharesProperty()
expectCol := streams.NewActivityStreamsCollection()
expectItems := streams.NewActivityStreamsItemsProperty()
expectItems.AppendIRI(mustParse(testFederatedActivityIRI))
expectCol.SetActivityStreamsItems(expectItems)
expectShares.SetActivityStreamsCollection(expectCol)
expectNote.SetActivityStreamsShares(expectShares)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Owns(ctx, mustParse(testNoteId1)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(
note, nil)
mockDB.EXPECT().Update(ctx, expectNote).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
a := newAnnounceFn()
err := w.announce(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("AddsToExistingSharesCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
note := streams.NewActivityStreamsNote()
shares := streams.NewActivityStreamsSharesProperty()
col := streams.NewActivityStreamsCollection()
items := streams.NewActivityStreamsItemsProperty()
items.AppendIRI(mustParse(testFederatedActivityIRI2))
col.SetActivityStreamsItems(items)
shares.SetActivityStreamsCollection(col)
note.SetActivityStreamsShares(shares)
expectNote := streams.NewActivityStreamsNote()
expectShares := streams.NewActivityStreamsSharesProperty()
expectCol := streams.NewActivityStreamsCollection()
expectItems := streams.NewActivityStreamsItemsProperty()
expectItems.AppendIRI(mustParse(testFederatedActivityIRI))
expectItems.AppendIRI(mustParse(testFederatedActivityIRI2))
expectCol.SetActivityStreamsItems(expectItems)
expectShares.SetActivityStreamsCollection(expectCol)
expectNote.SetActivityStreamsShares(expectShares)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Owns(ctx, mustParse(testNoteId1)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(
note, nil)
mockDB.EXPECT().Update(ctx, expectNote).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
a := newAnnounceFn()
err := w.announce(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("AddsToExistingSharesOrderedCollection", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
note := streams.NewActivityStreamsNote()
shares := streams.NewActivityStreamsSharesProperty()
col := streams.NewActivityStreamsOrderedCollection()
items := streams.NewActivityStreamsOrderedItemsProperty()
items.AppendIRI(mustParse(testFederatedActivityIRI2))
col.SetActivityStreamsOrderedItems(items)
shares.SetActivityStreamsOrderedCollection(col)
note.SetActivityStreamsShares(shares)
expectNote := streams.NewActivityStreamsNote()
expectShares := streams.NewActivityStreamsSharesProperty()
expectCol := streams.NewActivityStreamsOrderedCollection()
expectItems := streams.NewActivityStreamsOrderedItemsProperty()
expectItems.AppendIRI(mustParse(testFederatedActivityIRI))
expectItems.AppendIRI(mustParse(testFederatedActivityIRI2))
expectCol.SetActivityStreamsOrderedItems(expectItems)
expectShares.SetActivityStreamsOrderedCollection(expectCol)
expectNote.SetActivityStreamsShares(expectShares)
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Owns(ctx, mustParse(testNoteId1)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(
note, nil)
mockDB.EXPECT().Update(ctx, expectNote).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
a := newAnnounceFn()
err := w.announce(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockDB := setupFn(ctl)
note := streams.NewActivityStreamsNote()
mockDB.EXPECT().Lock(ctx, mustParse(testNoteId1))
mockDB.EXPECT().Owns(ctx, mustParse(testNoteId1)).Return(
true, nil)
mockDB.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(
note, nil)
mockDB.EXPECT().Update(ctx, gomock.Any()).Return(nil)
mockDB.EXPECT().Unlock(ctx, mustParse(testNoteId1))
var gotc context.Context
var got vocab.ActivityStreamsAnnounce
w.Announce = func(ctx context.Context, v vocab.ActivityStreamsAnnounce) error {
gotc = ctx
got = v
return nil
}
a := newAnnounceFn()
err := w.announce(ctx, a)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, a, got)
})
}
func TestFederatedUndo(t *testing.T) {
newUndoFn := func() vocab.ActivityStreamsUndo {
u := streams.NewActivityStreamsUndo()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testFederatedActivityIRI2))
u.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
u.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendActivityStreamsListen(testListen)
u.SetActivityStreamsObject(op)
return u
}
ctx := context.Background()
setupFn := func(ctl *gomock.Controller) (w FederatingWrappedCallbacks, mockTp *MockTransport) {
mockTp = NewMockTransport(ctl)
w.inboxIRI = mustParse(testMyInboxIRI)
w.newTransport = func(c context.Context, a *url.URL, s string) (Transport, error) {
return mockTp, nil
}
return
}
t.Run("ErrorIfNoObject", func(t *testing.T) {
u := newUndoFn()
u.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.undo(ctx, u)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfObjectLengthZero", func(t *testing.T) {
u := newUndoFn()
u.GetActivityStreamsObject().Remove(0)
var w FederatingWrappedCallbacks
err := w.undo(ctx, u)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfActorMismatch", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockTp := setupFn(ctl)
mockTp.EXPECT().Dereference(ctx, mustParse(testFederatedActivityIRI)).Return(
mustSerializeToBytes(testListen), nil)
u := newUndoFn()
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI2))
u.SetActivityStreamsActor(actor)
err := w.undo(ctx, u)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfActorMismatchWhenDereferencingIRI", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockTp := setupFn(ctl)
mockTp.EXPECT().Dereference(ctx, mustParse(testFederatedActivityIRI)).Return(
mustSerializeToBytes(testFollow), nil)
u := newUndoFn()
op := streams.NewActivityStreamsObjectProperty()
op.AppendIRI(mustParse(testFederatedActivityIRI))
u.SetActivityStreamsObject(op)
err := w.undo(ctx, u)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("DereferencesWhenUndoValue", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockTp := setupFn(ctl)
mockTp.EXPECT().Dereference(ctx, mustParse(testFederatedActivityIRI)).Return(
mustSerializeToBytes(testListen), nil)
u := newUndoFn()
err := w.undo(ctx, u)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("DereferencesWhenUndoIRI", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockTp := setupFn(ctl)
mockTp.EXPECT().Dereference(ctx, mustParse(testFederatedActivityIRI)).Return(
mustSerializeToBytes(testListen), nil)
u := newUndoFn()
op := streams.NewActivityStreamsObjectProperty()
op.AppendIRI(mustParse(testFederatedActivityIRI))
u.SetActivityStreamsObject(op)
err := w.undo(ctx, u)
if err != nil {
t.Fatalf("got error %s", err)
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
w, mockTp := setupFn(ctl)
mockTp.EXPECT().Dereference(ctx, mustParse(testFederatedActivityIRI)).Return(
mustSerializeToBytes(testListen), nil)
var gotc context.Context
var got vocab.ActivityStreamsUndo
w.Undo = func(ctx context.Context, v vocab.ActivityStreamsUndo) error {
gotc = ctx
got = v
return nil
}
u := newUndoFn()
err := w.undo(ctx, u)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, u, got)
})
}
func TestFederatedBlock(t *testing.T) {
newBlockFn := func() vocab.ActivityStreamsBlock {
b := streams.NewActivityStreamsBlock()
id := streams.NewJSONLDIdProperty()
id.Set(mustParse(testFederatedActivityIRI))
b.SetJSONLDId(id)
actor := streams.NewActivityStreamsActorProperty()
actor.AppendIRI(mustParse(testFederatedActorIRI))
b.SetActivityStreamsActor(actor)
op := streams.NewActivityStreamsObjectProperty()
op.AppendIRI(mustParse(testFederatedActorIRI2))
b.SetActivityStreamsObject(op)
return b
}
ctx := context.Background()
t.Run("ErrorIfNoObject", func(t *testing.T) {
b := newBlockFn()
b.SetActivityStreamsObject(nil)
var w FederatingWrappedCallbacks
err := w.block(ctx, b)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("ErrorIfObjectLengthZero", func(t *testing.T) {
b := newBlockFn()
b.GetActivityStreamsObject().Remove(0)
var w FederatingWrappedCallbacks
err := w.block(ctx, b)
if err == nil {
t.Fatalf("expected error, got none")
}
})
t.Run("CallsCustomCallback", func(t *testing.T) {
var w FederatingWrappedCallbacks
var gotc context.Context
var got vocab.ActivityStreamsBlock
w.Block = func(ctx context.Context, v vocab.ActivityStreamsBlock) error {
gotc = ctx
got = v
return nil
}
b := newBlockFn()
err := w.block(ctx, b)
if err != nil {
t.Fatalf("got error %s", err)
}
assertEqual(t, ctx, gotc)
assertEqual(t, b, got)
})
}