Add extra integration tests.

These generally include improving the handling of OrderedCollections and
IRIs. Note that improvement to setting IRI'd fetches from the
implementing application were made.

Improve the handing of AutoAccept and AutoReject follows. If there are
no owned objects in the Activity, we prevent sending the automatic reply
in case the implemented application is not checking for ownership of the
object of the original Follow activity.
このコミットが含まれているのは:
Cory Slep 2018-05-12 23:03:20 +02:00
コミット 4bad90902e
4個のファイルの変更513行の追加71行の削除

ファイルの表示

@ -695,27 +695,27 @@ func (f *federator) handleClientLike(ctx context.Context, deliverable *bool) fun
if s.LenObject() == 0 {
return ErrObjectRequired
}
getter := func(actor vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) error {
getter := func(actor vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) (bool, error) {
if actor.IsLikedAnyURI() {
pObj, err := f.App.Get(ctx, actor.GetLikedAnyURI())
if err != nil {
return err
return true, err
}
ok := false
if *lc, ok = pObj.(vocab.CollectionType); !ok {
if *loc, ok = pObj.(vocab.OrderedCollectionType); !ok {
return fmt.Errorf("actors liked collection not CollectionType nor OrderedCollectionType")
return true, fmt.Errorf("actors liked collection not CollectionType nor OrderedCollectionType")
}
}
return nil
return true, nil
} else if actor.IsLikedCollection() {
*lc = actor.GetLikedCollection()
return nil
return false, nil
} else if actor.IsLikedOrderedCollection() {
*loc = actor.GetLikedOrderedCollection()
return nil
return false, nil
}
return fmt.Errorf("cannot determine type of actor liked")
return false, fmt.Errorf("cannot determine type of actor liked")
}
if err := f.addAllObjectsToActorCollection(ctx, getter, s.Raw()); err != nil {
return err
@ -863,34 +863,44 @@ func (f *federator) handleFollow(c context.Context) func(s *streams.Follow) erro
activity.AddToIRI(raw.GetActorIRI(i))
}
}
if err := f.deliver(activity); err != nil {
return err
}
ownsAny := false
if todo == AutomaticAccept {
getter := func(object vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) error {
getter := func(object vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) (bool, error) {
if object.IsFollowersAnyURI() {
pObj, err := f.App.Get(c, object.GetFollowersAnyURI())
if err != nil {
return err
return true, err
}
ok := false
if *lc, ok = pObj.(vocab.CollectionType); !ok {
if *loc, ok = pObj.(vocab.OrderedCollectionType); !ok {
return fmt.Errorf("object followers collection not CollectionType nor OrderedCollectionType")
return true, fmt.Errorf("object followers collection not CollectionType nor OrderedCollectionType")
}
}
return nil
return true, nil
} else if object.IsFollowersCollection() {
*lc = object.GetFollowersCollection()
return nil
return false, nil
} else if object.IsFollowersOrderedCollection() {
*loc = object.GetFollowersOrderedCollection()
return nil
return false, nil
}
return fmt.Errorf("cannot determine type of object followers")
return false, fmt.Errorf("cannot determine type of object followers")
}
// TODO: Deduplication detection.
if err := f.addAllActorsToObjectCollection(c, getter, raw); err != nil {
var err error
if ownsAny, err = f.addAllActorsToObjectCollection(c, getter, raw); err != nil {
return err
}
} else if todo == AutomaticReject {
var err error
ownsAny, err = f.ownsAnyObjects(c, raw)
if err != nil {
return err
}
}
if ownsAny {
if err := f.deliver(activity); err != nil {
return err
}
}
@ -912,27 +922,27 @@ func (f *federator) handleAccept(c context.Context) func(s *streams.Accept) erro
if !ok {
continue
}
getter := func(actor vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) error {
getter := func(actor vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) (bool, error) {
if actor.IsFollowingAnyURI() {
pObj, err := f.App.Get(c, actor.GetFollowingAnyURI())
if err != nil {
return err
return true, err
}
ok := false
if *lc, ok = pObj.(vocab.CollectionType); !ok {
if *loc, ok = pObj.(vocab.OrderedCollectionType); !ok {
return fmt.Errorf("actors following collection not CollectionType nor OrderedCollectionType")
return true, fmt.Errorf("actors following collection not CollectionType nor OrderedCollectionType")
}
}
return nil
return true, nil
} else if actor.IsFollowingCollection() {
*lc = actor.GetFollowingCollection()
return nil
return false, nil
} else if actor.IsFollowingOrderedCollection() {
*loc = actor.GetFollowingOrderedCollection()
return nil
return false, nil
}
return fmt.Errorf("cannot determine type of actor following")
return false, fmt.Errorf("cannot determine type of actor following")
}
// TODO: Deduplication detection.
if err := f.addAllObjectsToActorCollection(c, getter, follow); err != nil {
@ -1087,29 +1097,29 @@ func (f *federator) handleLike(c context.Context) func(s *streams.Like) error {
if s.LenObject() == 0 {
return ErrObjectRequired
}
getter := func(object vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) error {
getter := func(object vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) (bool, error) {
if object.IsLikesAnyURI() {
pObj, err := f.App.Get(c, object.GetLikesAnyURI())
if err != nil {
return err
return true, err
}
ok := false
if *lc, ok = pObj.(vocab.CollectionType); !ok {
if *loc, ok = pObj.(vocab.OrderedCollectionType); !ok {
return fmt.Errorf("object likes collection not CollectionType nor OrderedCollectionType")
return true, fmt.Errorf("object likes collection not CollectionType nor OrderedCollectionType")
}
}
return nil
return true, nil
} else if object.IsLikesCollection() {
*lc = object.GetLikesCollection()
return nil
return false, nil
} else if object.IsLikesOrderedCollection() {
*loc = object.GetLikesOrderedCollection()
return nil
return false, nil
}
return fmt.Errorf("cannot determine type of object likes")
return false, fmt.Errorf("cannot determine type of object likes")
}
if err := f.addAllActorsToObjectCollection(c, getter, s.Raw()); err != nil {
if _, err := f.addAllActorsToObjectCollection(c, getter, s.Raw()); err != nil {
return err
}
return f.ServerCallbacker.Like(c, s)

ファイルの表示

@ -17,20 +17,21 @@ import (
)
const (
iriString = "https://example.com/something"
noteURIString = "https://example.com/note/123"
updateURIString = "https://example.com/note/update/123"
noteActivityURIString = "https://example.com/activity/987"
testAgent = "test agent string"
testInboxURI = "https://example.com/sally/inbox"
testOutboxURI = "https://example.com/sally/outbox"
testNewIRIString = "https://example.com/test/new/iri"
sallyIRIString = "https://example.com/sally"
samIRIString = "https://example.com/sam"
samIRIInboxString = "https://example.com/sam/inbox"
samIRIFollowersString = "https://example.com/sam/followers"
sallyIRIInboxString = "https://example.com/sally/inbox"
noteName = "A Note"
iriString = "https://example.com/something"
noteURIString = "https://example.com/note/123"
updateURIString = "https://example.com/note/update/123"
noteActivityURIString = "https://example.com/activity/987"
testAgent = "test agent string"
testInboxURI = "https://example.com/sally/inbox"
testOutboxURI = "https://example.com/sally/outbox"
testNewIRIString = "https://example.com/test/new/iri"
sallyIRIString = "https://example.com/sally"
sallyFollowingIRIString = "https://example.com/sally/following"
samIRIString = "https://example.com/sam"
samIRIInboxString = "https://example.com/sam/inbox"
samIRIFollowersString = "https://example.com/sam/followers"
sallyIRIInboxString = "https://example.com/sally/inbox"
noteName = "A Note"
)
var (
@ -41,6 +42,7 @@ var (
testNewIRI *url.URL
sallyIRI *url.URL
sallyIRIInbox *url.URL
sallyFollowingIRI *url.URL
sallyActor *vocab.Person
sallyActorJSON []byte
samIRI *url.URL
@ -111,6 +113,10 @@ func init() {
if err != nil {
panic(err)
}
sallyFollowingIRI, err = url.Parse(sallyFollowingIRIString)
if err != nil {
panic(err)
}
samIRI, err = url.Parse(samIRIString)
if err != nil {
panic(err)
@ -1979,6 +1985,13 @@ func TestPostInbox_Follow_AutoReject(t *testing.T) {
fedCb.follow = func(c context.Context, s *streams.Follow) error {
return nil
}
gotOwns := 0
var ownsIRI url.URL
app.owns = func(c context.Context, id url.URL) bool {
gotOwns++
ownsIRI = id
return true
}
gotHttpDo := 0
var httpActorRequest *http.Request
var httpDeliveryRequest *http.Request
@ -2028,6 +2041,10 @@ func TestPostInbox_Follow_AutoReject(t *testing.T) {
t.Fatalf("expected %s, got %s", sallyIRIString, s)
} else if s := httpDeliveryRequest.URL.String(); s != sallyIRIInboxString {
t.Fatalf("expected %s, got %s", sallyIRIInboxString, s)
} else if gotOwns != 1 {
t.Fatalf("expected %d, got %d", 1, gotOwns)
} else if ownsIRI.String() != samIRIString {
t.Fatalf("expected %s, got %s", samIRIString, ownsIRI.String())
} else if gotDoDelivery != 1 {
t.Fatalf("expected %d, got %d", 1, gotDoDelivery)
} else if doDeliveryURL.String() != sallyIRIInboxString {
@ -2037,8 +2054,6 @@ func TestPostInbox_Follow_AutoReject(t *testing.T) {
}
}
// TODO: Test follower OrderedCollection & IRI.
// TODO: Test does not own one of the objects.
func TestPostInbox_Follow_AutoAccept(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
@ -2155,6 +2170,190 @@ func TestPostInbox_Follow_AutoAccept(t *testing.T) {
}
}
func TestPostInbox_Follow_AutoAcceptFollowersIsOrderedCollection(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
resp := httptest.NewRecorder()
req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testFollow))))
fedApp.onFollow = func(c context.Context, s *streams.Follow) FollowResponse {
return AutomaticAccept
}
fedCb.follow = func(c context.Context, s *streams.Follow) error {
return nil
}
gotHttpDo := 0
httpClient.do = func(req *http.Request) (*http.Response, error) {
gotHttpDo++
if gotHttpDo == 1 {
actorResp := &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBuffer(sallyActorJSON)),
}
return actorResp, nil
} else if gotHttpDo == 2 {
okResp := &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBuffer([]byte{})),
}
return okResp, nil
}
return nil, nil
}
d.do = func(b []byte, u url.URL, toDo func(b []byte, u url.URL) error) {
if err := toDo(b, u); err != nil {
t.Fatalf("Unexpected error in MockDeliverer.Do: %s", err)
}
}
app.owns = func(c context.Context, id url.URL) bool {
return true
}
app.get = func(c context.Context, id url.URL) (PubObject, error) {
samActor := &vocab.Person{}
samActor.SetInboxAnyURI(*samIRIInbox)
samActor.SetId(*samIRI)
samActor.SetFollowersOrderedCollection(&vocab.OrderedCollection{})
return samActor, nil
}
gotSet := 0
var setObject PubObject
app.set = func(c context.Context, o PubObject) error {
gotSet++
if gotSet == 1 {
setObject = o
}
return nil
}
handled, err := p.PostInbox(context.Background(), resp, req)
expectedFollowers := &vocab.OrderedCollection{}
expectedFollowers.AddOrderedItemsObject(sallyActor)
expectedActor := &vocab.Person{}
expectedActor.SetInboxAnyURI(*samIRIInbox)
expectedActor.SetId(*samIRI)
expectedActor.SetFollowersOrderedCollection(expectedFollowers)
if err != nil {
t.Fatal(err)
} else if !handled {
t.Fatalf("expected handled, got !handled")
} else if err := PubObjectEquals(setObject, expectedActor); err != nil {
t.Fatal(err)
}
}
func TestPostInbox_Follow_AutoAcceptFollowersIsIRI(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
resp := httptest.NewRecorder()
req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testFollow))))
fedApp.onFollow = func(c context.Context, s *streams.Follow) FollowResponse {
return AutomaticAccept
}
fedCb.follow = func(c context.Context, s *streams.Follow) error {
return nil
}
gotHttpDo := 0
httpClient.do = func(req *http.Request) (*http.Response, error) {
gotHttpDo++
if gotHttpDo == 1 {
actorResp := &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBuffer(sallyActorJSON)),
}
return actorResp, nil
} else if gotHttpDo == 2 {
okResp := &http.Response{
StatusCode: http.StatusOK,
Body: ioutil.NopCloser(bytes.NewBuffer([]byte{})),
}
return okResp, nil
}
return nil, nil
}
d.do = func(b []byte, u url.URL, toDo func(b []byte, u url.URL) error) {
if err := toDo(b, u); err != nil {
t.Fatalf("Unexpected error in MockDeliverer.Do: %s", err)
}
}
app.owns = func(c context.Context, id url.URL) bool {
return true
}
app.get = func(c context.Context, id url.URL) (PubObject, error) {
if id == *samIRI {
samActor := &vocab.Person{}
samActor.SetInboxAnyURI(*samIRIInbox)
samActor.SetId(*samIRI)
samActor.SetFollowersAnyURI(*testNewIRI)
return samActor, nil
} else if id == *testNewIRI {
return &vocab.Collection{}, nil
}
t.Fatalf("unexpected get(%s)", &id)
return nil, nil
}
gotSet := 0
var setObject PubObject
app.set = func(c context.Context, o PubObject) error {
gotSet++
if gotSet == 1 {
setObject = o
}
return nil
}
handled, err := p.PostInbox(context.Background(), resp, req)
expectedFollowers := &vocab.Collection{}
expectedFollowers.AddItemsObject(sallyActor)
if err != nil {
t.Fatal(err)
} else if !handled {
t.Fatalf("expected handled, got !handled")
} else if err := PubObjectEquals(setObject, expectedFollowers); err != nil {
t.Fatal(err)
}
}
func TestPostInbox_Follow_DoesNotAutoAcceptIfNotOwned(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
resp := httptest.NewRecorder()
req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testFollow))))
fedApp.onFollow = func(c context.Context, s *streams.Follow) FollowResponse {
return AutomaticAccept
}
fedCb.follow = func(c context.Context, s *streams.Follow) error {
return nil
}
app.owns = func(c context.Context, id url.URL) bool {
return false
}
handled, err := p.PostInbox(context.Background(), resp, req)
if err != nil {
t.Fatal(err)
} else if !handled {
t.Fatalf("expected handled, got !handled")
}
}
func TestPostInbox_Follow_DoesNotAutoRejectIfNotOwned(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
resp := httptest.NewRecorder()
req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testFollow))))
fedApp.onFollow = func(c context.Context, s *streams.Follow) FollowResponse {
return AutomaticReject
}
fedCb.follow = func(c context.Context, s *streams.Follow) error {
return nil
}
app.owns = func(c context.Context, id url.URL) bool {
return false
}
handled, err := p.PostInbox(context.Background(), resp, req)
if err != nil {
t.Fatal(err)
} else if !handled {
t.Fatalf("expected handled, got !handled")
}
}
func TestPostInbox_Follow_CallsCallback(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
@ -2198,7 +2397,6 @@ func TestPostInbox_Accept_DoesNothingIfNotAcceptingFollow(t *testing.T) {
}
}
// TODO: Test follower OrderedCollection & IRI.
func TestPostInbox_Accept_AcceptFollowAddsToFollowersIfOwned(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
@ -2260,6 +2458,94 @@ func TestPostInbox_Accept_AcceptFollowAddsToFollowersIfOwned(t *testing.T) {
}
}
func TestPostInbox_Accept_AcceptFollowAddsToFollowersOrderedCollection(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
resp := httptest.NewRecorder()
req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testAcceptFollow))))
app.owns = func(c context.Context, id url.URL) bool {
return true
}
app.get = func(c context.Context, id url.URL) (PubObject, error) {
sallyActor := &vocab.Person{}
sallyActor.SetInboxAnyURI(*sallyIRIInbox)
sallyActor.SetId(*sallyIRI)
sallyActor.SetFollowingOrderedCollection(&vocab.OrderedCollection{})
return sallyActor, nil
}
gotSet := 0
var setObject PubObject
app.set = func(c context.Context, o PubObject) error {
gotSet++
if gotSet == 1 {
setObject = o
}
return nil
}
fedCb.accept = func(c context.Context, s *streams.Accept) error {
return nil
}
expectedFollowing := &vocab.OrderedCollection{}
expectedFollowing.AddOrderedItemsObject(samActor)
expectedActor := &vocab.Person{}
expectedActor.SetInboxAnyURI(*sallyIRIInbox)
expectedActor.SetId(*sallyIRI)
expectedActor.SetFollowingOrderedCollection(expectedFollowing)
handled, err := p.PostInbox(context.Background(), resp, req)
if err != nil {
t.Fatal(err)
} else if !handled {
t.Fatalf("expected handled, got !handled")
} else if err := PubObjectEquals(setObject, expectedActor); err != nil {
t.Fatal(err)
}
}
func TestPostInbox_Accept_AcceptFollowAddsToFollowersIRI(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
resp := httptest.NewRecorder()
req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testAcceptFollow))))
app.owns = func(c context.Context, id url.URL) bool {
return true
}
app.get = func(c context.Context, id url.URL) (PubObject, error) {
if id == *sallyIRI {
sallyActor := &vocab.Person{}
sallyActor.SetInboxAnyURI(*sallyIRIInbox)
sallyActor.SetId(*sallyIRI)
sallyActor.SetFollowingAnyURI(*sallyFollowingIRI)
return sallyActor, nil
} else if id == *sallyFollowingIRI {
return &vocab.OrderedCollection{}, nil
}
t.Fatalf("Unexpected get(%s)", (&id).String())
return nil, nil
}
gotSet := 0
var setObject PubObject
app.set = func(c context.Context, o PubObject) error {
gotSet++
if gotSet == 1 {
setObject = o
}
return nil
}
fedCb.accept = func(c context.Context, s *streams.Accept) error {
return nil
}
expectedFollowing := &vocab.OrderedCollection{}
expectedFollowing.AddOrderedItemsObject(samActor)
handled, err := p.PostInbox(context.Background(), resp, req)
if err != nil {
t.Fatal(err)
} else if !handled {
t.Fatalf("expected handled, got !handled")
} else if err := PubObjectEquals(setObject, expectedFollowing); err != nil {
t.Fatal(err)
}
}
func TestPostInbox_Accept_DoesNothingIfNotOwned(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
@ -2717,7 +3003,6 @@ func TestPostInbox_Remove_CallsCallback(t *testing.T) {
}
}
// TODO: Test likes OrderedCollection & IRI.
func TestPostInbox_Like_AddsToLikeCollection(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
@ -2781,6 +3066,97 @@ func TestPostInbox_Like_AddsToLikeCollection(t *testing.T) {
}
}
func TestPostInbox_Like_AddsToLikeOrderedCollection(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
resp := httptest.NewRecorder()
req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testLikeNote))))
app.owns = func(c context.Context, id url.URL) bool {
return true
}
app.get = func(c context.Context, id url.URL) (PubObject, error) {
v := &vocab.Note{}
v.SetId(*noteIRI)
v.AddNameString(noteName)
v.AddContentString("This is a simple note")
v.SetLikesOrderedCollection(&vocab.OrderedCollection{})
return v, nil
}
gotSet := 0
var gotSetObject PubObject
app.set = func(c context.Context, target PubObject) error {
gotSet++
if gotSet == 1 {
gotSetObject = target
}
return nil
}
fedCb.like = func(c context.Context, s *streams.Like) error {
return nil
}
handled, err := p.PostInbox(context.Background(), resp, req)
expected := &vocab.OrderedCollection{}
expected.AddOrderedItemsObject(sallyActor)
expectedNote := &vocab.Note{}
expectedNote.SetId(*noteIRI)
expectedNote.AddNameString(noteName)
expectedNote.AddContentString("This is a simple note")
expectedNote.SetLikesOrderedCollection(expected)
if err != nil {
t.Fatal(err)
} else if !handled {
t.Fatalf("expected handled, got !handled")
} else if err := PubObjectEquals(gotSetObject, expectedNote); err != nil {
t.Fatalf("unexpected callback object: %s", err)
}
}
func TestPostInbox_Like_AddsToLikeIRI(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
resp := httptest.NewRecorder()
req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testLikeNote))))
app.owns = func(c context.Context, id url.URL) bool {
return true
}
app.get = func(c context.Context, id url.URL) (PubObject, error) {
if id == *noteIRI {
v := &vocab.Note{}
v.SetId(*noteIRI)
v.AddNameString(noteName)
v.AddContentString("This is a simple note")
v.SetLikesAnyURI(*testNewIRI)
return v, nil
} else if id == *testNewIRI {
return &vocab.OrderedCollection{}, nil
}
t.Fatalf("unexpected get(%s)", &id)
return nil, nil
}
gotSet := 0
var gotSetObject PubObject
app.set = func(c context.Context, target PubObject) error {
gotSet++
if gotSet == 1 {
gotSetObject = target
}
return nil
}
fedCb.like = func(c context.Context, s *streams.Like) error {
return nil
}
handled, err := p.PostInbox(context.Background(), resp, req)
expected := &vocab.OrderedCollection{}
expected.AddOrderedItemsObject(sallyActor)
if err != nil {
t.Fatal(err)
} else if !handled {
t.Fatalf("expected handled, got !handled")
} else if err := PubObjectEquals(gotSetObject, expected); err != nil {
t.Fatalf("unexpected callback object: %s", err)
}
}
func TestPostInbox_Like_CallsCallback(t *testing.T) {
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
@ -4718,12 +5094,26 @@ func TestPostOutbox_Block_IsNotDelivered(t *testing.T) {
}
}
func TestPostOutbox_DoesNotDeliverNondeliverable(t *testing.T) {
// TODO: Implement
}
func TestPostOutbox_SetsLocationHeader(t *testing.T) {
// TODO: Implement
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
PreparePostOutboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
resp := httptest.NewRecorder()
req := ActivityPubRequest(httptest.NewRequest("POST", testOutboxURI, bytes.NewBuffer(MustSerialize(testCreateNote))))
socialCb.create = func(c context.Context, s *streams.Create) error {
return nil
}
handled, err := p.PostOutbox(context.Background(), resp, req)
if err != nil {
t.Fatal(err)
} else if !handled {
t.Fatalf("expected handled, got !handled")
} else if loc, ok := resp.HeaderMap["Location"]; !ok {
t.Fatalf("expected Location header, got none")
} else if len(loc) != 1 {
t.Fatalf("expected Location header to have length 1, got %d", len(loc))
} else if loc[0] != testNewIRIString {
t.Fatalf("expected %s, got %s", testNewIRIString, loc[0])
}
}
func TestGetOutbox_RejectNonActivityPub(t *testing.T) {
@ -4739,7 +5129,6 @@ func TestGetOutbox_RejectNonActivityPub(t *testing.T) {
} else if handled {
t.Fatalf("expected !handled, got handled")
}
}
func TestGetOutbox_SetsContentTypeHeader(t *testing.T) {

ファイルの表示

@ -88,8 +88,9 @@ type FederateApp interface {
// the given target collection.
CanRemove(c context.Context, obj vocab.ObjectType, target vocab.ObjectType) bool
// OnFollow determines whether to take any automatic reactions in
// response to this follow. Note that this method must check ownership
// to automatically Accept the Follow.
// response to this follow. Note that if this application does not own
// an object on the activity, then the 'AutomaticAccept' and
// 'AutomaticReject' results will behave as if they were 'DoNothing'.
OnFollow(c context.Context, s *streams.Follow) FollowResponse
// Unblocked should return an error if the provided actor ids are not
// able to interact with this particular end user due to being blocked

ファイルの表示

@ -1187,7 +1187,9 @@ func toTombstone(obj vocab.ObjectType, id url.URL, now time.Time) vocab.Tombston
return tomb
}
func (f *federator) addAllObjectsToActorCollection(ctx context.Context, getter func(actor vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) error, c vocab.ActivityType) error {
type getActorCollectionFn func(actor vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) (isIRI bool, e error)
func (f *federator) addAllObjectsToActorCollection(ctx context.Context, getter getActorCollectionFn, c vocab.ActivityType) error {
for i := 0; i < c.ActorLen(); i++ {
var iri url.URL
if c.IsActorObject(i) {
@ -1221,7 +1223,8 @@ func (f *federator) addAllObjectsToActorCollection(ctx context.Context, getter f
}
var lc vocab.CollectionType
var loc vocab.OrderedCollectionType
if err := getter(actor, &lc, &loc); err != nil {
isIRI := false
if isIRI, err = getter(actor, &lc, &loc); err != nil {
return err
}
for i := 0; i < c.ObjectLen(); i++ {
@ -1239,20 +1242,32 @@ func (f *federator) addAllObjectsToActorCollection(ctx context.Context, getter f
}
}
}
if err := f.App.Set(ctx, actor); err != nil {
if isIRI {
if lc != nil {
err = f.App.Set(ctx, lc)
} else if loc != nil {
err = f.App.Set(ctx, loc)
}
if err != nil {
return err
}
} else if err := f.App.Set(ctx, actor); err != nil {
return err
}
}
return nil
}
func (f *federator) addAllActorsToObjectCollection(ctx context.Context, getter func(object vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) error, c vocab.ActivityType) error {
type getObjectCollectionFn func(object vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) (isIRI bool, e error)
func (f *federator) addAllActorsToObjectCollection(ctx context.Context, getter getObjectCollectionFn, c vocab.ActivityType) (bool, error) {
ownsAny := false
for i := 0; i < c.ObjectLen(); i++ {
var iri url.URL
if c.IsObject(i) {
obj := c.GetObject(i)
if !obj.HasId() {
return fmt.Errorf("object does not have id")
return ownsAny, fmt.Errorf("object does not have id")
}
iri = obj.GetId()
} else if c.IsObjectIRI(i) {
@ -1261,21 +1276,23 @@ func (f *federator) addAllActorsToObjectCollection(ctx context.Context, getter f
if !f.App.Owns(ctx, iri) {
continue
}
ownsAny = true
var object vocab.ObjectType
pObj, err := f.App.Get(ctx, iri)
if err != nil {
return err
return ownsAny, err
}
ok := false
object, ok = pObj.(vocab.ObjectType)
if !ok {
// TODO: Handle links, too
return fmt.Errorf("object is not vocab.ObjectType")
return ownsAny, fmt.Errorf("object is not vocab.ObjectType")
}
var lc vocab.CollectionType
var loc vocab.OrderedCollectionType
if err := getter(object, &lc, &loc); err != nil {
return err
isIRI := false
if isIRI, err = getter(object, &lc, &loc); err != nil {
return ownsAny, err
}
for i := 0; i < c.ActorLen(); i++ {
if c.IsActorIRI(i) {
@ -1298,11 +1315,36 @@ func (f *federator) addAllActorsToObjectCollection(ctx context.Context, getter f
}
}
}
if err := f.App.Set(ctx, object); err != nil {
return err
if isIRI {
if lc != nil {
err = f.App.Set(ctx, lc)
} else if loc != nil {
err = f.App.Set(ctx, loc)
}
if err != nil {
return ownsAny, err
}
} else if err := f.App.Set(ctx, object); err != nil {
return ownsAny, err
}
}
return nil
return ownsAny, nil
}
func (f *federator) ownsAnyObjects(c context.Context, a vocab.ActivityType) (bool, error) {
var iris []url.URL
for i := 0; i < a.ObjectLen(); i++ {
if a.IsObject(i) {
obj := a.GetObject(i)
if !obj.HasId() {
return false, fmt.Errorf("object missing id")
}
iris = append(iris, obj.GetId())
} else if a.IsObjectIRI(i) {
iris = append(iris, a.GetObjectIRI(i))
}
}
return f.ownsAnyIRIs(c, iris), nil
}
func (f *federator) addToOutbox(c context.Context, r *http.Request, m map[string]interface{}) error {