Skip to content

Commit

Permalink
fix: BodyContainsBytes & BodyContainsString used with And/Or
Browse files Browse the repository at this point in the history
Both "rearm" the body before (re-)reading it, so they can be used
several times in a same matcher (combined with Or & And).

Closes #145.

Signed-off-by: Maxime Soulé <btik-git@scoubidou.com>
  • Loading branch information
maxatome committed Jul 20, 2023
1 parent 070d3c8 commit b654aef
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
6 changes: 6 additions & 0 deletions match.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ func NewMatcher(name string, fn MatcherFunc) Matcher {
func BodyContainsBytes(subslice []byte) Matcher {
return NewMatcher("",
func(req *http.Request) bool {
if body, ok := req.Body.(*bodyCopyOnRead); ok {
body.rearm()
}
b, err := ioutil.ReadAll(req.Body)
return err == nil && bytes.Contains(b, subslice)
})
Expand All @@ -243,6 +246,9 @@ func BodyContainsBytes(subslice []byte) Matcher {
func BodyContainsString(substr string) Matcher {
return NewMatcher("",
func(req *http.Request) bool {
if body, ok := req.Body.(*bodyCopyOnRead); ok {
body.rearm()
}
b, err := ioutil.ReadAll(req.Body)
return err == nil && bytes.Contains(b, []byte(substr))
})
Expand Down
12 changes: 12 additions & 0 deletions match_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,30 @@ func TestNewMatcher(t *testing.T) {
return req
}

reqCopyBody := func(t testing.TB, body string, header ...string) *http.Request {
req := req(t, body, header...)
req.Body = httpmock.NewBodyCopyOnRead(req.Body)
return req
}

t.Run("BodyContainsBytes", func(t *testing.T) {
m := httpmock.BodyContainsBytes([]byte("ip"))
td.Cmp(t, m.Name(), autogenName)
td.CmpTrue(t, m.Check(req(t, "pipo")))
td.CmpFalse(t, m.Check(req(t, "bingo")))

td.CmpTrue(t, m.Check(reqCopyBody(t, "pipo")))
td.CmpFalse(t, m.Check(reqCopyBody(t, "bingo")))
})

t.Run("BodyContainsString", func(t *testing.T) {
m := httpmock.BodyContainsString("ip")
td.Cmp(t, m.Name(), autogenName)
td.CmpTrue(t, m.Check(req(t, "pipo")))
td.CmpFalse(t, m.Check(req(t, "bingo")))

td.CmpTrue(t, m.Check(reqCopyBody(t, "pipo")))
td.CmpFalse(t, m.Check(reqCopyBody(t, "bingo")))
})

t.Run("HeaderExists", func(t *testing.T) {
Expand Down
21 changes: 19 additions & 2 deletions transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ func TestRegisterMatcherResponder(t *testing.T) {
}),
NewStringResponder(200, "body-FOO"))

RegisterMatcherResponder("POST", "/foo",
BodyContainsString("xxx").
Or(BodyContainsString("yyy")).
WithName("03-body-xxx|yyy"),
NewStringResponder(200, "body-xxx|yyy"))

RegisterResponder("POST", "/foo", NewStringResponder(200, "default"))

RegisterNoResponder(NewNotFoundResponder(nil))
Expand Down Expand Up @@ -156,6 +162,16 @@ func TestRegisterMatcherResponder(t *testing.T) {
body: "FOO",
expectedBody: "body-FOO",
},
{
name: "body xxx",
body: "...xxx...",
expectedBody: "body-xxx|yyy",
},
{
name: "body yyy",
body: "...yyy...",
expectedBody: "body-xxx|yyy",
},
{
name: "default",
body: "ANYTHING",
Expand Down Expand Up @@ -194,12 +210,13 @@ func TestRegisterMatcherResponder(t *testing.T) {
"text/plain",
strings.NewReader("ANYTHING"),
)
assert.HasSuffix(err, `Responder not found for POST http://test.com/foo despite 3 matchers: ["00-header-foo=bar" "01-body-BAR" "02-body-FOO"]`)
assert.HasSuffix(err, `Responder not found for POST http://test.com/foo despite 4 matchers: ["00-header-foo=bar" "01-body-BAR" "02-body-FOO" "03-body-xxx|yyy"]`)
})

// Remove 2 matcher responders
// Remove 3 matcher responders
RegisterMatcherResponder("POST", "/foo", NewMatcher("01-body-BAR", nil), nil)
RegisterMatcherResponder("POST", "/foo", NewMatcher("02-body-FOO", nil), nil)
RegisterMatcherResponder("POST", "/foo", NewMatcher("03-body-xxx|yyy", nil), nil)

assert.Run("not found despite 1", func(assert *td.T) {
_, err := http.Post(
Expand Down

0 comments on commit b654aef

Please sign in to comment.