1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-08 20:41:57 +00:00

add 'Context.Register/RemoveDependency' for registering dependencies for next handler in the chain from a common iris handler in serve-time

And also, add a Configuration.FireEmptyFormError if end-dev wants to receive an iris.ErrEmptyForm error on missing form data on 'Context.ReadForm/ReadBody'


Former-commit-id: a2713bec77375b2908f1f066a46be4f19e6b7a61
This commit is contained in:
Gerasimos (Makis) Maropoulos
2020-05-19 09:28:27 +03:00
parent c0fd429a43
commit c866709acc
10 changed files with 181 additions and 8 deletions

View File

@@ -323,6 +323,14 @@ func payloadBinding(index int, typ reflect.Type) *binding {
Handle: func(ctx context.Context, input *Input) (newValue reflect.Value, err error) {
wasPtr := input.Type.Kind() == reflect.Ptr
if serveDepsV := ctx.Values().Get(context.DependenciesContextKey); serveDepsV != nil {
if serveDeps, ok := serveDepsV.(context.DependenciesMap); ok {
if newValue, ok = serveDeps[typ]; ok {
return
}
}
}
newValue = reflect.New(indirectType(input.Type))
ptr := newValue.Interface()
err = ctx.ReadBody(ptr)

View File

@@ -75,7 +75,8 @@ func makeHandler(fn interface{}, c *Container, paramsCount int) context.Handler
}
v := valueOf(fn)
numIn := v.Type().NumIn()
typ := v.Type()
numIn := typ.NumIn()
bindings := getBindingsForFunc(v, c.Dependencies, paramsCount)

View File

@@ -129,17 +129,18 @@ func TestBindFunctionAsFunctionInputArgument(t *testing.T) {
func TestPayloadBinding(t *testing.T) {
h := New()
postHandler := h.Handler(func(input *testUserStruct /* ptr */) string {
ptrHandler := h.Handler(func(input *testUserStruct /* ptr */) string {
return input.Username
})
postHandler2 := h.Handler(func(input testUserStruct) string {
valHandler := h.Handler(func(input testUserStruct) string {
return input.Username
})
app := iris.New()
app.Post("/", postHandler)
app.Post("/2", postHandler2)
app.Get("/", ptrHandler)
app.Post("/", ptrHandler)
app.Post("/2", valHandler)
e := httptest.New(t, app)
@@ -152,8 +153,10 @@ func TestPayloadBinding(t *testing.T) {
// FORM (multipart)
e.POST("/").WithMultipart().WithFormField("username", "makis").Expect().Status(httptest.StatusOK).Body().Equal("makis")
// URL query.
// POST URL query.
e.POST("/").WithQuery("username", "makis").Expect().Status(httptest.StatusOK).Body().Equal("makis")
// GET URL query.
e.GET("/").WithQuery("username", "makis").Expect().Status(httptest.StatusOK).Body().Equal("makis")
}
/* Author's notes:
@@ -241,3 +244,44 @@ func TestHandlerPathParams(t *testing.T) {
testReq.Expect().Status(httptest.StatusOK).Body().Equal("42")
}
}
func TestRegisterDependenciesFromContext(t *testing.T) {
// Tests serve-time struct dependencies through a common Iris middleware.
app := iris.New()
app.Use(func(ctx iris.Context) {
ctx.RegisterDependency(testUserStruct{Username: "kataras"})
ctx.Next()
})
app.Use(func(ctx iris.Context) {
ctx.RegisterDependency(&testServiceImpl{prefix: "say"})
ctx.Next()
})
app.ConfigureContainer(func(api *iris.APIContainer) {
api.Get("/", func(u testUserStruct) string {
return u.Username
})
api.Get("/service", func(s *testServiceImpl) string {
return s.Say("hello")
})
// Note: we are not allowed to pass the service as an interface here
// because the container will, correctly, panic because it will expect
// a dependency to be registered before server ran.
api.Get("/both", func(s *testServiceImpl, u testUserStruct) string {
return s.Say(u.Username)
})
api.Get("/non", func() string {
return "nothing"
})
})
e := httptest.New(t, app)
e.GET("/").Expect().Status(httptest.StatusOK).Body().Equal("kataras")
e.GET("/service").Expect().Status(httptest.StatusOK).Body().Equal("say hello")
e.GET("/both").Expect().Status(httptest.StatusOK).Body().Equal("say kataras")
e.GET("/non").Expect().Status(httptest.StatusOK).Body().Equal("nothing")
}