package mvc_test import ( "errors" "testing" "github.com/kataras/iris" "github.com/kataras/iris/context" "github.com/kataras/iris/httptest" "github.com/kataras/iris/mvc" ) // activator/methodfunc/func_caller.go. // and activator/methodfunc/func_result_dispatcher.go type testControllerMethodResult struct { mvc.C } func (c *testControllerMethodResult) Get() mvc.Result { return mvc.Response{ Text: "Hello World!", } } func (c *testControllerMethodResult) GetWithStatus() mvc.Response { // or mvc.Result again, no problem. return mvc.Response{ Text: "This page doesn't exist", Code: iris.StatusNotFound, } } type testCustomStruct struct { Name string `json:"name" xml:"name"` Age int `json:"age" xml:"age"` } func (c *testControllerMethodResult) GetJson() mvc.Result { var err error if c.Ctx.URLParamExists("err") { err = errors.New("error here") } return mvc.Response{ Err: err, // if err != nil then it will fire the error's text with a BadRequest. Object: testCustomStruct{Name: "Iris", Age: 2}, } } var things = []string{"thing 0", "thing 1", "thing 2"} func (c *testControllerMethodResult) GetThingWithTryBy(index int) mvc.Result { failure := mvc.Response{ Text: "thing does not exist", Code: iris.StatusNotFound, } return mvc.Try(func() mvc.Result { // if panic because of index exceed the slice // then the "failure" response will be returned instead. return mvc.Response{Text: things[index]} }, failure) } func (c *testControllerMethodResult) GetThingWithTryDefaultBy(index int) mvc.Result { return mvc.Try(func() mvc.Result { // if panic because of index exceed the slice // then the default failure response will be returned instead (400 bad request). return mvc.Response{Text: things[index]} }) } func TestControllerMethodResult(t *testing.T) { app := iris.New() app.Controller("/", new(testControllerMethodResult)) e := httptest.New(t, app) e.GET("/").Expect().Status(iris.StatusOK). Body().Equal("Hello World!") e.GET("/with/status").Expect().Status(iris.StatusNotFound). Body().Equal("This page doesn't exist") e.GET("/json").Expect().Status(iris.StatusOK). JSON().Equal(iris.Map{ "name": "Iris", "age": 2, }) e.GET("/json").WithQuery("err", true).Expect(). Status(iris.StatusBadRequest). Body().Equal("error here") e.GET("/thing/with/try/1").Expect(). Status(iris.StatusOK). Body().Equal("thing 1") // failure because of index exceed the slice e.GET("/thing/with/try/3").Expect(). Status(iris.StatusNotFound). Body().Equal("thing does not exist") e.GET("/thing/with/try/default/3").Expect(). Status(iris.StatusBadRequest). Body().Equal("Bad Request") } type testControllerMethodResultTypes struct { mvc.Controller } func (c *testControllerMethodResultTypes) GetText() string { return "text" } func (c *testControllerMethodResultTypes) GetStatus() int { return iris.StatusBadGateway } func (c *testControllerMethodResultTypes) GetTextWithStatusOk() (string, int) { return "OK", iris.StatusOK } // tests should have output arguments mixed func (c *testControllerMethodResultTypes) GetStatusWithTextNotOkBy(first string, second string) (int, string) { return iris.StatusForbidden, "NOT_OK_" + first + second } func (c *testControllerMethodResultTypes) GetTextAndContentType() (string, string) { return "text", "text/html" } type testControllerMethodCustomResult struct { HTML string } // The only one required function to make that a custom Response dispatcher. func (r testControllerMethodCustomResult) Dispatch(ctx context.Context) { ctx.HTML(r.HTML) } func (c *testControllerMethodResultTypes) GetCustomResponse() testControllerMethodCustomResult { return testControllerMethodCustomResult{"text"} } func (c *testControllerMethodResultTypes) GetCustomResponseWithStatusOk() (testControllerMethodCustomResult, int) { return testControllerMethodCustomResult{"OK"}, iris.StatusOK } func (c *testControllerMethodResultTypes) GetCustomResponseWithStatusNotOk() (testControllerMethodCustomResult, int) { return testControllerMethodCustomResult{"internal server error"}, iris.StatusInternalServerError } func (c *testControllerMethodResultTypes) GetCustomStruct() testCustomStruct { return testCustomStruct{"Iris", 2} } func (c *testControllerMethodResultTypes) GetCustomStructWithStatusNotOk() (testCustomStruct, int) { return testCustomStruct{"Iris", 2}, iris.StatusInternalServerError } func (c *testControllerMethodResultTypes) GetCustomStructWithContentType() (testCustomStruct, string) { return testCustomStruct{"Iris", 2}, "text/xml" } func (c *testControllerMethodResultTypes) GetCustomStructWithError() (s testCustomStruct, err error) { s = testCustomStruct{"Iris", 2} if c.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 } func TestControllerMethodResultTypes(t *testing.T) { app := iris.New() app.Controller("/", new(testControllerMethodResultTypes)) 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") 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") } type testControllerViewResultRespectCtxViewData struct { T *testing.T mvc.C } func (t *testControllerViewResultRespectCtxViewData) BeginRequest(ctx context.Context) { t.C.BeginRequest(ctx) ctx.ViewData("name_begin", "iris_begin") } func (t *testControllerViewResultRespectCtxViewData) EndRequest(ctx context.Context) { t.C.EndRequest(ctx) // check if data is not overridden by return mvc.View {Data: context.Map...} dataWritten := ctx.GetViewData() if dataWritten == nil { t.T.Fatalf("view data is nil, both BeginRequest and Get failed to write the data") return } if dataWritten["name_begin"] == nil { t.T.Fatalf(`view data[name_begin] is nil, BeginRequest's ctx.ViewData call have been overridden by Get's return mvc.View {Data: }. Total view data: %v`, dataWritten) } if dataWritten["name"] == nil { t.T.Fatalf("view data[name] is nil, Get's return mvc.View {Data: } didn't work. Total view data: %v", dataWritten) } } func (t *testControllerViewResultRespectCtxViewData) Get() mvc.Result { return mvc.View{ Name: "doesnt_exists.html", Data: context.Map{"name": "iris"}, // we care about this only. Code: iris.StatusInternalServerError, } } func TestControllerViewResultRespectCtxViewData(t *testing.T) { app := iris.New() app.Controller("/", new(testControllerViewResultRespectCtxViewData), t) e := httptest.New(t, app) e.GET("/").Expect().Status(iris.StatusInternalServerError) }