From 18d66734a6516aeab2574d9622d4d07c42564750 Mon Sep 17 00:00:00 2001 From: Kyle-Cooley <41492133+Kyle-Cooley@users.noreply.github.com> Date: Thu, 27 Jul 2023 04:02:49 -0500 Subject: [PATCH] Read Body for Newer Responses in HaveHTTPBodyMatcher (#686) --- matchers/have_http_body_matcher.go | 9 ++++++--- matchers/have_http_body_matcher_test.go | 27 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/matchers/have_http_body_matcher.go b/matchers/have_http_body_matcher.go index 6a3dcdc35..d14d9e5fc 100644 --- a/matchers/have_http_body_matcher.go +++ b/matchers/have_http_body_matcher.go @@ -11,8 +11,9 @@ import ( ) type HaveHTTPBodyMatcher struct { - Expected interface{} - cachedBody []byte + Expected interface{} + cachedResponse interface{} + cachedBody []byte } func (matcher *HaveHTTPBodyMatcher) Match(actual interface{}) (bool, error) { @@ -73,7 +74,7 @@ func (matcher *HaveHTTPBodyMatcher) NegatedFailureMessage(actual interface{}) (m // the Reader is closed and it is not readable again in FailureMessage() // or NegatedFailureMessage() func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) { - if matcher.cachedBody != nil { + if matcher.cachedResponse == actual && matcher.cachedBody != nil { return matcher.cachedBody, nil } @@ -91,8 +92,10 @@ func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) { switch a := actual.(type) { case *http.Response: + matcher.cachedResponse = a return body(a) case *httptest.ResponseRecorder: + matcher.cachedResponse = a return body(a.Result()) default: return nil, fmt.Errorf("HaveHTTPBody matcher expects *http.Response or *httptest.ResponseRecorder. Got:\n%s", format.Object(actual, 1)) diff --git a/matchers/have_http_body_matcher_test.go b/matchers/have_http_body_matcher_test.go index 926d6a5e5..8fd3e3d7a 100644 --- a/matchers/have_http_body_matcher_test.go +++ b/matchers/have_http_body_matcher_test.go @@ -2,6 +2,7 @@ package matchers_test import ( "bytes" + "io" "net/http" "net/http/httptest" "strings" @@ -24,6 +25,19 @@ var _ = Describe("HaveHTTPBody", func() { resp := &http.Response{Body: gutil.NopCloser(strings.NewReader(body))} Expect(resp).NotTo(HaveHTTPBody("something else")) }) + + It("matches the body against later calls", func() { + firstCall := true + getResp := func() *http.Response { + if firstCall { + firstCall = false + return &http.Response{Body: io.NopCloser(strings.NewReader("first_call"))} + } else { + return &http.Response{Body: io.NopCloser(strings.NewReader("later_call"))} + } + } + Eventually(getResp).MustPassRepeatedly(2).Should(HaveHTTPBody([]byte("later_call"))) + }) }) When("ACTUAL is *httptest.ResponseRecorder", func() { @@ -38,6 +52,19 @@ var _ = Describe("HaveHTTPBody", func() { resp := &httptest.ResponseRecorder{Body: bytes.NewBufferString(body)} Expect(resp).NotTo(HaveHTTPBody("something else")) }) + + It("matches the body against later calls", func() { + firstCall := true + getResp := func() *httptest.ResponseRecorder { + if firstCall { + firstCall = false + return &httptest.ResponseRecorder{Body: bytes.NewBufferString("first_call")} + } else { + return &httptest.ResponseRecorder{Body: bytes.NewBufferString("later_call")} + } + } + Eventually(getResp).MustPassRepeatedly(2).Should(HaveHTTPBody([]byte("later_call"))) + }) }) When("ACTUAL is neither *http.Response nor *httptest.ResponseRecorder", func() {