diff --git a/pkg/httptest/client.go b/pkg/httptest/client.go index b3df26c..6e8997a 100644 --- a/pkg/httptest/client.go +++ b/pkg/httptest/client.go @@ -2,6 +2,7 @@ package httptest import ( "net/http" + "strconv" accord "github.com/datascienceinc/accord/pkg" ) @@ -25,7 +26,7 @@ func (c *Client) Evaluate(req *http.Request, expected *accord.Response) error { // first things first is the status code right? if resp.StatusCode != expected.Code { - return diffError(string(expected.Code), string(resp.StatusCode)) + return diffError("Status", strconv.Itoa(expected.Code), strconv.Itoa(resp.StatusCode)) } // Lets go through all the headers in the expectation and make sure they match @@ -33,7 +34,7 @@ func (c *Client) Evaluate(req *http.Request, expected *accord.Response) error { // will send extra headers (ie. X-Powered-By) for h := range expected.Headers { if expected.Headers.Get(h) != resp.Header.Get(h) { - return diffError(expected.Headers.Get(h), resp.Header.Get(h)) + return diffError("Header", expected.Headers.Get(h), resp.Header.Get(h)) } } diff --git a/pkg/httptest/client_test.go b/pkg/httptest/client_test.go new file mode 100644 index 0000000..249fb1c --- /dev/null +++ b/pkg/httptest/client_test.go @@ -0,0 +1,151 @@ +package httptest + +import ( + "bytes" + "fmt" + "net/http" + "net/http/httptest" + "strings" + "testing" + + accord "github.com/datascienceinc/accord/pkg" +) + +func httpHandler(method string, res *accord.Response, t *testing.T) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + if req.Method != method { + t.Errorf("Expected method to be %s, got %s", method, req.Method) + } + + for key := range res.Headers { + w.Header().Set(key, res.Headers.Get(key)) + } + + w.WriteHeader(res.Code) + + resp := parseBody(res.Headers, res.Body) + w.Write(resp.Bytes()) + } +} + +func newRequest(method, url string, req *accord.Request) (*http.Request, error) { + var buf bytes.Buffer + if req != nil { + buf = parseBody(req.Headers, req.Body) + } + + r, err := http.NewRequest(method, url, &buf) + if err != nil { + return nil, err + } + + return r, nil +} + +func TestHttpClient(t *testing.T) { + cases := []struct { + name string + errNil bool + method string + url string + request *accord.Request + response *accord.Response + expected *accord.Response + }{ + { + name: "Basic Request", + errNil: true, + method: "GET", + url: "/test", + request: &accord.Request{}, + response: &accord.Response{}, + expected: &accord.Response{}, + }, + { + name: "Failing Status Code request", + errNil: false, + method: "GET", + url: "/test", + request: &accord.Request{}, + response: &accord.Response{}, + expected: &accord.Response{ + Code: 400, + }, + }, + { + name: "Failing Header request", + errNil: false, + method: "GET", + url: "/test", + request: &accord.Request{}, + response: &accord.Response{}, + expected: &accord.Response{ + Headers: http.Header(map[string][]string{ + "X-My-Header": []string{"test"}, + }), + }, + }, + { + name: "Failing Body request", + errNil: false, + method: "GET", + url: "/test", + request: &accord.Request{}, + response: &accord.Response{}, + expected: &accord.Response{ + Body: "test", + }, + }, + { + name: "JSON body request", + errNil: true, + method: "GET", + url: "/test", + request: &accord.Request{}, + response: &accord.Response{ + Headers: http.Header(map[string][]string{ + "Content-Type": []string{"application/json"}, + }), + Body: map[string]string{ + "test": "yes", + }, + }, + expected: &accord.Response{ + Headers: http.Header(map[string][]string{ + "Content-Type": []string{"application/json"}, + }), + Body: map[string]string{ + "test": "yes", + }, + }, + }, + } + + client := NewClient() + for _, c := range cases { + fmt.Printf("==> %s\n", c.name) + server := httptest.NewServer( + http.HandlerFunc( + httpHandler( + c.method, + c.response, + t, + ), + ), + ) + defer server.Close() + + req, err := newRequest( + c.method, + strings.Join([]string{server.URL, c.url}, "/"), + c.request) + if err != nil { + t.Error(err) + } + + err = client.Evaluate(req, c.expected) + if c.errNil && err != nil { + t.Errorf("Expected evaluate to return nil got:\n%s\n", err) + } + } +} diff --git a/pkg/httptest/utils.go b/pkg/httptest/utils.go index 8ca2614..e3e6aa1 100644 --- a/pkg/httptest/utils.go +++ b/pkg/httptest/utils.go @@ -13,12 +13,12 @@ import ( "github.com/pmezard/go-difflib/difflib" ) -func diffError(a string, b string) error { +func diffError(typ, a, b string) error { diff := difflib.ContextDiff{ A: difflib.SplitLines(a), B: difflib.SplitLines(b), - FromFile: "Actual", - ToFile: "Expectation", + FromFile: fmt.Sprintf("Actual %s", typ), + ToFile: fmt.Sprintf("Expected %s", typ), Context: 3, Eol: "\n", }