func TestUse(t *testing.T) { is := is.New(t) n := noodle.New(mwFactory("A"), mwFactory("B")).Use(mwFactory("C")).Then(handlerFactory("H1", "VarA", "VarB", "VarC")) res := RunHTTP(n) is.Equal("A>B>C>H1 [VarA=Avalue][VarB=Bvalue][VarC=Cvalue]", res) }
// Group starts new route group with common prefix. // Middleware passed to Group will be used for all routes in it. func (wok *Wok) Group(prefix string, mws ...noodle.Middleware) *Wok { return &Wok{ prefix: prefix, parent: wok, Router: wok.Router, chain: noodle.New(mws...), } }
func TestThen(t *testing.T) { is := is.New(t) h := noodle.New().Then(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { fmt.Fprintf(w, "Abracadabra") return nil }) is.Equal("Abracadabra", RunHTTP(h)) }
func TestRecover(t *testing.T) { is := is.New(t) n := noodle.New(mw.Recover).Then(panickyHandler) r, _ := http.NewRequest("GET", "http://localhost", nil) err := n(context.TODO(), httptest.NewRecorder(), r) is.Equal(err.Error(), "panic: whoopsie!") _, ok := err.(mw.RecoverError) is.True(ok) }
// Handle allows to attach some noodle Middlewares and a Handle to a route func (wok *Wok) Handle(method, path string, mws ...noodle.Middleware) RouteClosure { chain := noodle.New(mws...) for router := wok; router != nil; router = router.parent { chain = router.chain.Use(chain...) path = UrlJoin(router.prefix, path) } return func(h noodle.Handler) { h = chain.Then(h) wok.Router.Handle(method, path, wok.convert(h)) } }
func TestStore(t *testing.T) { is := is.New(t) n := noodle.New(mw.LocalStore).Then( func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { s := mw.GetStore(ctx) is.NotNil(s) return nil }, ) r, _ := http.NewRequest("GET", "http://localhost", nil) _ = n(context.TODO(), httptest.NewRecorder(), r) }
func TestBindJSON(t *testing.T) { is := is.New(t) buf := bytes.NewBuffer([]byte(`{"a": 1, "b": "Ololo"}`)) emptyBuf := bytes.NewBuffer([]byte{}) n := noodle.New(bind.JSON(TestStruct{})).Then(bindHandlerFactory(is)) r, _ := http.NewRequest("POST", "http://localhost", buf) is.NotErr(n(context.TODO(), httptest.NewRecorder(), r)) r, _ = http.NewRequest("POST", "http://localhost", emptyBuf) is.Err(n(context.TODO(), httptest.NewRecorder(), r)) }
func TestBindForm(t *testing.T) { is := is.New(t) testForm, _ := form.EncodeToString(TestStruct{1, "Ololo"}) buf := bytes.NewBuffer([]byte(testForm)) emptyBuf := bytes.NewBuffer([]byte("alskdjasdklj")) n := noodle.New(bind.Form(TestStruct{})).Then(bindHandlerFactory(is)) r, _ := http.NewRequest("POST", "http://localhost", buf) is.NotErr(n(context.TODO(), httptest.NewRecorder(), r)) r, _ = http.NewRequest("POST", "http://localhost", emptyBuf) is.Err(n(context.TODO(), httptest.NewRecorder(), r)) }
func TestHttpErrorPropagates(t *testing.T) { is := is.New(t) testError := errors.New("test error") n := noodle.New(noodleMW, adapt.Http(httpMW)).Then( func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { return testError }, ) r, _ := http.NewRequest("GET", "http://localhost", nil) err := n(context.TODO(), httptest.NewRecorder(), r) is.Err(err) is.Equal(err, testError) }
func genericRenderTest(mw noodle.Middleware, data interface{}, mutators ...headerMutator) (w *httptest.ResponseRecorder, err error) { h := noodle.New(mw).Then( func(c context.Context, w http.ResponseWriter, r *http.Request) error { return render.Yield(c, 200, data) }) r, _ := http.NewRequest("GET", "http://localhost/testId", nil) for _, m := range mutators { m(r) } w = httptest.NewRecorder() err = h(context.TODO(), w, r) return }
func TestHttpContextPasses(t *testing.T) { is := is.New(t) n := noodle.New(noodleMW, adapt.Http(httpMW)).Then( func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { val, ok := ctx.Value("testKey").(string) is.True(ok) is.Equal(val, "testValue") return nil }, ) r, _ := http.NewRequest("GET", "http://localhost", nil) _ = n(context.TODO(), httptest.NewRecorder(), r) }
func TestChain(t *testing.T) { is := is.New(t) site := noodle.New(gorilla.Vars, noodleMW) router := mux.NewRouter() router.Handle("/{id}", site.Then(func(c context.Context, w http.ResponseWriter, r *http.Request) error { is.Equal(gorilla.GetVars(c)["id"], "testId") is.Equal(c.Value(testKey).(string), "testValue") return nil })) r, _ := http.NewRequest("GET", "http://localhost/testId", nil) router.ServeHTTP(httptest.NewRecorder(), r) }
func TestUseSeparates(t *testing.T) { is := is.New(t) root := noodle.New(mwFactory("A"), mwFactory("B")) chain1 := root.Use(mwFactory("C")) chain2 := root.Use(mwFactory("D")) h1 := root.Then(handlerFactory("H1", "VarA", "VarB")) h2 := chain1.Then(handlerFactory("H1", "VarA", "VarB", "VarC")) h3 := chain2.Then(handlerFactory("H1", "VarA", "VarB", "VarD")) res1 := RunHTTP(h1) res2 := RunHTTP(h2) res3 := RunHTTP(h3) is.Equal("A>B>H1 [VarA=Avalue][VarB=Bvalue]", res1) is.Equal("A>B>C>H1 [VarA=Avalue][VarB=Bvalue][VarC=Cvalue]", res2) is.Equal("A>B>D>H1 [VarA=Avalue][VarB=Bvalue][VarD=Dvalue]", res3) }
func TestLoggerImplementsInterfaces(t *testing.T) { is := is.New(t) n := noodle.New(mw.Logger).Then( func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { _, ok := w.(http.Flusher) is.True(ok) _, ok = w.(http.Hijacker) is.True(ok) _, ok = w.(http.CloseNotifier) is.True(ok) return nil }, ) r, _ := http.NewRequest("GET", "http://localhost", nil) err := n(context.TODO(), httptest.NewRecorder(), r) is.NotErr(err) }
func TestLogger(t *testing.T) { is := is.New(t) buf := new(bytes.Buffer) log.SetOutput(buf) testError := errors.New("test error") n := noodle.New(mw.Logger).Then( func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { w.WriteHeader(400) return testError }, ) r, _ := http.NewRequest("GET", "http://localhost", nil) err := n(context.TODO(), httptest.NewRecorder(), r) logString := buf.String() is.Equal(err, testError) is.True(strings.Contains(logString, "GET")) is.True(strings.Contains(logString, "(400)")) is.True(strings.Contains(logString, "test error")) }
func TestHttpAuth(t *testing.T) { is := is.New(t) n := noodle.New(mw.HTTPAuth("test", func(u, p string) bool { return p == "testPassword" })).Then(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { user := mw.GetUser(ctx) is.Equal(user, "testUser") return nil }) r, _ := http.NewRequest("GET", "http://localhost", nil) w := httptest.NewRecorder() err := n(context.TODO(), w, r) is.Err(err) is.Equal(err, mw.UnauthorizedRequest) is.Equal(w.Code, http.StatusUnauthorized) is.Equal(w.Header().Get("WWW-Authenticate"), "Basic realm=test") r.SetBasicAuth("testUser", "wrongPassword") is.Err(n(context.TODO(), w, r)) r.SetBasicAuth("testUser", "testPassword") is.NotErr(n(context.TODO(), w, r)) }
// New creates new Wok initialized with middlewares. // The resulting middleware chain will be called for all routes in Wok func New(mws ...noodle.Middleware) *Wok { return &Wok{ Router: httprouter.New(), chain: noodle.New(mws...), } }
// Default is a convenience function creating new noodle.Chain with Logger, Recover and LocalStore middlewares func Default(mws ...noodle.Middleware) noodle.Chain { return noodle.New(RealIP, Logger, Recover, LocalStore).Use(mws...) }