Skip to content

Commit

Permalink
Adds HTTP serving tests (dapr#98)
Browse files Browse the repository at this point in the history
* options

* service, topic test

* binding, invoke, topic tests
  • Loading branch information
mchmarny authored Oct 29, 2020
1 parent 5cfb55b commit e606bbc
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 28 deletions.
29 changes: 29 additions & 0 deletions service/http/binding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,32 @@ func TestBindingHandlerWithData(t *testing.T) {
assert.Equal(t, http.StatusOK, resp.Code)
assert.Equal(t, "test", resp.Body.String())
}

func bindingHandlerFn(ctx context.Context, in *common.BindingEvent) (out []byte, err error) {
if in == nil {
return nil, errors.New("nil input")
}
return []byte("test"), nil
}

func bindingHandlerFnWithError(ctx context.Context, in *common.BindingEvent) (out []byte, err error) {
return nil, errors.New("intentional error")
}

func TestBindingHandlerErrors(t *testing.T) {
data := `{"name": "test"}`
s := newServer("", nil)
err := s.AddBindingInvocationHandler("", bindingHandlerFn)
assert.Errorf(t, err, "expected error adding binding event handler sans route")

err = s.AddBindingInvocationHandler("errors", bindingHandlerFnWithError)
assert.NoErrorf(t, err, "error adding binding event handler sans slash")

req, err := http.NewRequest(http.MethodPost, "/errors", strings.NewReader(data))
assert.NoErrorf(t, err, "error creating request")
req.Header.Set("Content-Type", "application/json")

resp := httptest.NewRecorder()
s.mux.ServeHTTP(resp, req)
assert.Equal(t, http.StatusInternalServerError, resp.Code)
}
43 changes: 35 additions & 8 deletions service/http/invoke_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"

Expand Down Expand Up @@ -68,17 +69,43 @@ func TestInvocationHandlerWithoutInputData(t *testing.T) {
assert.Equal(t, "", string(b))
}

func emptyInvocationFn(ctx context.Context, in *common.InvocationEvent) (out *common.Content, err error) {
return nil, nil
}

func TestInvocationHandlerWithInvalidRoute(t *testing.T) {
s := newServer("", nil)
err := s.AddServiceInvocationHandler("/a", func(ctx context.Context, in *common.InvocationEvent) (out *common.Content, err error) {
return nil, nil
})

err := s.AddServiceInvocationHandler("no-slash", emptyInvocationFn)
assert.NoErrorf(t, err, "error adding no slash route event handler")

err = s.AddServiceInvocationHandler("", emptyInvocationFn)
assert.Errorf(t, err, "expected error from adding no route event handler")

err = s.AddServiceInvocationHandler("/a", emptyInvocationFn)
assert.NoErrorf(t, err, "error adding event handler")

req, err := http.NewRequest(http.MethodPost, "/b", nil)
assert.NoErrorf(t, err, "error creating request")
makeEventRequest(t, s, "/b", "", http.StatusNotFound)
}

resp := httptest.NewRecorder()
s.mux.ServeHTTP(resp, req)
assert.Equal(t, http.StatusNotFound, resp.Code)
func errorInvocationFn(ctx context.Context, in *common.InvocationEvent) (out *common.Content, err error) {
return nil, errors.New("intentional test error")
}

func TestInvocationHandlerWithError(t *testing.T) {
s := newServer("", nil)

err := s.AddServiceInvocationHandler("/error", errorInvocationFn)
assert.NoErrorf(t, err, "error adding error event handler")

makeEventRequest(t, s, "/error", "", http.StatusInternalServerError)
}

func TestValuesToMap(t *testing.T) {
m := valuesToMap(url.Values{
"k1": []string{"v11", "v12", "v13"},
"k2": []string{"v21", "v22", "v23"},
"k3": []string{"v31", "v32", "v33"},
})
assert.Equal(t, 3, len(m["k2"]))
}
12 changes: 8 additions & 4 deletions service/http/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,17 @@ func (s *Server) Stop() error {
return nil
}

func setOptions(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST,OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "authorization, origin, content-type, accept")
w.Header().Set("Allow", "POST,OPTIONS")
}

