From 289f1498a1ded81277c860794e2ec8c3ed57dac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulrich=20Liss=C3=A9?= Date: Wed, 10 Apr 2019 15:46:30 +0200 Subject: [PATCH 1/2] Introduce Recorder to simplify httptest setup --- mite/api.go | 14 +++- mite/api_test.go | 100 +++++++++++++++++++++++-- mite/project_test.go | 26 +++---- mite/service_test.go | 26 +++---- mite/time_entry_test.go | 161 +++++++++++++++------------------------- mite/tracker_test.go | 132 ++++++++++++++------------------ 6 files changed, 244 insertions(+), 215 deletions(-) diff --git a/mite/api.go b/mite/api.go index 2a091dc..fafce7f 100644 --- a/mite/api.go +++ b/mite/api.go @@ -68,7 +68,12 @@ func (a *api) get(resource string, query url.Values, result interface{}) error { } func (a *api) post(resource string, body interface{}, result interface{}) error { - b, err := json.Marshal(body) + v := body + if v == nil { + v = struct{}{} + } + + b, err := json.Marshal(v) if err != nil { return err } @@ -100,7 +105,12 @@ func (a *api) post(resource string, body interface{}, result interface{}) error } func (a *api) patch(resource string, body interface{}, result interface{}) error { - b, err := json.Marshal(body) + v := body + if v == nil { + v = struct{}{} + } + + b, err := json.Marshal(v) if err != nil { return err } diff --git a/mite/api_test.go b/mite/api_test.go index dc6753a..bb6a277 100644 --- a/mite/api_test.go +++ b/mite/api_test.go @@ -3,6 +3,8 @@ package mite_test import ( "bytes" "encoding/json" + "io/ioutil" + "net/http" ) const ( @@ -11,13 +13,97 @@ const ( testUserAgent = "mite-go/" + testClientVersion + " (+github.com/leanovate/mite-go)" ) -type recorder struct { - method string - url string - body []byte - contentType string - userAgent string - miteKey string +type Recorder struct { + reqMethod string + reqUri string + reqBody []byte + reqHeader http.Header + resHeader http.Header + resBody string + resStatus int +} + +func NewRecorder() *Recorder { + return &Recorder{reqHeader: make(http.Header), resHeader: make(http.Header), resStatus: 200} +} + +func (r *Recorder) RequestMethod() string { + return r.reqMethod +} + +func (r *Recorder) RequestURI() string { + return r.reqUri +} + +func (r *Recorder) RequestContentType() string { + return r.RequestHeader("Content-Type") +} + +func (r *Recorder) RequestUserAgent() string { + return r.RequestHeader("User-Agent") +} + +func (r *Recorder) RequestMiteKey() string { + return r.RequestHeader("X-MiteApiKey") +} + +func (r *Recorder) RequestHeader(header string) string { + return r.reqHeader.Get(header) +} + +func (r *Recorder) RequestBody() []byte { + return r.reqBody +} + +func (r *Recorder) ResponseContentType(contentType string) *Recorder { + r.resHeader.Add("Content-Type", contentType) + return r +} + +func (r *Recorder) ResponseLocation(location string) *Recorder { + r.resHeader.Add("Location", location) + return r +} + +func (r *Recorder) ResponseBody(body string) *Recorder { + r.resBody = body + return r +} + +func (r *Recorder) ResponseStatus(status int) *Recorder { + r.resStatus = status + return r +} + +func (r *Recorder) Handler() http.Handler { + return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + b, err := ioutil.ReadAll(request.Body) + if err != nil { + panic(err) + } + + r.reqMethod = request.Method + r.reqUri = request.RequestURI + r.reqHeader = request.Header + r.reqBody = b + + for k, vs := range r.resHeader { + for _, v := range vs { + writer.Header().Add(k, v) + } + } + + writer.WriteHeader(r.resStatus) + + if r.resBody == "" { + return + } + + _, err = writer.Write([]byte(r.resBody)) + if err != nil { + panic(err) + } + }) } func prettifyJson(b []byte, indent string) []byte { diff --git a/mite/project_test.go b/mite/project_test.go index 13c437c..1ff0408 100644 --- a/mite/project_test.go +++ b/mite/project_test.go @@ -45,17 +45,11 @@ var projectObject = domain.Project{ func TestApi_Projects(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.WriteHeader(200) - _, _ = w.Write([]byte(fmt.Sprintf("[%s]", projectResponse))) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseBody(fmt.Sprintf("[%s]", projectResponse)). + ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -69,8 +63,10 @@ func TestApi_Projects(t *testing.T) { assert.Nil(t, err) assert.Equal(t, []*domain.Project{&projectObject}, projects) - assert.Equal(t, http.MethodGet, rec.method) - assert.Equal(t, "/projects.json", rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodGet, rec.RequestMethod()) + assert.Equal(t, "/projects.json", rec.RequestURI()) + assert.Empty(t, rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Empty(t, rec.RequestBody()) } diff --git a/mite/service_test.go b/mite/service_test.go index e81fb34..2fa58d2 100644 --- a/mite/service_test.go +++ b/mite/service_test.go @@ -31,17 +31,11 @@ var serviceObject = domain.Service{ func TestApi_Services(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.WriteHeader(200) - _, _ = w.Write([]byte(fmt.Sprintf("[%s]", serviceResponse))) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseBody(fmt.Sprintf("[%s]", serviceResponse)). + ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -55,8 +49,10 @@ func TestApi_Services(t *testing.T) { assert.Nil(t, err) assert.Equal(t, []*domain.Service{&serviceObject}, services) - assert.Equal(t, http.MethodGet, rec.method) - assert.Equal(t, "/services.json", rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodGet, rec.RequestMethod()) + assert.Equal(t, "/services.json", rec.RequestURI()) + assert.Empty(t, rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Empty(t, rec.RequestBody()) } diff --git a/mite/time_entry_test.go b/mite/time_entry_test.go index 6d37b91..afda63a 100644 --- a/mite/time_entry_test.go +++ b/mite/time_entry_test.go @@ -5,7 +5,6 @@ import ( "github.com/leanovate/mite-go/domain" "github.com/leanovate/mite-go/mite" "github.com/stretchr/testify/assert" - "io/ioutil" "net/http" "net/http/httptest" "testing" @@ -68,17 +67,11 @@ var timeEntryObject = domain.TimeEntry{ func TestApi_TimeEntries(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.WriteHeader(200) - _, _ = w.Write([]byte(fmt.Sprintf("[%s]", timeEntryResponse))) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseBody(fmt.Sprintf("[%s]", timeEntryResponse)). + ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -92,25 +85,21 @@ func TestApi_TimeEntries(t *testing.T) { assert.Nil(t, err) assert.Equal(t, []*domain.TimeEntry{&timeEntryObject}, timeEntries) - assert.Equal(t, http.MethodGet, rec.method) - assert.Equal(t, "/time_entries.json", rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodGet, rec.RequestMethod()) + assert.Equal(t, "/time_entries.json", rec.RequestURI()) + assert.Empty(t, rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Empty(t, rec.RequestBody()) } func TestApi_TimeEntries_WithQuery(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.WriteHeader(200) - _, _ = w.Write([]byte(fmt.Sprintf("[%s]", timeEntryResponse))) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseBody(fmt.Sprintf("[%s]", timeEntryResponse)). + ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -130,25 +119,21 @@ func TestApi_TimeEntries_WithQuery(t *testing.T) { assert.Nil(t, err) assert.Equal(t, []*domain.TimeEntry{&timeEntryObject}, timeEntries) - assert.Equal(t, http.MethodGet, rec.method) - assert.Equal(t, fmt.Sprintf("/time_entries.json?direction=%s&from=%s&to=%s", query.Direction, query.From, query.To), rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodGet, rec.RequestMethod()) + assert.Equal(t, fmt.Sprintf("/time_entries.json?direction=%s&from=%s&to=%s", query.Direction, query.From, query.To), rec.RequestURI()) + assert.Empty(t, rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Empty(t, rec.RequestBody()) } func TestApi_TimeEntry(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.WriteHeader(200) - _, _ = w.Write([]byte(timeEntryResponse)) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseBody(timeEntryResponse). + ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -162,30 +147,22 @@ func TestApi_TimeEntry(t *testing.T) { assert.Nil(t, err) assert.Equal(t, &timeEntryObject, timeEntry) - assert.Equal(t, http.MethodGet, rec.method) - assert.Equal(t, fmt.Sprintf("/time_entries/%s.json", timeEntryObject.Id), rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodGet, rec.RequestMethod()) + assert.Equal(t, fmt.Sprintf("/time_entries/%s.json", timeEntryObject.Id), rec.RequestURI()) + assert.Empty(t, rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Empty(t, rec.RequestBody()) } func TestApi_CreateTimeEntry(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - b, _ := ioutil.ReadAll(r.Body) - - rec.body = b - rec.method = r.Method - rec.url = r.RequestURI - rec.contentType = r.Header.Get("Content-Type") - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.Header().Add("Location", fmt.Sprintf("/time_entries/%s.json", timeEntryObject.Id)) - w.WriteHeader(201) - _, _ = w.Write([]byte(timeEntryResponse)) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseLocation(fmt.Sprintf("/time_entries/%s.json", timeEntryObject.Id)). + ResponseBody(timeEntryResponse). + ResponseStatus(201) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -206,30 +183,18 @@ func TestApi_CreateTimeEntry(t *testing.T) { assert.Nil(t, err) assert.Equal(t, &timeEntryObject, timeEntry) - assert.Equal(t, timeEntryRequest, string(prettifyJson(rec.body, " "))) - assert.Equal(t, http.MethodPost, rec.method) - assert.Equal(t, "/time_entries.json", rec.url) - assert.Equal(t, "application/json", rec.contentType) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodPost, rec.RequestMethod()) + assert.Equal(t, "/time_entries.json", rec.RequestURI()) + assert.Equal(t, "application/json", rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Equal(t, timeEntryRequest, string(prettifyJson(rec.RequestBody(), " "))) } func TestApi_EditTimeEntry(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - b, _ := ioutil.ReadAll(r.Body) - - rec.body = b - rec.method = r.Method - rec.url = r.RequestURI - rec.contentType = r.Header.Get("Content-Type") - - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.WriteHeader(200) - })) + rec := NewRecorder().ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -249,24 +214,18 @@ func TestApi_EditTimeEntry(t *testing.T) { // then assert.Nil(t, err) - assert.Equal(t, timeEntryRequest, string(prettifyJson(rec.body, " "))) - assert.Equal(t, http.MethodPatch, rec.method) - assert.Equal(t, fmt.Sprintf("/time_entries/%s.json", timeEntryObject.Id), rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodPatch, rec.RequestMethod()) + assert.Equal(t, fmt.Sprintf("/time_entries/%s.json", timeEntryObject.Id), rec.RequestURI()) + assert.Equal(t, "application/json", rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Equal(t, timeEntryRequest, string(prettifyJson(rec.RequestBody(), " "))) } func TestApi_DeleteTimeEntry(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.WriteHeader(200) - })) + rec := NewRecorder().ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -279,8 +238,10 @@ func TestApi_DeleteTimeEntry(t *testing.T) { // then assert.Nil(t, err) - assert.Equal(t, http.MethodDelete, rec.method) - assert.Equal(t, fmt.Sprintf("/time_entries/%s.json", timeEntryObject.Id), rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodDelete, rec.RequestMethod()) + assert.Equal(t, fmt.Sprintf("/time_entries/%s.json", timeEntryObject.Id), rec.RequestURI()) + assert.Empty(t, rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Empty(t, rec.RequestBody()) } diff --git a/mite/tracker_test.go b/mite/tracker_test.go index b20c413..a9c7bf0 100644 --- a/mite/tracker_test.go +++ b/mite/tracker_test.go @@ -11,7 +11,7 @@ import ( "time" ) -const emptyResponse = `{"tracker":{}}` +const emptyTrackerResponse = `{"tracker":{}}` const trackingTimeEntryResponse = `{ "tracker": { @@ -59,17 +59,11 @@ var stoppedTimeEntryObject = domain.StoppedTimeEntry{ func TestApi_Tracker(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.WriteHeader(200) - _, _ = w.Write([]byte(trackingTimeEntryResponse)) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseBody(trackingTimeEntryResponse). + ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -83,25 +77,21 @@ func TestApi_Tracker(t *testing.T) { assert.Nil(t, err) assert.Equal(t, &trackingTimeEntryObject, tracking) - assert.Equal(t, http.MethodGet, rec.method) - assert.Equal(t, "/tracker.json", rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodGet, rec.RequestMethod()) + assert.Equal(t, "/tracker.json", rec.RequestURI()) + assert.Empty(t, rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Empty(t, rec.RequestBody()) } func TestApi_Tracker_Empty(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.WriteHeader(200) - _, _ = w.Write([]byte(emptyResponse)) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseBody(emptyTrackerResponse). + ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -115,25 +105,21 @@ func TestApi_Tracker_Empty(t *testing.T) { assert.Nil(t, err) assert.Nil(t, tracking) - assert.Equal(t, http.MethodGet, rec.method) - assert.Equal(t, "/tracker.json", rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodGet, rec.RequestMethod()) + assert.Equal(t, "/tracker.json", rec.RequestURI()) + assert.Empty(t, rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Empty(t, rec.RequestBody()) } func TestApi_StartTracker(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.WriteHeader(200) - _, _ = w.Write([]byte(trackingTimeEntryResponse)) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseBody(trackingTimeEntryResponse). + ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -148,25 +134,21 @@ func TestApi_StartTracker(t *testing.T) { assert.Equal(t, &trackingTimeEntryObject, tracking) assert.Nil(t, stopped) - assert.Equal(t, http.MethodPatch, rec.method) - assert.Equal(t, fmt.Sprintf("/tracker/%s.json", trackingTimeEntryObject.Id), rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodPatch, rec.RequestMethod()) + assert.Equal(t, fmt.Sprintf("/tracker/%s.json", trackingTimeEntryObject.Id), rec.RequestURI()) + assert.Equal(t, "application/json", rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Equal(t, "{}", string(prettifyJson(rec.RequestBody(), ""))) } func TestApi_StartTracker_Running(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.WriteHeader(200) - _, _ = w.Write([]byte(combinedTimeEntryResponse)) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseBody(combinedTimeEntryResponse). + ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -181,25 +163,21 @@ func TestApi_StartTracker_Running(t *testing.T) { assert.Equal(t, &trackingTimeEntryObject, tracking) assert.Equal(t, &stoppedTimeEntryObject, stopped) - assert.Equal(t, http.MethodPatch, rec.method) - assert.Equal(t, fmt.Sprintf("/tracker/%s.json", trackingTimeEntryObject.Id), rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodPatch, rec.RequestMethod()) + assert.Equal(t, fmt.Sprintf("/tracker/%s.json", trackingTimeEntryObject.Id), rec.RequestURI()) + assert.Equal(t, "application/json", rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Equal(t, "{}", string(prettifyJson(rec.RequestBody(), ""))) } func TestApi_StopTracker(t *testing.T) { // given - rec := recorder{} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rec.method = r.Method - rec.url = r.RequestURI - rec.miteKey = r.Header.Get("X-MiteApiKey") - rec.userAgent = r.Header.Get("User-Agent") - - w.Header().Add("Content-Type", "application/json; charset=utf-8") - w.WriteHeader(200) - _, _ = w.Write([]byte(stoppedTimeEntryResponse)) - })) + rec := NewRecorder(). + ResponseContentType("application/json; charset=utf-8"). + ResponseBody(stoppedTimeEntryResponse). + ResponseStatus(200) + srv := httptest.NewServer(rec.Handler()) defer srv.Close() @@ -213,8 +191,10 @@ func TestApi_StopTracker(t *testing.T) { assert.Nil(t, err) assert.Equal(t, &stoppedTimeEntryObject, stopped) - assert.Equal(t, http.MethodDelete, rec.method) - assert.Equal(t, fmt.Sprintf("/tracker/%s.json", stoppedTimeEntryObject.Id), rec.url) - assert.Equal(t, testApiKey, rec.miteKey) - assert.Equal(t, testUserAgent, rec.userAgent) + assert.Equal(t, http.MethodDelete, rec.RequestMethod()) + assert.Equal(t, fmt.Sprintf("/tracker/%s.json", stoppedTimeEntryObject.Id), rec.RequestURI()) + assert.Empty(t, rec.RequestContentType()) + assert.Equal(t, testUserAgent, rec.RequestUserAgent()) + assert.Equal(t, testApiKey, rec.RequestMiteKey()) + assert.Empty(t, rec.RequestBody()) } From 88c6b869e0bbc91632a3edcbe03273ec0e94200e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulrich=20Liss=C3=A9?= Date: Wed, 10 Apr 2019 15:55:42 +0200 Subject: [PATCH 2/2] Simplify JSON assertions --- mite/api_test.go | 12 ++++++++++-- mite/time_entry_test.go | 4 ++-- mite/tracker_test.go | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/mite/api_test.go b/mite/api_test.go index bb6a277..4df53ac 100644 --- a/mite/api_test.go +++ b/mite/api_test.go @@ -55,6 +55,10 @@ func (r *Recorder) RequestBody() []byte { return r.reqBody } +func (r *Recorder) RequestBodyCanonical() string { + return string(canonicalJSON(r.reqBody)) +} + func (r *Recorder) ResponseContentType(contentType string) *Recorder { r.resHeader.Add("Content-Type", contentType) return r @@ -106,9 +110,13 @@ func (r *Recorder) Handler() http.Handler { }) } -func prettifyJson(b []byte, indent string) []byte { +func CanonicalString(s string) string { + return string(canonicalJSON([]byte(s))) +} + +func canonicalJSON(b []byte) []byte { buf := &bytes.Buffer{} - err := json.Indent(buf, b, "", indent) + err := json.Indent(buf, b, "", " ") if err != nil { panic(err) } diff --git a/mite/time_entry_test.go b/mite/time_entry_test.go index afda63a..0234703 100644 --- a/mite/time_entry_test.go +++ b/mite/time_entry_test.go @@ -188,7 +188,7 @@ func TestApi_CreateTimeEntry(t *testing.T) { assert.Equal(t, "application/json", rec.RequestContentType()) assert.Equal(t, testUserAgent, rec.RequestUserAgent()) assert.Equal(t, testApiKey, rec.RequestMiteKey()) - assert.Equal(t, timeEntryRequest, string(prettifyJson(rec.RequestBody(), " "))) + assert.Equal(t, CanonicalString(timeEntryRequest), rec.RequestBodyCanonical()) } func TestApi_EditTimeEntry(t *testing.T) { @@ -219,7 +219,7 @@ func TestApi_EditTimeEntry(t *testing.T) { assert.Equal(t, "application/json", rec.RequestContentType()) assert.Equal(t, testUserAgent, rec.RequestUserAgent()) assert.Equal(t, testApiKey, rec.RequestMiteKey()) - assert.Equal(t, timeEntryRequest, string(prettifyJson(rec.RequestBody(), " "))) + assert.Equal(t, CanonicalString(timeEntryRequest), rec.RequestBodyCanonical()) } func TestApi_DeleteTimeEntry(t *testing.T) { diff --git a/mite/tracker_test.go b/mite/tracker_test.go index a9c7bf0..c23cf04 100644 --- a/mite/tracker_test.go +++ b/mite/tracker_test.go @@ -139,7 +139,7 @@ func TestApi_StartTracker(t *testing.T) { assert.Equal(t, "application/json", rec.RequestContentType()) assert.Equal(t, testUserAgent, rec.RequestUserAgent()) assert.Equal(t, testApiKey, rec.RequestMiteKey()) - assert.Equal(t, "{}", string(prettifyJson(rec.RequestBody(), ""))) + assert.Equal(t, `{}`, rec.RequestBodyCanonical()) } func TestApi_StartTracker_Running(t *testing.T) { @@ -168,7 +168,7 @@ func TestApi_StartTracker_Running(t *testing.T) { assert.Equal(t, "application/json", rec.RequestContentType()) assert.Equal(t, testUserAgent, rec.RequestUserAgent()) assert.Equal(t, testApiKey, rec.RequestMiteKey()) - assert.Equal(t, "{}", string(prettifyJson(rec.RequestBody(), ""))) + assert.Equal(t, `{}`, rec.RequestBodyCanonical()) } func TestApi_StopTracker(t *testing.T) {