From c3b24964d414f8d305487e0df1ca40a63feec566 Mon Sep 17 00:00:00 2001 From: Cory Slep Date: Sun, 5 Jul 2020 15:54:31 +0200 Subject: [PATCH] Add unit tests for the AS handler --- pub/handlers_test.go | 105 +++++++++++++++++++++++++++++++++++++++++++ pub/pub_test.go | 9 ++++ 2 files changed, 114 insertions(+) create mode 100644 pub/handlers_test.go diff --git a/pub/handlers_test.go b/pub/handlers_test.go new file mode 100644 index 0000000..f31e477 --- /dev/null +++ b/pub/handlers_test.go @@ -0,0 +1,105 @@ +package pub + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" + + "github.com/golang/mock/gomock" +) + +// TestActivityStreamsHandler tests the handler for serving ActivityPub +// requests. +func TestActivityStreamsHandler(t *testing.T) { + ctx := context.Background() + setupFn := func(ctl *gomock.Controller) (db *MockDatabase, clock *MockClock, hf HandlerFunc) { + db = NewMockDatabase(ctl) + clock = NewMockClock(ctl) + hf = NewActivityStreamsHandler(db, clock) + return + } + t.Run("IgnoresIfNotActivityPubGetRequest", func(t *testing.T) { + // Setup + ctl := gomock.NewController(t) + defer ctl.Finish() + _, _, hf := setupFn(ctl) + resp := httptest.NewRecorder() + req := httptest.NewRequest("GET", testNoteId1, nil) + // Run & Verify + isAPReq, err := hf(ctx, resp, req) + assertEqual(t, isAPReq, false) + assertEqual(t, err, nil) + assertEqual(t, len(resp.Result().Header), 0) + }) + t.Run("ReturnsErrorWhenDatabaseFetchReturnsError", func(t *testing.T) { + // Setup + ctl := gomock.NewController(t) + defer ctl.Finish() + mockDb, _, hf := setupFn(ctl) + resp := httptest.NewRecorder() + req := toAPRequest(httptest.NewRequest("GET", testNoteId1, nil)) + testErr := fmt.Errorf("test error") + // Mock + mockDb.EXPECT().Lock(ctx, mustParse(testNoteId1)) + mockDb.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(nil, testErr) + mockDb.EXPECT().Unlock(ctx, mustParse(testNoteId1)) + // Run & Verify + isAPReq, err := hf(ctx, resp, req) + assertEqual(t, isAPReq, true) + assertEqual(t, err, testErr) + assertEqual(t, len(resp.Result().Header), 0) + }) + t.Run("ServesTombstoneWithStatusGone", func(t *testing.T) { + // Setup + ctl := gomock.NewController(t) + defer ctl.Finish() + mockDb, mockClock, hf := setupFn(ctl) + resp := httptest.NewRecorder() + req := toAPRequest(httptest.NewRequest("GET", testNoteId1, nil)) + // Mock + mockDb.EXPECT().Lock(ctx, mustParse(testNoteId1)) + mockDb.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(testTombstone, nil) + mockDb.EXPECT().Unlock(ctx, mustParse(testNoteId1)) + mockClock.EXPECT().Now().Return(now()) + // Run & Verify + isAPReq, err := hf(ctx, resp, req) + assertEqual(t, isAPReq, true) + assertEqual(t, err, nil) + assertEqual(t, resp.Code, http.StatusGone) + 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, mustSerializeToBytes(testTombstone)) + }) + t.Run("ServesContentWithStatusOk", func(t *testing.T) { + // Setup + ctl := gomock.NewController(t) + defer ctl.Finish() + mockDb, mockClock, hf := setupFn(ctl) + resp := httptest.NewRecorder() + req := toAPRequest(httptest.NewRequest("GET", testNoteId1, nil)) + // Mock + mockDb.EXPECT().Lock(ctx, mustParse(testNoteId1)) + mockDb.EXPECT().Get(ctx, mustParse(testNoteId1)).Return(testMyNote, nil) + mockDb.EXPECT().Unlock(ctx, mustParse(testNoteId1)) + mockClock.EXPECT().Now().Return(now()) + // Run & Verify + isAPReq, err := hf(ctx, resp, req) + assertEqual(t, isAPReq, true) + assertEqual(t, err, nil) + 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, mustSerializeToBytes(testMyNote)) + }) +} diff --git a/pub/pub_test.go b/pub/pub_test.go index 5621c7e..3a15d14 100644 --- a/pub/pub_test.go +++ b/pub/pub_test.go @@ -144,6 +144,8 @@ var ( testNestedInReplyTo vocab.ActivityStreamsListen // testFollow is a test Follow Activity. testFollow vocab.ActivityStreamsFollow + // testTombstone is a test Tombsone. + testTombstone vocab.ActivityStreamsTombstone ) // The test data cannot be created at init time since that is when the hooks of @@ -449,6 +451,13 @@ func setupData() { op.AppendIRI(mustParse(testFederatedActorIRI)) testFollow.SetActivityStreamsObject(op) }() + // testTombstone + func() { + testTombstone = streams.NewActivityStreamsTombstone() + id := streams.NewJSONLDIdProperty() + id.Set(mustParse(testFederatedActivityIRI)) + testTombstone.SetJSONLDId(id) + }() } // wrappedInCreate returns a Create activity wrapping the given type.