func optionsHandler(h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodOptions {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST,OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "authorization, origin, content-type, accept")
w.Header().Set("Allow", "POST,OPTIONS")
setOptions(w, r)
} else {
h.ServeHTTP(w, r)
}
Expand Down
25 changes: 25 additions & 0 deletions service/http/service_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package http

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -9,4 +11,27 @@ import (
func TestStoppingUnstartedService(t *testing.T) {
s := newServer("", nil)
assert.NotNil(t, s)
err := s.Stop()
assert.NoError(t, err)
}

func TestSettingOptions(t *testing.T) {
req, err := http.NewRequest(http.MethodOptions, "/", nil)
assert.NoErrorf(t, err, "error creating request")
w := httptest.NewRecorder()
setOptions(w, req)
resp := w.Result()
assert.NotNil(t, resp)
assert.Equal(t, "*", resp.Header.Get("Access-Control-Allow-Origin"))
assert.Equal(t, "POST,OPTIONS", resp.Header.Get("Access-Control-Allow-Methods"))
assert.Equal(t, "authorization, origin, content-type, accept", resp.Header.Get("Access-Control-Allow-Headers"))
assert.Equal(t, "POST,OPTIONS", resp.Header.Get("Allow"))
}

func testRequest(t *testing.T, s *Server, r *http.Request, expectedStatusCode int) {
rr := httptest.NewRecorder()
s.mux.ServeHTTP(rr, r)
rez := rr.Result()
assert.NotNil(t, rez)
assert.Equal(t, expectedStatusCode, rez.StatusCode)
}
69 changes: 53 additions & 16 deletions service/http/topic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,27 @@ import (
"errors"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"

"github.com/dapr/go-sdk/service/common"
"github.com/stretchr/testify/assert"
)

func testTopicFunc(ctx context.Context, e *common.TopicEvent) (retry bool, err error) {
if e == nil {
return false, errors.New("nil content")
}
if e.DataContentType != "application/json" {
return false, fmt.Errorf("invalid content type: %s", e.DataContentType)
}
return false, nil
}

func testErrorTopicFunc(ctx context.Context, e *common.TopicEvent) (retry bool, err error) {
return true, errors.New("error to cause a retry")
}

func TestEventHandler(t *testing.T) {
data := `{
"specversion" : "1.0",
Expand All @@ -35,23 +48,47 @@ func TestEventHandler(t *testing.T) {
Route: "/",
Metadata: map[string]string{},
}
err := s.AddTopicEventHandler(sub, func(ctx context.Context, e *common.TopicEvent) (retry bool, err error) {
if e == nil {
return false, errors.New("nil content")
}
if e.DataContentType != "application/json" {
return false, fmt.Errorf("invalid content type: %s", e.DataContentType)
}
return false, nil
})
err := s.AddTopicEventHandler(sub, testTopicFunc)
assert.NoErrorf(t, err, "error adding event handler")

req, err := http.NewRequest(http.MethodPost, "/", strings.NewReader(data))
assert.NoErrorf(t, err, "error creating request")
req.Header.Set("Content-Type", "application/json")
sub2 := &common.Subscription{
PubsubName: "messages",
Topic: "errors",
Route: "/errors",
Metadata: map[string]string{},
}
err = s.AddTopicEventHandler(sub2, testErrorTopicFunc)
assert.NoErrorf(t, err, "error adding error event handler")

rr := httptest.NewRecorder()
s.registerSubscribeHandler()
s.mux.ServeHTTP(rr, req)
assert.Equal(t, http.StatusOK, rr.Code)

makeEventRequest(t, s, "/", data, http.StatusOK)
makeEventRequest(t, s, "/", "", http.StatusSeeOther)
makeEventRequest(t, s, "/", "not JSON", http.StatusSeeOther)
makeEventRequest(t, s, "/errors", data, http.StatusOK)
}

func makeEventRequest(t *testing.T, s *Server, route, data string, expectedStatusCode int) {
req, err := http.NewRequest(http.MethodPost, route, strings.NewReader(data))
assert.NoErrorf(t, err, "error creating request: %s", data)
req.Header.Set("Content-Type", "application/json")
testRequest(t, s, req, expectedStatusCode)
}

func TestAddingInvalidEventHandlers(t *testing.T) {
s := newServer("", nil)
err := s.AddTopicEventHandler(nil, testTopicFunc)
assert.Errorf(t, err, "expected error adding no sub event handler")

sub := &common.Subscription{Metadata: map[string]string{}}
err = s.AddTopicEventHandler(sub, testTopicFunc)
assert.Errorf(t, err, "expected error adding empty sub event handler")

sub.Topic = "test"
err = s.AddTopicEventHandler(sub, testTopicFunc)
assert.Errorf(t, err, "expected error adding sub without component event handler")

sub.PubsubName = "messages"
err = s.AddTopicEventHandler(sub, testTopicFunc)
assert.Errorf(t, err, "expected error adding sub without route event handler")
}

0 comments on commit e606bbc

Please sign in to comment.