From 5d9b1725489692e5282cc8261bc6b8ca0befd34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20Soul=C3=A9?= Date: Sat, 4 Feb 2023 21:27:58 +0100 Subject: [PATCH] test: increase coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime Soulé --- tdhttpmock.go | 6 +- tdhttpmock_test.go | 218 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 222 insertions(+), 2 deletions(-) diff --git a/tdhttpmock.go b/tdhttpmock.go index 58f5445..fab432d 100644 --- a/tdhttpmock.go +++ b/tdhttpmock.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022, Maxime Soulé +// Copyright (c) 2022-2023, Maxime Soulé // All rights reserved. // // This source code is licensed under the BSD-style license found in the @@ -18,6 +18,10 @@ import ( "github.com/maxatome/go-testdeep/td" ) +func init() { + httpmock.IgnoreMatcherHelper() +} + var interfaceType = reflect.TypeOf((*any)(nil)).Elem() func marshaledBody( diff --git a/tdhttpmock_test.go b/tdhttpmock_test.go index 998e437..161d8e1 100644 --- a/tdhttpmock_test.go +++ b/tdhttpmock_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022, Maxime Soulé +// Copyright (c) 2022-2023, Maxime Soulé // All rights reserved. // // This source code is licensed under the BSD-style license found in the @@ -18,6 +18,10 @@ import ( "github.com/maxatome/tdhttpmock" ) +func TestMatcherName(t *testing.T) { + td.Cmp(t, tdhttpmock.Body(td.Empty()).Name(), td.Re(`/tdhttpmock_test.go:\d+$`)) +} + func TestBodyHeader(t *testing.T) { httpmock.Activate() defer httpmock.DeactivateAndReset() @@ -133,3 +137,215 @@ func TestBodyHeader(t *testing.T) { assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-70"))) }) } + +func TestJSONBody(t *testing.T) { + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterNoResponder(httpmock.NewStringResponder(404, "Not found")) + + httpmock.RegisterMatcherResponder( + http.MethodPost, + "/test", + tdhttpmock.JSONBody(td.SuperJSONOf(`{"name":"bob"}`)).WithName("20-body"), + httpmock.NewStringResponder(200, "OK-20"), + ) + + httpmock.RegisterMatcherResponder( + http.MethodPost, + "/test", + tdhttpmock.JSONBody(td.SuperJSONOf(`{"age":23}`)).WithName("10-body"), + httpmock.NewStringResponder(200, "OK-10"), + ) + + assert := td.Assert(t) + + assert.RunAssertRequire("20-body", func(assert, require *td.T) { + resp, err := http.Post("/test", "application/json", + strings.NewReader(`{"name":"bob","age":66}`)) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 200) + assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-20"))) + }) + + assert.RunAssertRequire("10-body", func(assert, require *td.T) { + resp, err := http.Post("/test", "application/json", + strings.NewReader(`{"name":"bob","age":23}`)) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 200) + assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-10"))) + }) + + assert.RunAssertRequire("no match", func(assert, require *td.T) { + resp, err := http.Post("/test", "application/json", + strings.NewReader(`{"name":"alice","age":32}`)) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 404) + }) + + assert.RunAssertRequire("empty", func(assert, require *td.T) { + resp, err := http.Post("/test", "", nil) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 404) + }) +} + +func TestXMLBody(t *testing.T) { + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + type XBody struct { + Name string `xml:"name"` + Age int `xml:"age"` + } + + httpmock.RegisterNoResponder(httpmock.NewStringResponder(404, "Not found")) + + httpmock.RegisterMatcherResponder( + http.MethodPost, + "/test", + tdhttpmock.XMLBody(td.Struct(XBody{Name: "bob"}, nil)).WithName("20-body"), + httpmock.NewStringResponder(200, "OK-20"), + ) + + httpmock.RegisterMatcherResponder( + http.MethodPost, + "/test", + tdhttpmock.XMLBody(td.Struct(XBody{Age: 23}, nil)).WithName("10-body"), + httpmock.NewStringResponder(200, "OK-10"), + ) + + assert := td.Assert(t) + + assert.RunAssertRequire("20-body", func(assert, require *td.T) { + resp, err := http.Post("/test", "application/xml", + strings.NewReader(`bob66`)) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 200) + assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-20"))) + }) + + assert.RunAssertRequire("10-body", func(assert, require *td.T) { + resp, err := http.Post("/test", "application/xml", + strings.NewReader(`bob23`)) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 200) + assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-10"))) + }) + + assert.RunAssertRequire("no match", func(assert, require *td.T) { + resp, err := http.Post("/test", "application/xml", + strings.NewReader(`alice32`)) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 404) + }) + + assert.RunAssertRequire("empty", func(assert, require *td.T) { + resp, err := http.Post("/test", "", nil) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 404) + }) +} + +func TestCookies(t *testing.T) { + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterNoResponder(httpmock.NewStringResponder(404, "Not found")) + + httpmock.RegisterMatcherResponder( + http.MethodGet, + "/test", + tdhttpmock.Cookies([]*http.Cookie{ + {Name: "first", Value: "cookie1"}, + {Name: "second", Value: "cookie2"}, + }).WithName("20-cookies"), + httpmock.NewStringResponder(200, "OK-20"), + ) + + httpmock.RegisterMatcherResponder( + http.MethodGet, + "/test", + tdhttpmock.Cookies(td.Bag( + &http.Cookie{Name: "first", Value: "cookie1"}, + &http.Cookie{Name: "third", Value: "cookie3"}, + )).WithName("10-cookies"), + httpmock.NewStringResponder(200, "OK-10"), + ) + + httpmock.RegisterMatcherResponder( + http.MethodGet, + "/test", + tdhttpmock.Cookies(td.SuperBagOf( + &http.Cookie{Name: "third", Value: "cookie3"}, + )).WithName("30-cookies"), + httpmock.NewStringResponder(200, "OK-30"), + ) + + setCookie := func(req *http.Request, cookie *http.Cookie) { + if v := cookie.String(); v != "" { + req.Header.Add("Cookie", v) + } + } + + assert := td.Assert(t) + + assert.RunAssertRequire("20-cookies", func(assert, require *td.T) { + req, err := http.NewRequest("GET", "/test", nil) + require.CmpNoError(err) + + setCookie(req, &http.Cookie{Name: "first", Value: "cookie1"}) + setCookie(req, &http.Cookie{Name: "second", Value: "cookie2"}) + + resp, err := http.DefaultClient.Do(req) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 200) + assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-20"))) + }) + + assert.RunAssertRequire("10-cookies", func(assert, require *td.T) { + req, err := http.NewRequest("GET", "/test", nil) + require.CmpNoError(err) + + setCookie(req, &http.Cookie{Name: "third", Value: "cookie3"}) + setCookie(req, &http.Cookie{Name: "first", Value: "cookie1"}) + + resp, err := http.DefaultClient.Do(req) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 200) + assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-10"))) + }) + + assert.RunAssertRequire("30-cookies", func(assert, require *td.T) { + req, err := http.NewRequest("GET", "/test", nil) + require.CmpNoError(err) + + setCookie(req, &http.Cookie{Name: "third", Value: "cookie3"}) + setCookie(req, &http.Cookie{Name: "another", Value: "cookieX"}) + + resp, err := http.DefaultClient.Do(req) + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 200) + assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-30"))) + }) + + assert.RunAssertRequire("no cookies", func(assert, require *td.T) { + resp, err := http.Get("/test") + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 404) + }) + + httpmock.RegisterMatcherResponder( + http.MethodGet, + "/test", + tdhttpmock.Cookies(td.Empty()).WithName("NO-cookies"), + httpmock.NewStringResponder(200, "OK-NO"), + ) + + assert.RunAssertRequire("catch no cookies", func(assert, require *td.T) { + resp, err := http.Get("/test") + require.CmpNoError(err) + assert.Cmp(resp.StatusCode, 200) + assert.Cmp(resp.Body, td.Smuggle(ioutil.ReadAll, td.String("OK-NO"))) + }) +}