parent
dc16296d74
commit
52bc5fb9a5
|
@ -158,6 +158,7 @@ func (b *baseActor) PostInbox(c context.Context, w http.ResponseWriter, r *http.
|
|||
if err != nil {
|
||||
return true, err
|
||||
} else if shouldReturn {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return true, nil
|
||||
}
|
||||
// Begin processing the request, but have not yet applied
|
||||
|
@ -192,6 +193,7 @@ func (b *baseActor) PostInbox(c context.Context, w http.ResponseWriter, r *http.
|
|||
if err != nil {
|
||||
return true, err
|
||||
} else if shouldReturn {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return true, nil
|
||||
}
|
||||
// Post the activity to the actor's inbox and trigger side effects for
|
||||
|
@ -234,6 +236,7 @@ func (b *baseActor) GetInbox(c context.Context, w http.ResponseWriter, r *http.R
|
|||
if err != nil {
|
||||
return true, err
|
||||
} else if shouldReturn {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return true, nil
|
||||
}
|
||||
// Everything is good to begin processing the request.
|
||||
|
@ -287,6 +290,7 @@ func (b *baseActor) PostOutbox(c context.Context, w http.ResponseWriter, r *http
|
|||
if err != nil {
|
||||
return true, err
|
||||
} else if shouldReturn {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return true, nil
|
||||
}
|
||||
// Everything is good to begin processing the request.
|
||||
|
@ -356,7 +360,7 @@ func (b *baseActor) PostOutbox(c context.Context, w http.ResponseWriter, r *http
|
|||
}
|
||||
}
|
||||
// Respond to the request with the new Activity's IRI location.
|
||||
w.Header().Set("Location", activity.GetActivityStreamsId().Get().String())
|
||||
w.Header().Set(locationHeader, activity.GetActivityStreamsId().Get().String())
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
return true, nil
|
||||
}
|
||||
|
@ -374,6 +378,7 @@ func (b *baseActor) GetOutbox(c context.Context, w http.ResponseWriter, r *http.
|
|||
if err != nil {
|
||||
return true, err
|
||||
} else if shouldReturn {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return true, nil
|
||||
}
|
||||
// Everything is good to begin processing the request.
|
||||
|
|
|
@ -0,0 +1,724 @@
|
|||
package pub
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/go-fed/activity/streams/vocab"
|
||||
"github.com/golang/mock/gomock"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestBaseActorSocialProtocol tests the Actor returned with NewCustomActor
|
||||
// and only having the SocialProtocol enabled.
|
||||
func TestBaseActorSocialProtocol(t *testing.T) {
|
||||
// Set up test case
|
||||
setupData()
|
||||
ctx := context.Background()
|
||||
setupFn := func(ctl *gomock.Controller) (delegate *MockDelegateActor, clock *MockClock, a Actor) {
|
||||
delegate = NewMockDelegateActor(ctl)
|
||||
clock = NewMockClock(ctl)
|
||||
a = NewCustomActor(
|
||||
delegate,
|
||||
/*enableSocialProtocol=*/ true,
|
||||
/*enableFederatedProtocol=*/ false,
|
||||
clock)
|
||||
return
|
||||
}
|
||||
// Run tests
|
||||
t.Run("PostInboxIgnoresNonActivityPubRequest", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toPostInboxRequest(testCreate)
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, false)
|
||||
assertEqual(t, len(resp.Result().Header), 0)
|
||||
})
|
||||
t.Run("PostInboxNotAllowed", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostInboxRequest(testCreate))
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusMethodNotAllowed)
|
||||
})
|
||||
t.Run("GetInboxIgnoresNonActivityPubRequest", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toGetInboxRequest()
|
||||
// Run the test
|
||||
handled, err := a.GetInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, false)
|
||||
assertEqual(t, len(resp.Result().Header), 0)
|
||||
})
|
||||
t.Run("GetInboxDeniesIfNotAuthenticated", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toGetInboxRequest())
|
||||
delegate.EXPECT().AuthenticateGetInbox(ctx, resp, req).Return(true, nil)
|
||||
// Run the test
|
||||
handled, err := a.GetInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusForbidden)
|
||||
})
|
||||
t.Run("GetInboxRespondsWithDataAndHeaders", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, clock, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toGetInboxRequest())
|
||||
delegate.EXPECT().AuthenticateGetInbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().GetInbox(ctx, req).Return(testOrderedCollectionUniqueElems, nil)
|
||||
clock.EXPECT().Now().Return(now())
|
||||
// Run the test
|
||||
handled, err := a.GetInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusOK)
|
||||
respV := resp.Result()
|
||||
assertEqual(t, respV.Header.Get(contentTypeHeader), "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")
|
||||
assertEqual(t, respV.Header.Get(dateHeader), nowDateHeader())
|
||||
assertNotEqual(t, len(respV.Header.Get(digestHeader)), 0)
|
||||
b, err := ioutil.ReadAll(respV.Body)
|
||||
assertEqual(t, err, nil)
|
||||
assertByteEqual(t, b, []byte(testOrderedCollectionUniqueElemsString))
|
||||
})
|
||||
t.Run("GetInboxDeduplicatesData", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, clock, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toGetInboxRequest())
|
||||
delegate.EXPECT().AuthenticateGetInbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().GetInbox(ctx, req).Return(testOrderedCollectionDupedElems, nil)
|
||||
clock.EXPECT().Now().Return(now())
|
||||
// Run the test
|
||||
_, err := a.GetInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
respV := resp.Result()
|
||||
b, err := ioutil.ReadAll(respV.Body)
|
||||
assertEqual(t, err, nil)
|
||||
assertByteEqual(t, b, []byte(testOrderedCollectionDedupedElemsString))
|
||||
})
|
||||
t.Run("PostOutboxIgnoresNonActivityPubRequest", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toPostOutboxRequest(testCreateNoId)
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, false)
|
||||
assertEqual(t, len(resp.Result().Header), 0)
|
||||
})
|
||||
t.Run("PostOutboxDeniesIfNotAuthenticated", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostOutboxRequest(testCreateNoId))
|
||||
delegate.EXPECT().AuthenticatePostOutbox(ctx, resp, req).Return(true, nil)
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusForbidden)
|
||||
})
|
||||
t.Run("PostOutboxBadRequestIfUnknownType", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostOutboxUnknownRequest())
|
||||
delegate.EXPECT().AuthenticatePostOutbox(ctx, resp, req).Return(false, nil)
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusBadRequest)
|
||||
})
|
||||
t.Run("PostOutboxRespondsWithDataAndHeaders", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostOutboxRequest(testCreateNoId))
|
||||
delegate.EXPECT().AuthenticatePostOutbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().AddNewIds(ctx, toDeserializedForm(testCreateNoId)).DoAndReturn(func(c context.Context, activity Activity) error {
|
||||
activity = withNewId(activity)
|
||||
return nil
|
||||
})
|
||||
delegate.EXPECT().PostOutbox(
|
||||
ctx,
|
||||
withNewId(toDeserializedForm(testCreateNoId)),
|
||||
mustParse(testMyOutboxIRI),
|
||||
mustSerialize(testCreateNoId),
|
||||
).Return(true, nil)
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusCreated)
|
||||
respV := resp.Result()
|
||||
assertEqual(t, respV.Header.Get(locationHeader), testNewActivityIRI)
|
||||
})
|
||||
t.Run("PostOutboxWrapsInCreate", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostOutboxRequest(testMyNote))
|
||||
delegate.EXPECT().AuthenticatePostOutbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().WrapInCreate(ctx, toDeserializedForm(testMyNote), mustParse(testMyOutboxIRI)).DoAndReturn(func(c context.Context, t vocab.Type, u *url.URL) (vocab.ActivityStreamsCreate, error) {
|
||||
return wrappedInCreate(t), nil
|
||||
})
|
||||
delegate.EXPECT().AddNewIds(ctx, wrappedInCreate(toDeserializedForm(testMyNote))).DoAndReturn(func(c context.Context, activity Activity) error {
|
||||
activity = withNewId(activity)
|
||||
return nil
|
||||
})
|
||||
delegate.EXPECT().PostOutbox(
|
||||
ctx,
|
||||
withNewId(wrappedInCreate(toDeserializedForm(testMyNote))),
|
||||
mustParse(testMyOutboxIRI),
|
||||
mustSerialize(toDeserializedForm(testMyNote)),
|
||||
).Return(true, nil)
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusCreated)
|
||||
})
|
||||
t.Run("PostOutboxBadRequestForErrObjectRequired", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostOutboxRequest(testCreateNoId))
|
||||
delegate.EXPECT().AuthenticatePostOutbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().AddNewIds(ctx, toDeserializedForm(testCreateNoId)).DoAndReturn(func(c context.Context, activity Activity) error {
|
||||
activity = withNewId(activity)
|
||||
return nil
|
||||
})
|
||||
delegate.EXPECT().PostOutbox(
|
||||
ctx,
|
||||
withNewId(toDeserializedForm(testCreateNoId)),
|
||||
mustParse(testMyOutboxIRI),
|
||||
mustSerialize(testCreateNoId),
|
||||
).Return(true, ErrObjectRequired)
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusBadRequest)
|
||||
})
|
||||
t.Run("PostOutboxBadRequestForErrTargetRequired", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostOutboxRequest(testCreateNoId))
|
||||
delegate.EXPECT().AuthenticatePostOutbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().AddNewIds(ctx, toDeserializedForm(testCreateNoId)).DoAndReturn(func(c context.Context, activity Activity) error {
|
||||
activity = withNewId(activity)
|
||||
return nil
|
||||
})
|
||||
delegate.EXPECT().PostOutbox(
|
||||
ctx,
|
||||
withNewId(toDeserializedForm(testCreateNoId)),
|
||||
mustParse(testMyOutboxIRI),
|
||||
mustSerialize(testCreateNoId),
|
||||
).Return(true, ErrTargetRequired)
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusBadRequest)
|
||||
})
|
||||
t.Run("GetOutboxIgnoresNonActivityPubRequest", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toGetOutboxRequest()
|
||||
// Run the test
|
||||
handled, err := a.GetOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, false)
|
||||
assertEqual(t, len(resp.Result().Header), 0)
|
||||
})
|
||||
t.Run("GetOutboxDeniesIfNotAuthenticated", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toGetOutboxRequest())
|
||||
delegate.EXPECT().AuthenticateGetOutbox(ctx, resp, req).Return(true, nil)
|
||||
// Run the test
|
||||
handled, err := a.GetOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusForbidden)
|
||||
})
|
||||
t.Run("GetOutboxRespondsWithDataAndHeaders", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, clock, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toGetOutboxRequest())
|
||||
delegate.EXPECT().AuthenticateGetOutbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().GetOutbox(ctx, req).Return(testOrderedCollectionUniqueElems, nil)
|
||||
clock.EXPECT().Now().Return(now())
|
||||
// Run the test
|
||||
handled, err := a.GetOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusOK)
|
||||
respV := resp.Result()
|
||||
assertEqual(t, respV.Header.Get(contentTypeHeader), "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")
|
||||
assertEqual(t, respV.Header.Get(dateHeader), nowDateHeader())
|
||||
assertNotEqual(t, len(respV.Header.Get(digestHeader)), 0)
|
||||
b, err := ioutil.ReadAll(respV.Body)
|
||||
assertEqual(t, err, nil)
|
||||
assertByteEqual(t, b, []byte(testOrderedCollectionUniqueElemsString))
|
||||
})
|
||||
}
|
||||
|
||||
// TestBaseActorFederatingProtocol tests the Actor returned with
|
||||
// NewCustomActor and only having the FederatingProtocol enabled.
|
||||
func TestBaseActorFederatingProtocol(t *testing.T) {
|
||||
// Set up test case
|
||||
setupData()
|
||||
ctx := context.Background()
|
||||
setupFn := func(ctl *gomock.Controller) (delegate *MockDelegateActor, clock *MockClock, a Actor) {
|
||||
delegate = NewMockDelegateActor(ctl)
|
||||
clock = NewMockClock(ctl)
|
||||
a = NewCustomActor(
|
||||
delegate,
|
||||
/*enableSocialProtocol=*/ false,
|
||||
/*enableFederatedProtocol=*/ true,
|
||||
clock)
|
||||
return
|
||||
}
|
||||
// Run tests
|
||||
t.Run("PostInboxIgnoresNonActivityPubRequest", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toPostInboxRequest(testCreate)
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, false)
|
||||
assertEqual(t, len(resp.Result().Header), 0)
|
||||
})
|
||||
t.Run("PostInboxDeniesIfNotAuthenticated", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostInboxRequest(testCreate))
|
||||
delegate.EXPECT().AuthenticatePostInbox(ctx, resp, req).Return(true, nil)
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusForbidden)
|
||||
})
|
||||
t.Run("PostInboxBadRequestIfUnknownType", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostInboxUnknownRequest())
|
||||
delegate.EXPECT().AuthenticatePostInbox(ctx, resp, req).Return(false, nil)
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusBadRequest)
|
||||
})
|
||||
t.Run("PostInboxBadRequestIfActivityHasNoId", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostOutboxRequest(testCreateNoId))
|
||||
delegate.EXPECT().AuthenticatePostInbox(ctx, resp, req).Return(false, nil)
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusBadRequest)
|
||||
})
|
||||
t.Run("PostInboxDeniesIfNotAuthorized", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostInboxRequest(testCreate))
|
||||
delegate.EXPECT().AuthenticatePostInbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().AuthorizePostInbox(ctx, resp, toDeserializedForm(testCreate)).Return(true, nil)
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusForbidden)
|
||||
})
|
||||
t.Run("PostInboxRespondsWithStatus", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostInboxRequest(testCreate))
|
||||
delegate.EXPECT().AuthenticatePostInbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().AuthorizePostInbox(ctx, resp, toDeserializedForm(testCreate)).Return(false, nil)
|
||||
delegate.EXPECT().PostInbox(ctx, mustParse(testMyInboxIRI), toDeserializedForm(testCreate)).Return(nil)
|
||||
delegate.EXPECT().InboxForwarding(ctx, mustParse(testMyInboxIRI), toDeserializedForm(testCreate)).Return(nil)
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusOK)
|
||||
})
|
||||
t.Run("PostInboxBadRequestForErrObjectRequired", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostInboxRequest(testCreate))
|
||||
delegate.EXPECT().AuthenticatePostInbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().AuthorizePostInbox(ctx, resp, toDeserializedForm(testCreate)).Return(false, nil)
|
||||
delegate.EXPECT().PostInbox(ctx, mustParse(testMyInboxIRI), toDeserializedForm(testCreate)).Return(ErrObjectRequired)
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusBadRequest)
|
||||
})
|
||||
t.Run("PostInboxBadRequestForErrTargetRequired", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostInboxRequest(testCreate))
|
||||
delegate.EXPECT().AuthenticatePostInbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().AuthorizePostInbox(ctx, resp, toDeserializedForm(testCreate)).Return(false, nil)
|
||||
delegate.EXPECT().PostInbox(ctx, mustParse(testMyInboxIRI), toDeserializedForm(testCreate)).Return(ErrTargetRequired)
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusBadRequest)
|
||||
})
|
||||
t.Run("GetInboxIgnoresNonActivityPubRequest", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toGetInboxRequest()
|
||||
// Run the test
|
||||
handled, err := a.GetInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, false)
|
||||
assertEqual(t, len(resp.Result().Header), 0)
|
||||
})
|
||||
t.Run("GetInboxDeniesIfNotAuthenticated", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toGetInboxRequest())
|
||||
delegate.EXPECT().AuthenticateGetInbox(ctx, resp, req).Return(true, nil)
|
||||
// Run the test
|
||||
handled, err := a.GetInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusForbidden)
|
||||
})
|
||||
t.Run("GetInboxRespondsWithDataAndHeaders", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, clock, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toGetInboxRequest())
|
||||
delegate.EXPECT().AuthenticateGetInbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().GetInbox(ctx, req).Return(testOrderedCollectionUniqueElems, nil)
|
||||
clock.EXPECT().Now().Return(now())
|
||||
// Run the test
|
||||
handled, err := a.GetInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusOK)
|
||||
respV := resp.Result()
|
||||
assertEqual(t, respV.Header.Get(contentTypeHeader), "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")
|
||||
assertEqual(t, respV.Header.Get(dateHeader), nowDateHeader())
|
||||
assertNotEqual(t, len(respV.Header.Get(digestHeader)), 0)
|
||||
b, err := ioutil.ReadAll(respV.Body)
|
||||
assertEqual(t, err, nil)
|
||||
assertByteEqual(t, b, []byte(testOrderedCollectionUniqueElemsString))
|
||||
})
|
||||
t.Run("GetInboxDeduplicatesData", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, clock, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toGetInboxRequest())
|
||||
delegate.EXPECT().AuthenticateGetInbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().GetInbox(ctx, req).Return(testOrderedCollectionDupedElems, nil)
|
||||
clock.EXPECT().Now().Return(now())
|
||||
// Run the test
|
||||
_, err := a.GetInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
respV := resp.Result()
|
||||
b, err := ioutil.ReadAll(respV.Body)
|
||||
assertEqual(t, err, nil)
|
||||
assertByteEqual(t, b, []byte(testOrderedCollectionDedupedElemsString))
|
||||
})
|
||||
t.Run("PostOutboxIgnoresNonActivityPubRequest", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toPostOutboxRequest(testCreateNoId)
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, false)
|
||||
assertEqual(t, len(resp.Result().Header), 0)
|
||||
})
|
||||
t.Run("PostOutboxNotAllowed", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostOutboxRequest(testCreateNoId))
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusMethodNotAllowed)
|
||||
})
|
||||
t.Run("GetOutboxIgnoresNonActivityPubRequest", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
_, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toGetOutboxRequest()
|
||||
// Run the test
|
||||
handled, err := a.GetOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, false)
|
||||
assertEqual(t, len(resp.Result().Header), 0)
|
||||
})
|
||||
t.Run("GetOutboxDeniesIfNotAuthenticated", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toGetOutboxRequest())
|
||||
delegate.EXPECT().AuthenticateGetOutbox(ctx, resp, req).Return(true, nil)
|
||||
// Run the test
|
||||
handled, err := a.GetOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusForbidden)
|
||||
})
|
||||
t.Run("GetOutboxRespondsWithDataAndHeaders", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, clock, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toGetOutboxRequest())
|
||||
delegate.EXPECT().AuthenticateGetOutbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().GetOutbox(ctx, req).Return(testOrderedCollectionUniqueElems, nil)
|
||||
clock.EXPECT().Now().Return(now())
|
||||
// Run the test
|
||||
handled, err := a.GetOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusOK)
|
||||
respV := resp.Result()
|
||||
assertEqual(t, respV.Header.Get(contentTypeHeader), "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")
|
||||
assertEqual(t, respV.Header.Get(dateHeader), nowDateHeader())
|
||||
assertNotEqual(t, len(respV.Header.Get(digestHeader)), 0)
|
||||
b, err := ioutil.ReadAll(respV.Body)
|
||||
assertEqual(t, err, nil)
|
||||
assertByteEqual(t, b, []byte(testOrderedCollectionUniqueElemsString))
|
||||
})
|
||||
}
|
||||
|
||||
// TestBaseActor tests the Actor returned with NewCustomActor and having both
|
||||
// the SocialProtocol and FederatingProtocol enabled.
|
||||
func TestBaseActor(t *testing.T) {
|
||||
// Set up test case
|
||||
setupData()
|
||||
ctx := context.Background()
|
||||
setupFn := func(ctl *gomock.Controller) (delegate *MockDelegateActor, clock *MockClock, a Actor) {
|
||||
delegate = NewMockDelegateActor(ctl)
|
||||
clock = NewMockClock(ctl)
|
||||
a = NewCustomActor(
|
||||
delegate,
|
||||
/*enableSocialProtocol=*/ true,
|
||||
/*enableFederatedProtocol=*/ true,
|
||||
clock)
|
||||
return
|
||||
}
|
||||
// Run tests
|
||||
t.Run("PostInboxRespondsWithStatus", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostInboxRequest(testCreate))
|
||||
delegate.EXPECT().AuthenticatePostInbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().AuthorizePostInbox(ctx, resp, toDeserializedForm(testCreate)).Return(false, nil)
|
||||
delegate.EXPECT().PostInbox(ctx, mustParse(testMyInboxIRI), toDeserializedForm(testCreate)).Return(nil)
|
||||
delegate.EXPECT().InboxForwarding(ctx, mustParse(testMyInboxIRI), toDeserializedForm(testCreate)).Return(nil)
|
||||
// Run the test
|
||||
handled, err := a.PostInbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusOK)
|
||||
})
|
||||
t.Run("PostOutboxRespondsWithDataAndHeaders", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostOutboxRequest(testCreateNoId))
|
||||
delegate.EXPECT().AuthenticatePostOutbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().AddNewIds(ctx, toDeserializedForm(testCreateNoId)).DoAndReturn(func(c context.Context, activity Activity) error {
|
||||
activity = withNewId(activity)
|
||||
return nil
|
||||
})
|
||||
delegate.EXPECT().PostOutbox(
|
||||
ctx,
|
||||
withNewId(toDeserializedForm(testCreateNoId)),
|
||||
mustParse(testMyOutboxIRI),
|
||||
mustSerialize(testCreateNoId),
|
||||
).Return(false, nil)
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusCreated)
|
||||
respV := resp.Result()
|
||||
assertEqual(t, respV.Header.Get(locationHeader), testNewActivityIRI)
|
||||
})
|
||||
t.Run("PostOutboxFederates", func(t *testing.T) {
|
||||
// Setup
|
||||
ctl := gomock.NewController(t)
|
||||
defer ctl.Finish()
|
||||
delegate, _, a := setupFn(ctl)
|
||||
resp := httptest.NewRecorder()
|
||||
req := toAPRequest(toPostOutboxRequest(testCreateNoId))
|
||||
delegate.EXPECT().AuthenticatePostOutbox(ctx, resp, req).Return(false, nil)
|
||||
delegate.EXPECT().AddNewIds(ctx, toDeserializedForm(testCreateNoId)).DoAndReturn(func(c context.Context, activity Activity) error {
|
||||
activity = withNewId(activity)
|
||||
return nil
|
||||
})
|
||||
delegate.EXPECT().PostOutbox(
|
||||
ctx,
|
||||
withNewId(toDeserializedForm(testCreateNoId)),
|
||||
mustParse(testMyOutboxIRI),
|
||||
mustSerialize(testCreateNoId),
|
||||
).Return(true, nil)
|
||||
delegate.EXPECT().Deliver(ctx, mustParse(testMyOutboxIRI), withNewId(toDeserializedForm(testCreateNoId))).Return(nil)
|
||||
// Run the test
|
||||
handled, err := a.PostOutbox(ctx, resp, req)
|
||||
// Verify results
|
||||
assertEqual(t, err, nil)
|
||||
assertEqual(t, handled, true)
|
||||
assertEqual(t, resp.Code, http.StatusCreated)
|
||||
respV := resp.Result()
|
||||
assertEqual(t, respV.Header.Get(locationHeader), testNewActivityIRI)
|
||||
})
|
||||
}
|
8316
pub/fed_test.go
8316
pub/fed_test.go
File diff suppressed because it is too large
Load Diff
|
@ -1,698 +0,0 @@
|
|||
package pub
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"github.com/go-fed/activity/vocab"
|
||||
"github.com/go-fed/httpsig"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestServeActivityPubObject(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
app *MockApplication
|
||||
clock *MockClock
|
||||
input *http.Request
|
||||
expectedCode int
|
||||
expectedObjFn func() vocab.Serializer
|
||||
expectHandled bool
|
||||
}{
|
||||
{
|
||||
name: "unsigned request",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
get: func(c context.Context, id *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil)),
|
||||
expectedCode: http.StatusOK,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "http signature request",
|
||||
input: Sign(ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil))),
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
getPublicKey: func(c context.Context, publicKeyId string) (crypto.PublicKey, httpsig.Algorithm, *url.URL, error) {
|
||||
if publicKeyId != testPublicKeyId {
|
||||
t.Fatalf("expected %s, got %s", testPublicKeyId, publicKeyId)
|
||||
}
|
||||
return testPrivateKey.Public(), httpsig.RSA_SHA256, samIRI, nil
|
||||
},
|
||||
getAsVerifiedUser: func(c context.Context, id, user *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
} else if u := user.String(); u != samIRIString {
|
||||
t.Fatalf("expected %s, got %s", samIRIString, u)
|
||||
}
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
expectedCode: http.StatusOK,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "not owned",
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil)),
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return false
|
||||
},
|
||||
},
|
||||
expectedCode: http.StatusNotFound,
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "not activitypub get",
|
||||
input: httptest.NewRequest("GET", noteURIString, nil),
|
||||
expectHandled: false,
|
||||
},
|
||||
{
|
||||
name: "bad http signature",
|
||||
input: BadSignature(ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil))),
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
getPublicKey: func(c context.Context, publicKeyId string) (crypto.PublicKey, httpsig.Algorithm, *url.URL, error) {
|
||||
if publicKeyId != testPublicKeyId {
|
||||
t.Fatalf("expected %s, got %s", testPublicKeyId, publicKeyId)
|
||||
}
|
||||
return testPrivateKey.Public(), httpsig.RSA_SHA256, samIRI, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
expectedCode: http.StatusForbidden,
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "remove bto & bcc",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
get: func(c context.Context, id *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
testNote.AppendBtoIRI(samIRI)
|
||||
testNote.AppendBccIRI(sallyIRI)
|
||||
return testNote, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil)),
|
||||
expectedCode: http.StatusOK,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "tombstone is status gone",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
get: func(c context.Context, id *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != testNewIRIString {
|
||||
t.Fatalf("expected %s, got %s", testNewIRIString, s)
|
||||
}
|
||||
tombstone := &vocab.Tombstone{}
|
||||
tombstone.SetId(testNewIRI)
|
||||
return tombstone, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != testNewIRIString {
|
||||
t.Fatalf("expected %s, got %s", testNewIRIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", testNewIRIString, nil)),
|
||||
expectedCode: http.StatusGone,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
tombstone := &vocab.Tombstone{}
|
||||
tombstone.SetId(testNewIRI)
|
||||
return tombstone
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Logf("Running table test case %q", test.name)
|
||||
resp := httptest.NewRecorder()
|
||||
fnUnderTest := ServeActivityPubObject(test.app, test.clock)
|
||||
handled, err := fnUnderTest(context.Background(), resp, test.input)
|
||||
if err != nil {
|
||||
t.Fatalf("(%q) %s", test.name, err)
|
||||
} else if handled != test.expectHandled {
|
||||
t.Fatalf("(%q) expected %v, got %v", test.name, test.expectHandled, handled)
|
||||
} else if test.expectedCode != 0 {
|
||||
if resp.Code != test.expectedCode {
|
||||
t.Fatalf("(%q) expected %d, got %d", test.name, test.expectedCode, resp.Code)
|
||||
}
|
||||
} else if test.expectedObjFn != nil {
|
||||
if err := VocabEquals(resp.Body, test.expectedObjFn()); err != nil {
|
||||
t.Fatalf("(%q) unexpected object: %s", test.name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeActivityPubObjectWithVerificationMethod(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
app *MockApplication
|
||||
clock *MockClock
|
||||
verifier *MockSocialAPIVerifier
|
||||
input *http.Request
|
||||
expectedCode int
|
||||
expectedObjFn func() vocab.Serializer
|
||||
expectHandled bool
|
||||
}{
|
||||
{
|
||||
name: "unsigned request",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
get: func(c context.Context, id *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil)),
|
||||
expectedCode: http.StatusOK,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "http signature request",
|
||||
input: Sign(ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil))),
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
getPublicKey: func(c context.Context, publicKeyId string) (crypto.PublicKey, httpsig.Algorithm, *url.URL, error) {
|
||||
if publicKeyId != testPublicKeyId {
|
||||
t.Fatalf("expected %s, got %s", testPublicKeyId, publicKeyId)
|
||||
}
|
||||
return testPrivateKey.Public(), httpsig.RSA_SHA256, samIRI, nil
|
||||
},
|
||||
getAsVerifiedUser: func(c context.Context, id, user *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
} else if u := user.String(); u != samIRIString {
|
||||
t.Fatalf("expected %s, got %s", samIRIString, u)
|
||||
}
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
expectedCode: http.StatusOK,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "not owned",
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil)),
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return false
|
||||
},
|
||||
},
|
||||
expectedCode: http.StatusNotFound,
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "not activitypub get",
|
||||
input: httptest.NewRequest("GET", noteURIString, nil),
|
||||
expectHandled: false,
|
||||
},
|
||||
{
|
||||
name: "bad http signature",
|
||||
input: BadSignature(ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil))),
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
getPublicKey: func(c context.Context, publicKeyId string) (crypto.PublicKey, httpsig.Algorithm, *url.URL, error) {
|
||||
if publicKeyId != testPublicKeyId {
|
||||
t.Fatalf("expected %s, got %s", testPublicKeyId, publicKeyId)
|
||||
}
|
||||
return testPrivateKey.Public(), httpsig.RSA_SHA256, samIRI, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
expectedCode: http.StatusForbidden,
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "unsigned request passes verifier",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
getAsVerifiedUser: func(c context.Context, id, user *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
} else if u := user.String(); u != samIRIString {
|
||||
t.Fatalf("expected %s, got %s", samIRIString, u)
|
||||
}
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
verifier: &MockSocialAPIVerifier{
|
||||
t: t,
|
||||
verify: func(r *http.Request) (*url.URL, bool, bool, error) {
|
||||
return samIRI, true, true, nil
|
||||
},
|
||||
},
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil)),
|
||||
expectedCode: http.StatusOK,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "http signature request passes verifier",
|
||||
input: Sign(ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil))),
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
getAsVerifiedUser: func(c context.Context, id, user *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
} else if u := user.String(); u != samIRIString {
|
||||
t.Fatalf("expected %s, got %s", samIRIString, u)
|
||||
}
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
verifier: &MockSocialAPIVerifier{
|
||||
t: t,
|
||||
verify: func(r *http.Request) (*url.URL, bool, bool, error) {
|
||||
return samIRI, true, true, nil
|
||||
},
|
||||
},
|
||||
expectedCode: http.StatusOK,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "verifier authed unauthz",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
verifier: &MockSocialAPIVerifier{
|
||||
t: t,
|
||||
verify: func(r *http.Request) (*url.URL, bool, bool, error) {
|
||||
return samIRI, true, false, nil
|
||||
},
|
||||
},
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil)),
|
||||
expectedCode: http.StatusForbidden,
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "verifier unauthed unauthz",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
verifier: &MockSocialAPIVerifier{
|
||||
t: t,
|
||||
verify: func(r *http.Request) (*url.URL, bool, bool, error) {
|
||||
return nil, false, false, nil
|
||||
},
|
||||
},
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil)),
|
||||
expectedCode: http.StatusBadRequest,
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "verifier unauthed authz unsigned fails",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
verifier: &MockSocialAPIVerifier{
|
||||
t: t,
|
||||
verify: func(r *http.Request) (*url.URL, bool, bool, error) {
|
||||
return nil, false, true, nil
|
||||
},
|
||||
},
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil)),
|
||||
expectedCode: http.StatusBadRequest,
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "verifier unauthed authz signed success",
|
||||
input: Sign(ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil))),
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
getPublicKey: func(c context.Context, publicKeyId string) (crypto.PublicKey, httpsig.Algorithm, *url.URL, error) {
|
||||
if publicKeyId != testPublicKeyId {
|
||||
t.Fatalf("expected %s, got %s", testPublicKeyId, publicKeyId)
|
||||
}
|
||||
return testPrivateKey.Public(), httpsig.RSA_SHA256, samIRI, nil
|
||||
},
|
||||
getAsVerifiedUser: func(c context.Context, id, user *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
} else if u := user.String(); u != samIRIString {
|
||||
t.Fatalf("expected %s, got %s", samIRIString, u)
|
||||
}
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
verifier: &MockSocialAPIVerifier{
|
||||
t: t,
|
||||
verify: func(r *http.Request) (*url.URL, bool, bool, error) {
|
||||
return nil, false, true, nil
|
||||
},
|
||||
},
|
||||
expectedCode: http.StatusOK,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "verifier unauthed authz unsigned fails with bad impl returning user",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
verifier: &MockSocialAPIVerifier{
|
||||
t: t,
|
||||
verify: func(r *http.Request) (*url.URL, bool, bool, error) {
|
||||
return samIRI, false, true, nil
|
||||
},
|
||||
},
|
||||
input: ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil)),
|
||||
expectedCode: http.StatusBadRequest,
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "remove bto & bcc",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
getPublicKey: func(c context.Context, publicKeyId string) (crypto.PublicKey, httpsig.Algorithm, *url.URL, error) {
|
||||
if publicKeyId != testPublicKeyId {
|
||||
t.Fatalf("expected %s, got %s", testPublicKeyId, publicKeyId)
|
||||
}
|
||||
return testPrivateKey.Public(), httpsig.RSA_SHA256, samIRI, nil
|
||||
},
|
||||
getAsVerifiedUser: func(c context.Context, id, user *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
} else if u := user.String(); u != samIRIString {
|
||||
t.Fatalf("expected %s, got %s", samIRIString, u)
|
||||
}
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
testNote.AppendBtoIRI(samIRI)
|
||||
testNote.AppendBccIRI(sallyIRI)
|
||||
return testNote, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != noteURIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
input: Sign(ActivityPubRequest(httptest.NewRequest("GET", noteURIString, nil))),
|
||||
expectedCode: http.StatusOK,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
testNote = &vocab.Note{}
|
||||
testNote.SetId(noteIRI)
|
||||
testNote.AppendNameString(noteName)
|
||||
testNote.AppendContentString("This is a simple note")
|
||||
return testNote
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
{
|
||||
name: "tombstone is status gone",
|
||||
app: &MockApplication{
|
||||
t: t,
|
||||
getPublicKey: func(c context.Context, publicKeyId string) (crypto.PublicKey, httpsig.Algorithm, *url.URL, error) {
|
||||
if publicKeyId != testPublicKeyId {
|
||||
t.Fatalf("expected %s, got %s", testPublicKeyId, publicKeyId)
|
||||
}
|
||||
return testPrivateKey.Public(), httpsig.RSA_SHA256, samIRI, nil
|
||||
},
|
||||
getAsVerifiedUser: func(c context.Context, id, user *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != Read {
|
||||
t.Fatalf("expected RWType of %v, got %v", Read, rw)
|
||||
} else if s := id.String(); s != testNewIRIString {
|
||||
t.Fatalf("expected %s, got %s", testNewIRIString, s)
|
||||
} else if u := user.String(); u != samIRIString {
|
||||
t.Fatalf("expected %s, got %s", samIRIString, u)
|
||||
}
|
||||
tombstone := &vocab.Tombstone{}
|
||||
tombstone.SetId(testNewIRI)
|
||||
return tombstone, nil
|
||||
},
|
||||
owns: func(c context.Context, id *url.URL) bool {
|
||||
if s := id.String(); s != testNewIRIString {
|
||||
t.Fatalf("expected %s, got %s", testNewIRIString, s)
|
||||
}
|
||||
return true
|
||||
},
|
||||
},
|
||||
clock: &MockClock{now},
|
||||
input: Sign(ActivityPubRequest(httptest.NewRequest("GET", testNewIRIString, nil))),
|
||||
expectedCode: http.StatusGone,
|
||||
expectedObjFn: func() vocab.Serializer {
|
||||
tombstone := &vocab.Tombstone{}
|
||||
tombstone.SetId(testNewIRI)
|
||||
return tombstone
|
||||
},
|
||||
expectHandled: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Logf("Running table test case %q", test.name)
|
||||
resp := httptest.NewRecorder()
|
||||
var fnUnderTest HandlerFunc
|
||||
if test.verifier != nil {
|
||||
verifierFn := func(c context.Context) SocialAPIVerifier {
|
||||
return test.verifier
|
||||
}
|
||||
fnUnderTest = ServeActivityPubObjectWithVerificationMethod(test.app, test.clock, verifierFn)
|
||||
} else {
|
||||
fnUnderTest = ServeActivityPubObjectWithVerificationMethod(test.app, test.clock, nil)
|
||||
}
|
||||
handled, err := fnUnderTest(context.Background(), resp, test.input)
|
||||
if err != nil {
|
||||
t.Fatalf("(%q) %s", test.name, err)
|
||||
} else if handled != test.expectHandled {
|
||||
t.Fatalf("(%q) expected %v, got %v", test.name, test.expectHandled, handled)
|
||||
} else if test.expectedCode != 0 {
|
||||
if resp.Code != test.expectedCode {
|
||||
t.Fatalf("(%q) expected %d, got %d", test.name, test.expectedCode, resp.Code)
|
||||
}
|
||||
} else if test.expectedObjFn != nil {
|
||||
if err := VocabEquals(resp.Body, test.expectedObjFn()); err != nil {
|
||||
t.Fatalf("(%q) unexpected object: %s", test.name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package pub
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: clock.go
|
||||
|
||||
import (
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
time "time"
|
||||
)
|
||||
|
||||
// MockClock is a mock of Clock interface
|
||||
type MockClock struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockClockMockRecorder
|
||||
}
|
||||
|
||||
// MockClockMockRecorder is the mock recorder for MockClock
|
||||
type MockClockMockRecorder struct {
|
||||
mock *MockClock
|
||||
}
|
||||
|
||||
// NewMockClock creates a new mock instance
|
||||
func NewMockClock(ctrl *gomock.Controller) *MockClock {
|
||||
mock := &MockClock{ctrl: ctrl}
|
||||
mock.recorder = &MockClockMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockClock) EXPECT() *MockClockMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Now mocks base method
|
||||
func (m *MockClock) Now() time.Time {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Now")
|
||||
ret0, _ := ret[0].(time.Time)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Now indicates an expected call of Now
|
||||
func (mr *MockClockMockRecorder) Now() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Now", reflect.TypeOf((*MockClock)(nil).Now))
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
package pub
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: delegate_actor.go
|
||||
|
||||
import (
|
||||
context "context"
|
||||
vocab "github.com/go-fed/activity/streams/vocab"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
http "net/http"
|
||||
url "net/url"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockDelegateActor is a mock of DelegateActor interface
|
||||
type MockDelegateActor struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockDelegateActorMockRecorder
|
||||
}
|
||||
|
||||
// MockDelegateActorMockRecorder is the mock recorder for MockDelegateActor
|
||||
type MockDelegateActorMockRecorder struct {
|
||||
mock *MockDelegateActor
|
||||
}
|
||||
|
||||
// NewMockDelegateActor creates a new mock instance
|
||||
func NewMockDelegateActor(ctrl *gomock.Controller) *MockDelegateActor {
|
||||
mock := &MockDelegateActor{ctrl: ctrl}
|
||||
mock.recorder = &MockDelegateActorMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockDelegateActor) EXPECT() *MockDelegateActorMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// AuthenticatePostInbox mocks base method
|
||||
func (m *MockDelegateActor) AuthenticatePostInbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AuthenticatePostInbox", c, w, r)
|
||||
ret0, _ := ret[0].(bool)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AuthenticatePostInbox indicates an expected call of AuthenticatePostInbox
|
||||
func (mr *MockDelegateActorMockRecorder) AuthenticatePostInbox(c, w, r interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticatePostInbox", reflect.TypeOf((*MockDelegateActor)(nil).AuthenticatePostInbox), c, w, r)
|
||||
}
|
||||
|
||||
// AuthenticateGetInbox mocks base method
|
||||
func (m *MockDelegateActor) AuthenticateGetInbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AuthenticateGetInbox", c, w, r)
|
||||
ret0, _ := ret[0].(bool)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AuthenticateGetInbox indicates an expected call of AuthenticateGetInbox
|
||||
func (mr *MockDelegateActorMockRecorder) AuthenticateGetInbox(c, w, r interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticateGetInbox", reflect.TypeOf((*MockDelegateActor)(nil).AuthenticateGetInbox), c, w, r)
|
||||
}
|
||||
|
||||
// AuthorizePostInbox mocks base method
|
||||
func (m *MockDelegateActor) AuthorizePostInbox(c context.Context, w http.ResponseWriter, activity Activity) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AuthorizePostInbox", c, w, activity)
|
||||
ret0, _ := ret[0].(bool)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AuthorizePostInbox indicates an expected call of AuthorizePostInbox
|
||||
func (mr *MockDelegateActorMockRecorder) AuthorizePostInbox(c, w, activity interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthorizePostInbox", reflect.TypeOf((*MockDelegateActor)(nil).AuthorizePostInbox), c, w, activity)
|
||||
}
|
||||
|
||||
// PostInbox mocks base method
|
||||
func (m *MockDelegateActor) PostInbox(c context.Context, inboxIRI *url.URL, activity Activity) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PostInbox", c, inboxIRI, activity)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// PostInbox indicates an expected call of PostInbox
|
||||
func (mr *MockDelegateActorMockRecorder) PostInbox(c, inboxIRI, activity interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PostInbox", reflect.TypeOf((*MockDelegateActor)(nil).PostInbox), c, inboxIRI, activity)
|
||||
}
|
||||
|
||||
// InboxForwarding mocks base method
|
||||
func (m *MockDelegateActor) InboxForwarding(c context.Context, inboxIRI *url.URL, activity Activity) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "InboxForwarding", c, inboxIRI, activity)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// InboxForwarding indicates an expected call of InboxForwarding
|
||||
func (mr *MockDelegateActorMockRecorder) InboxForwarding(c, inboxIRI, activity interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InboxForwarding", reflect.TypeOf((*MockDelegateActor)(nil).InboxForwarding), c, inboxIRI, activity)
|
||||
}
|
||||
|
||||
// PostOutbox mocks base method
|
||||
func (m *MockDelegateActor) PostOutbox(c context.Context, a Activity, outboxIRI *url.URL, rawJSON map[string]interface{}) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PostOutbox", c, a, outboxIRI, rawJSON)
|
||||
ret0, _ := ret[0].(bool)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PostOutbox indicates an expected call of PostOutbox
|
||||
func (mr *MockDelegateActorMockRecorder) PostOutbox(c, a, outboxIRI, rawJSON interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PostOutbox", reflect.TypeOf((*MockDelegateActor)(nil).PostOutbox), c, a, outboxIRI, rawJSON)
|
||||
}
|
||||
|
||||
// AddNewIds mocks base method
|
||||
func (m *MockDelegateActor) AddNewIds(c context.Context, a Activity) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AddNewIds", c, a)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// AddNewIds indicates an expected call of AddNewIds
|
||||
func (mr *MockDelegateActorMockRecorder) AddNewIds(c, a interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddNewIds", reflect.TypeOf((*MockDelegateActor)(nil).AddNewIds), c, a)
|
||||
}
|
||||
|
||||
// Deliver mocks base method
|
||||
func (m *MockDelegateActor) Deliver(c context.Context, outbox *url.URL, activity Activity) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Deliver", c, outbox, activity)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Deliver indicates an expected call of Deliver
|
||||
func (mr *MockDelegateActorMockRecorder) Deliver(c, outbox, activity interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Deliver", reflect.TypeOf((*MockDelegateActor)(nil).Deliver), c, outbox, activity)
|
||||
}
|
||||
|
||||
// AuthenticatePostOutbox mocks base method
|
||||
func (m *MockDelegateActor) AuthenticatePostOutbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AuthenticatePostOutbox", c, w, r)
|
||||
ret0, _ := ret[0].(bool)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AuthenticatePostOutbox indicates an expected call of AuthenticatePostOutbox
|
||||
func (mr *MockDelegateActorMockRecorder) AuthenticatePostOutbox(c, w, r interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticatePostOutbox", reflect.TypeOf((*MockDelegateActor)(nil).AuthenticatePostOutbox), c, w, r)
|
||||
}
|
||||
|
||||
// AuthenticateGetOutbox mocks base method
|
||||
func (m *MockDelegateActor) AuthenticateGetOutbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AuthenticateGetOutbox", c, w, r)
|
||||
ret0, _ := ret[0].(bool)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AuthenticateGetOutbox indicates an expected call of AuthenticateGetOutbox
|
||||
func (mr *MockDelegateActorMockRecorder) AuthenticateGetOutbox(c, w, r interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthenticateGetOutbox", reflect.TypeOf((*MockDelegateActor)(nil).AuthenticateGetOutbox), c, w, r)
|
||||
}
|
||||
|
||||
// WrapInCreate mocks base method
|
||||
func (m *MockDelegateActor) WrapInCreate(c context.Context, value vocab.Type, outboxIRI *url.URL) (vocab.ActivityStreamsCreate, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "WrapInCreate", c, value, outboxIRI)
|
||||
ret0, _ := ret[0].(vocab.ActivityStreamsCreate)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// WrapInCreate indicates an expected call of WrapInCreate
|
||||
func (mr *MockDelegateActorMockRecorder) WrapInCreate(c, value, outboxIRI interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WrapInCreate", reflect.TypeOf((*MockDelegateActor)(nil).WrapInCreate), c, value, outboxIRI)
|
||||
}
|
||||
|
||||
// GetOutbox mocks base method
|
||||
func (m *MockDelegateActor) GetOutbox(c context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetOutbox", c, r)
|
||||
ret0, _ := ret[0].(vocab.ActivityStreamsOrderedCollectionPage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetOutbox indicates an expected call of GetOutbox
|
||||
func (mr *MockDelegateActorMockRecorder) GetOutbox(c, r interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOutbox", reflect.TypeOf((*MockDelegateActor)(nil).GetOutbox), c, r)
|
||||
}
|
||||
|
||||
// GetInbox mocks base method
|
||||
func (m *MockDelegateActor) GetInbox(c context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetInbox", c, r)
|
||||
ret0, _ := ret[0].(vocab.ActivityStreamsOrderedCollectionPage)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetInbox indicates an expected call of GetInbox
|
||||
func (mr *MockDelegateActorMockRecorder) GetInbox(c, r interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInbox", reflect.TypeOf((*MockDelegateActor)(nil).GetInbox), c, r)
|
||||
}
|
|
@ -0,0 +1,292 @@
|
|||
package pub
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/go-fed/activity/streams"
|
||||
"github.com/go-fed/activity/streams/vocab"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
testMyInboxIRI = "https://example.com/addison/inbox"
|
||||
testMyOutboxIRI = "https://example.com/addison/outbox"
|
||||
testFederatedActivityIRI = "https://other.example.com/activity/1"
|
||||
testFederatedActorIRI = "https://other.example.com/dakota"
|
||||
testNoteId1 = "https://example.com/note/1"
|
||||
testNoteId2 = "https://example.com/note/2"
|
||||
testNewActivityIRI = "https://example.com/new/1"
|
||||
)
|
||||
|
||||
// mustParse parses a URL or panics.
|
||||
func mustParse(s string) *url.URL {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// assertEqual ensures two values are equal.
|
||||
func assertEqual(t *testing.T, a, b interface{}) {
|
||||
if a != b {
|
||||
t.Errorf("expected equal: %v != %v", a, b)
|
||||
}
|
||||
}
|
||||
|
||||
// assertByteEqual ensures two byte slices are equal.
|
||||
func assertByteEqual(t *testing.T, a, b []byte) {
|
||||
if string(a) != string(b) {
|
||||
t.Errorf("expected equal:\n%s\n\n%s", a, b)
|
||||
}
|
||||
}
|
||||
|
||||
// assertNotEqual ensures two values are not equal.
|
||||
func assertNotEqual(t *testing.T, a, b interface{}) {
|
||||
if a == b {
|
||||
t.Errorf("expected not equal: %v != %v", a, b)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// testNote is a test Note from a federated peer.
|
||||
testFederatedNote vocab.ActivityStreamsNote
|
||||
// testNote is a test Note owned by this server.
|
||||
testMyNote vocab.ActivityStreamsNote
|
||||
// testCreate is a test Create Activity.
|
||||
testCreate vocab.ActivityStreamsCreate
|
||||
// testCreateNoId is a test Create Activity without an 'id' set.
|
||||
testCreateNoId vocab.ActivityStreamsCreate
|
||||
// testOrderedCollectionUniqueElems is a collection with only unique
|
||||
// ids.
|
||||
testOrderedCollectionUniqueElems vocab.ActivityStreamsOrderedCollectionPage
|
||||
// testOrderedCollectionUniqueElemsString is the JSON-LD version of the
|
||||
// testOrderedCollectionUniqueElems value
|
||||
testOrderedCollectionUniqueElemsString string
|
||||
// testOrderedCollectionDupedElems is a collection with duplicated ids.
|
||||
testOrderedCollectionDupedElems vocab.ActivityStreamsOrderedCollectionPage
|
||||
// testOrderedCollectionDedupedElemsString is the JSON-LD version of the
|
||||
// testOrderedCollectionDedupedElems value with duplicates removed
|
||||
testOrderedCollectionDedupedElemsString string
|
||||
)
|
||||
|
||||
// The test data cannot be created at init time since that is when the hooks of
|
||||
// the `streams` package are set up. So initialize the data in this call instead
|
||||
// of at init time.
|
||||
func setupData() {
|
||||
// testFederatedNote
|
||||
func() {
|
||||
testFederatedNote = streams.NewActivityStreamsNote()
|
||||
name := streams.NewActivityStreamsNameProperty()
|
||||
name.AppendXMLSchemaString("A Federated Note")
|
||||
testFederatedNote.SetActivityStreamsName(name)
|
||||
content := streams.NewActivityStreamsContentProperty()
|
||||
content.AppendXMLSchemaString("This is a simple note being federated.")
|
||||
testFederatedNote.SetActivityStreamsContent(content)
|
||||
}()
|
||||
// testMyNote
|
||||
func() {
|
||||
testMyNote = streams.NewActivityStreamsNote()
|
||||
name := streams.NewActivityStreamsNameProperty()
|
||||
name.AppendXMLSchemaString("My Note")
|
||||
testMyNote.SetActivityStreamsName(name)
|
||||
content := streams.NewActivityStreamsContentProperty()
|
||||
content.AppendXMLSchemaString("This is a simple note of mine.")
|
||||
testMyNote.SetActivityStreamsContent(content)
|
||||
}()
|
||||
// testCreate
|
||||
func() {
|
||||
testCreate = streams.NewActivityStreamsCreate()
|
||||
id := streams.NewActivityStreamsIdProperty()
|
||||
id.Set(mustParse(testFederatedActivityIRI))
|
||||
testCreate.SetActivityStreamsId(id)
|
||||
actor := streams.NewActivityStreamsActorProperty()
|
||||
actor.AppendIRI(mustParse(testFederatedActorIRI))
|
||||
testCreate.SetActivityStreamsActor(actor)
|
||||
op := streams.NewActivityStreamsObjectProperty()
|
||||
op.AppendActivityStreamsNote(testFederatedNote)
|
||||
testCreate.SetActivityStreamsObject(op)
|
||||
}()
|
||||
// testCreateNoId
|
||||
func() {
|
||||
testCreateNoId = streams.NewActivityStreamsCreate()
|
||||
actor := streams.NewActivityStreamsActorProperty()
|
||||
actor.AppendIRI(mustParse(testFederatedActorIRI))
|
||||
testCreateNoId.SetActivityStreamsActor(actor)
|
||||
op := streams.NewActivityStreamsObjectProperty()
|
||||
op.AppendActivityStreamsNote(testFederatedNote)
|
||||
testCreateNoId.SetActivityStreamsObject(op)
|
||||
}()
|
||||
// testOrderedCollectionUniqueElems and
|
||||
// testOrderedCollectionUniqueElemsString
|
||||
func() {
|
||||
testOrderedCollectionUniqueElems = streams.NewActivityStreamsOrderedCollectionPage()
|
||||
oi := streams.NewActivityStreamsOrderedItemsProperty()
|
||||
oi.AppendIRI(mustParse(testNoteId1))
|
||||
oi.AppendIRI(mustParse(testNoteId2))
|
||||
testOrderedCollectionUniqueElems.SetActivityStreamsOrderedItems(oi)
|
||||
testOrderedCollectionUniqueElemsString = `{"@context":"https://www.w3.org/TR/activitystreams-vocabulary","orderedItems":["https://example.com/note/1","https://example.com/note/2"],"type":"OrderedCollectionPage"}`
|
||||
}()
|
||||
// testOrderedCollectionDupedElems and
|
||||
// testOrderedCollectionDedupedElemsString
|
||||
func() {
|
||||
testOrderedCollectionDupedElems = streams.NewActivityStreamsOrderedCollectionPage()
|
||||
oi := streams.NewActivityStreamsOrderedItemsProperty()
|
||||
oi.AppendIRI(mustParse(testNoteId1))
|
||||
oi.AppendIRI(mustParse(testNoteId1))
|
||||
testOrderedCollectionDupedElems.SetActivityStreamsOrderedItems(oi)
|
||||
testOrderedCollectionDedupedElemsString = `{"@context":"https://www.w3.org/TR/activitystreams-vocabulary","orderedItems":"https://example.com/note/1","type":"OrderedCollectionPage"}`
|
||||
}()
|
||||
}
|
||||
|
||||
// wrappedInCreate returns a Create activity wrapping the given type.
|
||||
func wrappedInCreate(t vocab.Type) vocab.ActivityStreamsCreate {
|
||||
create := streams.NewActivityStreamsCreate()
|
||||
op := streams.NewActivityStreamsObjectProperty()
|
||||
op.AppendType(t)
|
||||
create.SetActivityStreamsObject(op)
|
||||
return create
|
||||
}
|
||||
|
||||
// mustSerialize serializes a type or panics.
|
||||
func mustSerialize(t vocab.Type) map[string]interface{} {
|
||||
m, err := serialize(t)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// toDeserializedForm serializes and deserializes a type so that it works with
|
||||
// mock expectations.
|
||||
func toDeserializedForm(t vocab.Type) vocab.Type {
|
||||
m := mustSerialize(t)
|
||||
asValue, err := streams.ToType(context.Background(), m)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return asValue
|
||||
}
|
||||
|
||||
// withNewId sets a new id property on the activity
|
||||
func withNewId(t vocab.Type) Activity {
|
||||
a, ok := t.(Activity)
|
||||
if !ok {
|
||||
panic("activity streams value is not an Activity")
|
||||
}
|
||||
id := streams.NewActivityStreamsIdProperty()
|
||||
id.Set(mustParse(testNewActivityIRI))
|
||||
a.SetActivityStreamsId(id)
|
||||
return a
|
||||
}
|
||||
|
||||
// now returns the "current" time for tests.
|
||||
func now() time.Time {
|
||||
l, err := time.LoadLocation("America/New_York")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return time.Date(2000, 2, 3, 4, 5, 6, 7, l)
|
||||
}
|
||||
|
||||
// nowDateHeader returns the "current" time formatted in a form expected by the
|
||||
// Date header in HTTP responses.
|
||||
func nowDateHeader() string {
|
||||
return now().UTC().Format("Mon, 02 Jan 2006 15:04:05") + " GMT"
|
||||
}
|
||||
|
||||
// toAPRequests adds the appropriate Content-Type or Accept headers to indicate
|
||||
// that the HTTP request is an ActivityPub one. Also sets the Date header with
|
||||
// the "current" test time.
|
||||
func toAPRequest(r *http.Request) *http.Request {
|
||||
if r.Method == "POST" {
|
||||
existing, ok := r.Header[contentTypeHeader]
|
||||
if ok {
|
||||
r.Header[contentTypeHeader] = append(existing, activityStreamsMediaTypes[0])
|
||||
} else {
|
||||
r.Header[contentTypeHeader] = []string{activityStreamsMediaTypes[0]}
|
||||
}
|
||||
} else if r.Method == "GET" {
|
||||
existing, ok := r.Header[acceptHeader]
|
||||
if ok {
|
||||
r.Header[acceptHeader] = append(existing, activityStreamsMediaTypes[0])
|
||||
} else {
|
||||
r.Header[acceptHeader] = []string{activityStreamsMediaTypes[0]}
|
||||
}
|
||||
} else {
|
||||
panic("cannot toAPRequest with method " + r.Method)
|
||||
}
|
||||
r.Header[dateHeader] = []string{now().UTC().Format("Mon, 02 Jan 2006 15:04:05") + " GMT"}
|
||||
return r
|
||||
}
|
||||
|
||||
// toPostInboxRequest creates a new POST HTTP request with the given type as
|
||||
// the payload.
|
||||
func toPostInboxRequest(t vocab.Type) *http.Request {
|
||||
m, err := serialize(t)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
buf := bytes.NewBuffer(b)
|
||||
return httptest.NewRequest("POST", testMyInboxIRI, buf)
|
||||
}
|
||||
|
||||
// toPostOutboxRequest creates a new POST HTTP request with the given type as
|
||||
// the payload.
|
||||
func toPostOutboxRequest(t vocab.Type) *http.Request {
|
||||
m, err := serialize(t)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
buf := bytes.NewBuffer(b)
|
||||
return httptest.NewRequest("POST", testMyOutboxIRI, buf)
|
||||
}
|
||||
|
||||
// toPostOutboxUnknownRequest creates a new POST HTTP request with an unknown
|
||||
// type in the payload.
|
||||
func toPostOutboxUnknownRequest() *http.Request {
|
||||
s := `{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"type": "http://www.types.example/ProductOffer",
|
||||
"id": "http://www.example.com/spam"
|
||||
}`
|
||||
b := []byte(s)
|
||||
buf := bytes.NewBuffer(b)
|
||||
return httptest.NewRequest("POST", testMyOutboxIRI, buf)
|
||||
}
|
||||
|
||||
// toPostInboxUnknownRequest creates a new POST HTTP request with an unknown
|
||||
// type in the payload.
|
||||
func toPostInboxUnknownRequest() *http.Request {
|
||||
s := `{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"type": "http://www.types.example/ProductOffer",
|
||||
"id": "http://www.example.com/spam"
|
||||
}`
|
||||
b := []byte(s)
|
||||
buf := bytes.NewBuffer(b)
|
||||
return httptest.NewRequest("POST", testMyInboxIRI, buf)
|
||||
}
|
||||
|
||||
// toGetInboxRequest creates a new GET HTTP request.
|
||||
func toGetInboxRequest() *http.Request {
|
||||
return httptest.NewRequest("GET", testMyInboxIRI, nil)
|
||||
}
|
||||
|
||||
// toGetOutboxRequest creates a new GET HTTP request.
|
||||
func toGetOutboxRequest() *http.Request {
|
||||
return httptest.NewRequest("GET", testMyOutboxIRI, nil)
|
||||
}
|
|
@ -168,6 +168,8 @@ func serialize(a vocab.Type) (m map[string]interface{}, e error) {
|
|||
}
|
||||
|
||||
const (
|
||||
// The Location header
|
||||
locationHeader = "Location"
|
||||
// Contains the ActivityStreams Content-Type value.
|
||||
contentTypeHeaderValue = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
|
||||
// The Date header.
|
||||
|
|
|
@ -67,8 +67,10 @@ func TestHeaderIsActivityPubMediaType(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if actual := headerIsActivityPubMediaType(test.input); actual != test.expected {
|
||||
t.Fatalf("(%q): expected %v, got %v", test.name, test.expected, actual)
|
||||
}
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if actual := headerIsActivityPubMediaType(test.input); actual != test.expected {
|
||||
t.Fatalf("expected %v, got %v", test.expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue