From 4b2da3f3f20a869b72e30f63952a9115f17c4c75 Mon Sep 17 00:00:00 2001 From: Chris James Date: Sun, 7 Aug 2016 15:53:23 +0100 Subject: [PATCH] seems to be working --- examples/example.yaml | 12 ++++++++ mockingjay/fakeendpoint.go | 1 - mockingjay/fakeendpoint_test.go | 8 ++++++ mockingjay/request.go | 51 +++++++++++++++++++++++++++++++-- mockingjay/request_test.go | 10 +++++-- mockingjay/requestmatch_test.go | 18 ++++++++++++ mockingjay/server_test.go | 4 +-- 7 files changed, 97 insertions(+), 7 deletions(-) diff --git a/examples/example.yaml b/examples/example.yaml index d814536a..0be8f374 100644 --- a/examples/example.yaml +++ b/examples/example.yaml @@ -35,3 +35,15 @@ response: code: 500 body: Oh no + + - name: Posting forms + cdcdisabled: false + request: + uri: /cats + method: POST + form: + age: 10 + name: Hudson + response: + code: 201 + body: Created \ No newline at end of file diff --git a/mockingjay/fakeendpoint.go b/mockingjay/fakeendpoint.go index 962d128a..e20e2cd8 100644 --- a/mockingjay/fakeendpoint.go +++ b/mockingjay/fakeendpoint.go @@ -12,7 +12,6 @@ type FakeEndpoint struct { CDCDisabled bool // When set to true it will not be included in the consumer driven contract tests against real server Request Request Response response - Form map[string]string } const fakeEndpointStringerFormat = "%s (%s)" diff --git a/mockingjay/fakeendpoint_test.go b/mockingjay/fakeendpoint_test.go index 9990792a..faece4ea 100644 --- a/mockingjay/fakeendpoint_test.go +++ b/mockingjay/fakeendpoint_test.go @@ -35,6 +35,9 @@ const testYAML = ` request: uri: /card method: POST + form: + age: 10 + name: Hudson body: Greetings response: code: 500 @@ -63,6 +66,11 @@ func TestItCreatesAServerConfigFromYAML(t *testing.T) { endpoint2 := endpoints[1] assert.True(t, endpoint2.CDCDisabled) + + failingEndpoint := endpoints[2] + + assert.Equal(t, failingEndpoint.Request.Form["age"], "10") + assert.Equal(t, failingEndpoint.Request.Form["name"], "Hudson") } func TestItReturnsAnErrorWhenNotValidYAML(t *testing.T) { diff --git a/mockingjay/request.go b/mockingjay/request.go index 1c2e0d71..0eb56126 100644 --- a/mockingjay/request.go +++ b/mockingjay/request.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "log" "net/http" + "net/url" "reflect" "strings" ) @@ -19,6 +20,7 @@ type Request struct { Method string Headers map[string]string Body string + Form map[string]string } var ( @@ -46,7 +48,18 @@ func (r Request) errors() error { // AsHTTPRequest tries to create a http.Request from a given baseURL func (r Request) AsHTTPRequest(baseURL string) (req *http.Request, err error) { - req, err = http.NewRequest(r.Method, baseURL+r.URI, ioutil.NopCloser(bytes.NewBufferString(r.Body))) + //todo: Test me with the form stuff + + body := r.Body + if r.Form != nil { + form := url.Values{} + for formKey, formValue := range r.Form { + form.Add(formKey, formValue) + } + body = form.Encode() + } + + req, err = http.NewRequest(r.Method, baseURL+r.URI, ioutil.NopCloser(bytes.NewBufferString(body))) if err != nil { return @@ -56,11 +69,18 @@ func (r Request) AsHTTPRequest(baseURL string) (req *http.Request, err error) { req.Header.Add(headerName, headerValue) } + if r.Form != nil { + req.Header.Add("content-type", "application/x-www-form-urlencoded") + } + return } // NewRequest creates a mockingjay request from a http request func NewRequest(httpRequest *http.Request) (req Request) { + + //todo: Test me with the form stuff + req.URI = httpRequest.URL.String() req.Method = httpRequest.Method @@ -69,6 +89,8 @@ func NewRequest(httpRequest *http.Request) (req Request) { req.Headers[header] = strings.Join(values, ",") } + err := httpRequest.ParseForm() + if httpRequest.Body != nil { reqBody, err := ioutil.ReadAll(httpRequest.Body) if err != nil { @@ -78,6 +100,16 @@ func NewRequest(httpRequest *http.Request) (req Request) { } } + if err == nil { + req.Form = make(map[string]string) + for key, val := range httpRequest.PostForm { + log.Println(val) + req.Form[key] = val[0] // bit naughty + } + } else { + log.Println("Problem parsing http form", err) + } + return } @@ -97,8 +129,23 @@ func requestMatches(expected, incoming Request) bool { bodyOk := expected.Body == "*" || expected.Body == incoming.Body || matchJSON(expected.Body, incoming.Body) urlOk := matchURI(expected.URI, expected.RegexURI, incoming.URI) methodOk := expected.Method == incoming.Method + formOK := matchForm(expected.Form, incoming.Form) + + return bodyOk && urlOk && methodOk && headersOk && formOK +} + +func matchForm(expected map[string]string, incoming map[string]string) bool { + if expected == nil { + return true + } - return bodyOk && urlOk && methodOk && headersOk + for expectedKey, expectedValue := range expected { + if incoming[expectedKey] != expectedValue { + return false + } + } + + return true } func matchJSON(a string, b string) bool { diff --git a/mockingjay/request_test.go b/mockingjay/request_test.go index 4a2ed89d..a708bfb2 100644 --- a/mockingjay/request_test.go +++ b/mockingjay/request_test.go @@ -1,10 +1,10 @@ package mockingjay import ( + "github.com/stretchr/testify/assert" "io/ioutil" + "net/http" "testing" - - "github.com/stretchr/testify/assert" ) func TestItCreatesHTTPRequests(t *testing.T) { @@ -32,6 +32,12 @@ func TestItCreatesHTTPRequests(t *testing.T) { assert.Equal(t, string(requestBody), body) } +func TestItMapsHTTPRequestsToMJRequests(t *testing.T) { + req, _ := http.NewRequest(http.MethodPost, "/foo", nil) + mjRequest := NewRequest(req) + assert.Equal(t, mjRequest.Method, http.MethodPost) +} + func TestItValidatesRequests(t *testing.T) { noURIRequest := Request{ URI: "", diff --git a/mockingjay/requestmatch_test.go b/mockingjay/requestmatch_test.go index 3c77087f..12ea3927 100644 --- a/mockingjay/requestmatch_test.go +++ b/mockingjay/requestmatch_test.go @@ -21,11 +21,15 @@ func TestItMatchesRequests(t *testing.T) { wrongHeaders := make(map[string]string) wrongHeaders["Content-Type"] = "text/html" + form := make(map[string]string) + form["name"] = "Hudson" + config := Request{ URI: "/cats", Method: "POST", Headers: requiredHeaders, Body: `123`, + Form: form, } failingCases := []struct { @@ -39,6 +43,7 @@ func TestItMatchesRequests(t *testing.T) { Method: "POST", Headers: requiredHeaders, Body: `123`, + Form: form, }, }, { @@ -48,6 +53,7 @@ func TestItMatchesRequests(t *testing.T) { Method: "GET", Headers: requiredHeaders, Body: `123`, + Form: form, }, }, { @@ -57,6 +63,7 @@ func TestItMatchesRequests(t *testing.T) { Method: "POST", Headers: wrongHeaders, Body: `123`, + Form: form, }, }, { @@ -66,6 +73,17 @@ func TestItMatchesRequests(t *testing.T) { Method: "POST", Headers: requiredHeaders, Body: `456`, + Form: form, + }, + }, + { + "No form", + Request{ + URI: "/cats", + Method: "POST", + Headers: requiredHeaders, + Body: `123`, + Form: nil, }, }, } diff --git a/mockingjay/server_test.go b/mockingjay/server_test.go index 542481c7..d847b3c7 100644 --- a/mockingjay/server_test.go +++ b/mockingjay/server_test.go @@ -135,7 +135,7 @@ func TestItRecordsIncomingRequests(t *testing.T) { wildcardBody := "*" expectedStatus := http.StatusOK - mjReq := Request{URI: testURL, Method: "POST", Body: wildcardBody, nil} + mjReq := Request{URI: testURL, Method: "POST", Body: wildcardBody, Form: nil} config := FakeEndpoint{testEndpointName, cdcDisabled, mjReq, response{expectedStatus, "", nil}} server := NewServer([]FakeEndpoint{config}) @@ -149,7 +149,7 @@ func TestItRecordsIncomingRequests(t *testing.T) { } func TestItReturnsListOfEndpoints(t *testing.T) { - mjReq := Request{URI: testURL, Method: "GET", nil} + mjReq := Request{URI: testURL, Method: "GET", Form: nil} endpoint := FakeEndpoint{testEndpointName, cdcDisabled, mjReq, response{http.StatusCreated, cannedResponse, nil}} server := NewServer([]FakeEndpoint{endpoint})