1835 lines
60 KiB
Go
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)
|
|
})
|
|
}
|