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)) }) }