package hero_test import ( "errors" "testing" "github.com/kataras/iris/v12" "github.com/kataras/iris/v12/context" "github.com/kataras/iris/v12/httptest" . "github.com/kataras/iris/v12/hero" ) func GetText() string { return "text" } func GetStatus() int { return iris.StatusBadGateway } func GetTextWithStatusOk() (string, int) { return "OK", iris.StatusOK } // tests should have output arguments mixed func GetStatusWithTextNotOkBy(first string, second string) (int, string) { return iris.StatusForbidden, "NOT_OK_" + first + second } func GetTextAndContentType() (string, string) { return "text", "text/html" } type testCustomResult struct { HTML string } // The only one required function to make that a custom Response dispatcher. func (r testCustomResult) Dispatch(ctx context.Context) { _, _ = ctx.HTML(r.HTML) } func GetCustomResponse() testCustomResult { return testCustomResult{"text"} } func GetCustomResponseWithStatusOk() (testCustomResult, int) { return testCustomResult{"OK"}, iris.StatusOK } func GetCustomResponseWithStatusNotOk() (testCustomResult, int) { return testCustomResult{"internal server error"}, iris.StatusInternalServerError } type testCustomStruct struct { Name string `json:"name" xml:"name"` Age int `json:"age" xml:"age"` } func GetCustomStruct() testCustomStruct { return testCustomStruct{"Iris", 2} } func GetCustomStructWithStatusNotOk() (testCustomStruct, int) { return testCustomStruct{"Iris", 2}, iris.StatusInternalServerError } func GetCustomStructWithContentType() (testCustomStruct, string) { return testCustomStruct{"Iris", 2}, "text/xml" } func GetCustomStructWithError(ctx context.Context) (s testCustomStruct, err error) { s = testCustomStruct{"Iris", 2} if ctx.URLParamExists("err") { err = errors.New("omit return of testCustomStruct and fire error") } // it should send the testCustomStruct as JSON if error is nil // otherwise it should fire the default error(BadRequest) with the error's text. return } type err struct { Status int `json:"status_code"` Message string `json:"message"` } func (e err) Dispatch(ctx context.Context) { // write the status code based on the err's StatusCode. ctx.StatusCode(e.Status) // send to the client the whole object as json _, _ = ctx.JSON(e) } func GetCustomErrorAsDispatcher() err { return err{iris.StatusBadRequest, "this is my error as json"} } func GetCustomTypedNilEmptyResponse() iris.Map { return nil } func GetCustomTypedPtrNilEmptyResponse() *iris.Map { return nil } func GetCustomMapNilEmptyResponse() map[string]interface{} { return nil } func GetCustomPtrStructNilEmptyResponse() *testCustomStruct { return nil } func TestFuncResult(t *testing.T) { app := iris.New() h := New() // for any 'By', by is not required but we use this suffix here, like controllers // to make it easier for the future to resolve if any bug. // add the binding for path parameters. app.Get("/text", h.Handler(GetText)) app.Get("/status", h.Handler(GetStatus)) app.Get("/text/with/status/ok", h.Handler(GetTextWithStatusOk)) app.Get("/status/with/text/not/ok/{first}/{second}", h.Handler(GetStatusWithTextNotOkBy)) app.Get("/text/and/content/type", h.Handler(GetTextAndContentType)) // app.Get("/custom/response", h.Handler(GetCustomResponse)) app.Get("/custom/response/with/status/ok", h.Handler(GetCustomResponseWithStatusOk)) app.Get("/custom/response/with/status/not/ok", h.Handler(GetCustomResponseWithStatusNotOk)) // app.Get("/custom/struct", h.Handler(GetCustomStruct)) app.Get("/custom/struct/with/status/not/ok", h.Handler(GetCustomStructWithStatusNotOk)) app.Get("/custom/struct/with/content/type", h.Handler(GetCustomStructWithContentType)) app.Get("/custom/struct/with/error", h.Handler(GetCustomStructWithError)) app.Get("/custom/error/as/dispatcher", h.Handler(GetCustomErrorAsDispatcher)) app.Get("/custom/nil/typed", h.Handler(GetCustomTypedNilEmptyResponse)) app.Get("/custom/nil/typed/ptr", h.Handler(GetCustomTypedPtrNilEmptyResponse)) app.Get("/custom/nil/map", h.Handler(GetCustomMapNilEmptyResponse)) app.Get("/custom/nil/struct", h.Handler(GetCustomPtrStructNilEmptyResponse)) e := httptest.New(t, app) e.GET("/text").Expect().Status(iris.StatusOK). Body().Equal("text") e.GET("/status").Expect().Status(iris.StatusBadGateway) e.GET("/text/with/status/ok").Expect().Status(iris.StatusOK). Body().Equal("OK") e.GET("/status/with/text/not/ok/first/second").Expect().Status(iris.StatusForbidden). Body().Equal("NOT_OK_firstsecond") // Author's note: <-- if that fails means that the last binder called for both input args, // see path_param_binder.go e.GET("/text/and/content/type").Expect().Status(iris.StatusOK). ContentType("text/html", "utf-8"). Body().Equal("text") e.GET("/custom/response").Expect().Status(iris.StatusOK). ContentType("text/html", "utf-8"). Body().Equal("text") e.GET("/custom/response/with/status/ok").Expect().Status(iris.StatusOK). ContentType("text/html", "utf-8"). Body().Equal("OK") e.GET("/custom/response/with/status/not/ok").Expect().Status(iris.StatusInternalServerError). ContentType("text/html", "utf-8"). Body().Equal("internal server error") expectedResultFromCustomStruct := map[string]interface{}{ "name": "Iris", "age": 2, } e.GET("/custom/struct").Expect().Status(iris.StatusOK). JSON().Equal(expectedResultFromCustomStruct) e.GET("/custom/struct/with/status/not/ok").Expect().Status(iris.StatusInternalServerError). JSON().Equal(expectedResultFromCustomStruct) e.GET("/custom/struct/with/content/type").Expect().Status(iris.StatusOK). ContentType("text/xml", "utf-8") e.GET("/custom/struct/with/error").Expect().Status(iris.StatusOK). JSON().Equal(expectedResultFromCustomStruct) e.GET("/custom/struct/with/error").WithQuery("err", true).Expect(). Status(iris.StatusBadRequest). // the default status code if error is not nil // the content should be not JSON it should be the status code's text // it will fire the error's text Body().Equal("omit return of testCustomStruct and fire error") e.GET("/custom/error/as/dispatcher").Expect(). Status(iris.StatusBadRequest). // the default status code if error is not nil // the content should be not JSON it should be the status code's text // it will fire the error's text JSON().Equal(err{iris.StatusBadRequest, "this is my error as json"}) // its result is nil should give an empty response but content-type is set correctly. e.GET("/custom/nil/typed").Expect(). Status(iris.StatusOK).ContentType(context.ContentJSONHeaderValue).Body().Empty() e.GET("/custom/nil/typed/ptr").Expect(). Status(iris.StatusOK).ContentType(context.ContentJSONHeaderValue).Body().Empty() e.GET("/custom/nil/map").Expect(). Status(iris.StatusOK).ContentType(context.ContentJSONHeaderValue).Body().Empty() e.GET("/custom/nil/struct").Expect(). Status(iris.StatusOK).ContentType(context.ContentJSONHeaderValue).Body().Empty() }