From e7619238ae9008b3a7634e69740768fe520d103f Mon Sep 17 00:00:00 2001 From: pancho horrillo Date: Tue, 19 Nov 2019 20:26:00 +0100 Subject: [PATCH] Add GetReasonFromBody() that extracts reason from JSON --- internal/http/reason.go | 24 +++++++++++ internal/http/reason_test.go | 82 ++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/internal/http/reason.go b/internal/http/reason.go index 89d8732..7851d5f 100644 --- a/internal/http/reason.go +++ b/internal/http/reason.go @@ -17,8 +17,13 @@ package http import ( + "encoding/json" + "errors" + "io/ioutil" "net/http" "strings" + + "github.com/BBVA/kapow/internal/server/srverrors" ) // GetReason returns the reason phrase part of an HTTP response @@ -28,3 +33,22 @@ func GetReason(r *http.Response) string { } return "" } + +func GetReasonFromBody(r *http.Response) (string, error) { + body, err := ioutil.ReadAll(r.Body) + if err != nil { + return "", errors.New("error reading response's body") + } + + reason := &srverrors.ServerErrMessage{} + err = json.Unmarshal(body, reason) + if err != nil { + return "", errors.New("error unmarshaling JSON") + } + + if reason.Reason == "" { + return "", errors.New("no reason") + } + + return reason.Reason, nil +} diff --git a/internal/http/reason_test.go b/internal/http/reason_test.go index aa17b93..6281fad 100644 --- a/internal/http/reason_test.go +++ b/internal/http/reason_test.go @@ -17,7 +17,9 @@ package http import ( + "io/ioutil" nethttp "net/http" + "strings" "testing" ) @@ -62,3 +64,83 @@ func TestBehaveWithOddSizeStatusCode(t *testing.T) { t.Errorf("Unexpected reason found") } } + +func TestGetReasonFromBodyExtractsReasonFromJSON(t *testing.T) { + r := &nethttp.Response{ + Status: "200 OK", + Body: ioutil.NopCloser( + strings.NewReader( + `{"reason": "Because reasons", "foo": "bar"}`, + ), + ), + } + + reason, _ := GetReasonFromBody(r) + + if reason != "Because reasons" { + t.Errorf(`reason mismatch, want "Because reasons", got %q`, reason) + } +} + +func TestGetReasonFromBodyErrorsOnJSONWithNoReason(t *testing.T) { + r := &nethttp.Response{ + Status: "200 OK", + Body: ioutil.NopCloser( + strings.NewReader( + `{"madness": "Because madness", "foo": "bar"}`, + ), + ), + } + + _, err := GetReasonFromBody(r) + + if err == nil { + t.Error("error not reported") + } +} + +func TestGetReasonFromBodyErrorsOnJSONWithEmptyReason(t *testing.T) { + r := &nethttp.Response{ + Body: ioutil.NopCloser( + strings.NewReader( + `{"reason": "", "foo": "bar"}`, + ), + ), + } + + _, err := GetReasonFromBody(r) + + if err == nil { + t.Error("error not reported") + } +} + +func TestGetReasonFromBodyErrorsOnNoJSON(t *testing.T) { + r := &nethttp.Response{ + Body: ioutil.NopCloser( + strings.NewReader(""), + ), + } + + _, err := GetReasonFromBody(r) + + if err == nil { + t.Error("error not reported") + } +} + +func TestGetReasonFromBodyErrorsOnInvalidJSON(t *testing.T) { + r := &nethttp.Response{ + Body: ioutil.NopCloser( + strings.NewReader( + `{"reason": "Because reasons", "cliffhanger...`, + ), + ), + } + + _, err := GetReasonFromBody(r) + + if err == nil { + t.Error("error not reported") + } +}