mirror of https://github.com/grafana/grafana.git
74 lines
1.9 KiB
Go
74 lines
1.9 KiB
Go
|
|
package webtest
|
||
|
|
|
||
|
|
import (
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
|
||
|
|
"github.com/grafana/grafana/pkg/web"
|
||
|
|
)
|
||
|
|
|
||
|
|
type Context struct {
|
||
|
|
Req *http.Request
|
||
|
|
Rw http.ResponseWriter
|
||
|
|
Next http.Handler
|
||
|
|
}
|
||
|
|
|
||
|
|
// Middleware is a utility for testing middlewares
|
||
|
|
type Middleware struct {
|
||
|
|
// Before are run ahead of the returned context
|
||
|
|
Before []web.Handler
|
||
|
|
// After are part of the http.Handler chain
|
||
|
|
After []web.Handler
|
||
|
|
// The actual handler at the end of the chain
|
||
|
|
Handler web.Handler
|
||
|
|
}
|
||
|
|
|
||
|
|
// MiddlewareContext returns a *http.Request, http.ResponseWriter and http.Handler
|
||
|
|
// exactly as if it was passed to a middleware
|
||
|
|
func MiddlewareContext(test Middleware, req *http.Request) *Context {
|
||
|
|
m := web.New()
|
||
|
|
|
||
|
|
// pkg/web requires the chain to write an HTTP response.
|
||
|
|
// While this ensures a basic amount of correctness for real handler chains,
|
||
|
|
// it is naturally incompatible with this package, as we terminate the chain early to pass its
|
||
|
|
// state to the surrounding test.
|
||
|
|
// By replacing the http.ResponseWriter and writing to the old one we make pkg/web happy.
|
||
|
|
m.Use(func(next http.Handler) http.Handler {
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
w.WriteHeader(http.StatusOK)
|
||
|
|
|
||
|
|
rw := web.Rw(httptest.NewRecorder(), r)
|
||
|
|
next.ServeHTTP(rw, r)
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
for _, mw := range test.Before {
|
||
|
|
m.Use(mw)
|
||
|
|
}
|
||
|
|
|
||
|
|
ch := make(chan *Context)
|
||
|
|
m.Use(func(next http.Handler) http.Handler {
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
ch <- &Context{
|
||
|
|
Req: r,
|
||
|
|
Rw: w,
|
||
|
|
Next: next,
|
||
|
|
}
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
for _, mw := range test.After {
|
||
|
|
m.Use(mw)
|
||
|
|
}
|
||
|
|
|
||
|
|
// set the provided (or noop) handler to exactly the queried path
|
||
|
|
handler := test.Handler
|
||
|
|
if handler == nil {
|
||
|
|
handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||
|
|
}
|
||
|
|
m.Handle(req.Method, req.URL.RequestURI(), []web.Handler{handler})
|
||
|
|
go m.ServeHTTP(httptest.NewRecorder(), req)
|
||
|
|
|
||
|
|
return <-ch
|
||
|
|
}
|