feat: import jsteenb2/testttp directly into pkg
parent
b1749ce257
commit
f6dbfec346
1
go.mod
1
go.mod
|
@ -44,7 +44,6 @@ require (
|
|||
github.com/influxdata/influxql v0.0.0-20180925231337-1cbfca8e56b6
|
||||
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368
|
||||
github.com/jessevdk/go-flags v1.4.0
|
||||
github.com/jsteenb2/testttp v0.0.0-20191106182320-3a9029951f41
|
||||
github.com/jsternberg/zap-logfmt v1.2.0
|
||||
github.com/julienschmidt/httprouter v1.2.0
|
||||
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef
|
||||
|
|
6
go.sum
6
go.sum
|
@ -239,10 +239,10 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
|
|||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/changelog v1.1.0 h1:HXhmLZDrbuC+Ca5YX7g8B8cH5DmJpaOjd844d9Y7aTQ=
|
||||
github.com/influxdata/changelog v1.1.0/go.mod h1:uzpGWE/qehT8L426YuXwpMQub+a63vIINhIeEI9mnSM=
|
||||
github.com/influxdata/flux v0.54.0 h1:DjAkGoPkgHLDPEn1jSuOpsH4QgcjmSBkRuxSAaQCj1Q=
|
||||
github.com/influxdata/flux v0.54.0/go.mod h1:ZFf4F0c8ACFP/5BkfCwk9I/vUwcByr0vMdLxwgOk57E=
|
||||
github.com/influxdata/cron v0.0.0-20191112133922-ad5847cfab62 h1:YipnPuvJKPAzyBhr7eXIMA49L2Eooga/NSytWdLLI8U=
|
||||
github.com/influxdata/cron v0.0.0-20191112133922-ad5847cfab62/go.mod h1:XabtPPW2qsCg0tl+kjaPU+cFS+CjQXEXbT1VJvHT4og=
|
||||
github.com/influxdata/flux v0.54.0 h1:DjAkGoPkgHLDPEn1jSuOpsH4QgcjmSBkRuxSAaQCj1Q=
|
||||
github.com/influxdata/flux v0.54.0/go.mod h1:ZFf4F0c8ACFP/5BkfCwk9I/vUwcByr0vMdLxwgOk57E=
|
||||
github.com/influxdata/goreleaser v0.97.0-influx h1:jT5OrcW7WfS0e2QxfwmTBjhLvpIC9CDLRhNgZJyhj8s=
|
||||
github.com/influxdata/goreleaser v0.97.0-influx/go.mod h1:MnjA0e0Uq6ISqjG1WxxMAl+3VS1QYjILSWVnMYDxasE=
|
||||
github.com/influxdata/influxql v0.0.0-20180925231337-1cbfca8e56b6 h1:CFx+pP90q/qg3spoiZjf8donE4WpAdjeJfPOcoNqkWo=
|
||||
|
@ -262,8 +262,6 @@ github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht
|
|||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jsteenb2/testttp v0.0.0-20191106182320-3a9029951f41 h1:x4CmjEFDJd2LVNwfd35xxBsNHOySHAeTzdZuwV/CuXs=
|
||||
github.com/jsteenb2/testttp v0.0.0-20191106182320-3a9029951f41/go.mod h1:Bpl/IMLYUekm9vMu/EA8SwzUtmH+rGBPKeY4xLswom8=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jsternberg/zap-logfmt v1.2.0 h1:1v+PK4/B48cy8cfQbxL4FmmNZrjnIMr2BsnyEmXqv2o=
|
||||
github.com/jsternberg/zap-logfmt v1.2.0/go.mod h1:kz+1CUmCutPWABnNkOu9hOHKdT2q3TDYCcsFy9hpqb0=
|
||||
|
|
|
@ -12,8 +12,8 @@ import (
|
|||
"github.com/influxdata/influxdb"
|
||||
fluxTTP "github.com/influxdata/influxdb/http"
|
||||
"github.com/influxdata/influxdb/mock"
|
||||
"github.com/influxdata/influxdb/pkg/testttp"
|
||||
"github.com/influxdata/influxdb/pkger"
|
||||
"github.com/jsteenb2/testttp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
package testttp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Req is a request builder.
|
||||
type Req struct {
|
||||
addr string
|
||||
method string
|
||||
body io.Reader
|
||||
headers []string
|
||||
}
|
||||
|
||||
// HTTP runs creates a request for an http call.
|
||||
func HTTP(method, addr string, body io.Reader) *Req {
|
||||
return &Req{
|
||||
addr: addr,
|
||||
method: method,
|
||||
body: body,
|
||||
}
|
||||
}
|
||||
|
||||
// Delete creates a DELETE request.
|
||||
func Delete(addr string) *Req {
|
||||
return HTTP(http.MethodDelete, addr, nil)
|
||||
}
|
||||
|
||||
// Get creates a GET request.
|
||||
func Get(addr string) *Req {
|
||||
return HTTP(http.MethodGet, addr, nil)
|
||||
}
|
||||
|
||||
// Patch creates a PATCH request.
|
||||
func Patch(addr string, body io.Reader) *Req {
|
||||
return HTTP(http.MethodPatch, addr, body)
|
||||
}
|
||||
|
||||
// Post creates a POST request.
|
||||
func Post(addr string, body io.Reader) *Req {
|
||||
return HTTP(http.MethodPost, addr, body)
|
||||
}
|
||||
|
||||
// Put creates a PUT request.
|
||||
func Put(addr string, body io.Reader) *Req {
|
||||
return HTTP(http.MethodPut, addr, body)
|
||||
}
|
||||
|
||||
// Headers allows the user to set headers on the http request.
|
||||
func (r *Req) Headers(k, v string, rest ...string) *Req {
|
||||
r.headers = append(r.headers, k, v)
|
||||
r.headers = append(r.headers, rest...)
|
||||
return r
|
||||
}
|
||||
|
||||
// Do runs the request against the provided handler.
|
||||
func (r *Req) Do(handler http.Handler) *Resp {
|
||||
req := httptest.NewRequest(r.method, r.addr, r.body)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
for i := 0; i < len(r.headers); i += 2 {
|
||||
if i+1 >= len(r.headers) {
|
||||
break
|
||||
}
|
||||
k, v := r.headers[i], r.headers[i+1]
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
return &Resp{
|
||||
Req: req,
|
||||
Rec: rec,
|
||||
}
|
||||
}
|
||||
|
||||
// Resp is a http recorder wrapper.
|
||||
type Resp struct {
|
||||
Req *http.Request
|
||||
Rec *httptest.ResponseRecorder
|
||||
}
|
||||
|
||||
// Expect allows the assertions against the raw Resp.
|
||||
func (r *Resp) Expect(fn func(*Resp)) *Resp {
|
||||
fn(r)
|
||||
return r
|
||||
}
|
||||
|
||||
// ExpectStatus compares the expected status code against the recorded status code.
|
||||
func (r *Resp) ExpectStatus(t *testing.T, code int) *Resp {
|
||||
t.Helper()
|
||||
|
||||
if r.Rec.Code != code {
|
||||
t.Errorf("unexpected status code: expected=%d got=%d", code, r.Rec.Code)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ExpectBody provides an assertion against the recorder body.
|
||||
func (r *Resp) ExpectBody(fn func(*bytes.Buffer)) *Resp {
|
||||
fn(r.Rec.Body)
|
||||
return r
|
||||
}
|
||||
|
||||
// ExpectHeader asserts that the header is in the recorder.
|
||||
func (r *Resp) ExpectHeader(t *testing.T, k, v string) *Resp {
|
||||
t.Helper()
|
||||
|
||||
vals, ok := r.Rec.Header()[k]
|
||||
if !ok {
|
||||
t.Errorf("did not find expected header: %q", k)
|
||||
return r
|
||||
}
|
||||
|
||||
for _, vv := range vals {
|
||||
if vv == v {
|
||||
return r
|
||||
}
|
||||
}
|
||||
t.Errorf("did not find expected value for header %q; got: %v", k, vals)
|
||||
|
||||
return r
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package testttp_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/influxdb/pkg/testttp"
|
||||
)
|
||||
|
||||
func TestHTTP(t *testing.T) {
|
||||
svr := newMux()
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
testttp.Get("/").
|
||||
Do(svr).
|
||||
ExpectStatus(t, http.StatusOK).
|
||||
ExpectBody(assertBody(t, http.MethodGet))
|
||||
})
|
||||
|
||||
t.Run("Post", func(t *testing.T) {
|
||||
testttp.Post("/", nil).Do(svr).
|
||||
ExpectStatus(t, http.StatusCreated).
|
||||
ExpectBody(assertBody(t, http.MethodPost))
|
||||
})
|
||||
|
||||
t.Run("Put", func(t *testing.T) {
|
||||
testttp.Put("/", nil).
|
||||
Do(svr).
|
||||
ExpectStatus(t, http.StatusAccepted).
|
||||
ExpectBody(assertBody(t, http.MethodPut))
|
||||
})
|
||||
|
||||
t.Run("Patch", func(t *testing.T) {
|
||||
testttp.Patch("/", nil).
|
||||
Do(svr).
|
||||
ExpectStatus(t, http.StatusPartialContent).
|
||||
ExpectBody(assertBody(t, http.MethodPatch))
|
||||
})
|
||||
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
testttp.Delete("/").
|
||||
Do(svr).
|
||||
ExpectStatus(t, http.StatusNoContent)
|
||||
})
|
||||
|
||||
t.Run("Headers", func(t *testing.T) {
|
||||
testttp.Post("/", strings.NewReader(`a: foo`)).
|
||||
Headers("Content-Type", "text/yml").
|
||||
Do(svr).
|
||||
Expect(func(resp *testttp.Resp) {
|
||||
equals(t, "text/yml", resp.Req.Header.Get("Content-Type"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
type foo struct {
|
||||
Name, Thing, Method string
|
||||
}
|
||||
|
||||
func newMux() http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
|
||||
switch req.Method {
|
||||
case http.MethodGet:
|
||||
writeFn(w, req.Method, http.StatusOK)
|
||||
case http.MethodPost:
|
||||
writeFn(w, req.Method, http.StatusCreated)
|
||||
case http.MethodPut:
|
||||
writeFn(w, req.Method, http.StatusAccepted)
|
||||
case http.MethodPatch:
|
||||
writeFn(w, req.Method, http.StatusPartialContent)
|
||||
case http.MethodDelete:
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
})
|
||||
return mux
|
||||
}
|
||||
|
||||
func assertBody(t *testing.T, method string) func(*bytes.Buffer) {
|
||||
return func(buf *bytes.Buffer) {
|
||||
var f foo
|
||||
if err := json.NewDecoder(buf).Decode(&f); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected := foo{Name: "name", Thing: "thing", Method: method}
|
||||
equals(t, expected, f)
|
||||
}
|
||||
}
|
||||
|
||||
func writeFn(w http.ResponseWriter, method string, statusCode int) {
|
||||
f := foo{Name: "name", Thing: "thing", Method: method}
|
||||
r, err := encodeBuf(f)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
if _, err := io.Copy(w, r); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func equals(t *testing.T, expected, actual interface{}) {
|
||||
t.Helper()
|
||||
if expected == actual {
|
||||
return
|
||||
}
|
||||
t.Errorf("expected: %v\tactual: %v", expected, actual)
|
||||
}
|
||||
|
||||
func encodeBuf(v interface{}) (io.Reader, error) {
|
||||
var buf bytes.Buffer
|
||||
if err := json.NewEncoder(&buf).Encode(v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &buf, nil
|
||||
}
|
Loading…
Reference in New Issue