From 8a861997a4b5feaf6397c1a3cbf671a6d5a684c4 Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Tue, 13 Dec 2016 07:12:58 +0200 Subject: [PATCH] nothing special here --- context.go | 1 - context_test.go | 266 +++++++++++++++++++++++------------------------- iris/get.go | 2 +- utils/exec.go | 2 +- 4 files changed, 131 insertions(+), 140 deletions(-) diff --git a/context.go b/context.go index 879345dd..a00c4984 100644 --- a/context.go +++ b/context.go @@ -78,7 +78,6 @@ const ( var ( errTemplateExecute = errors.New("Unable to execute a template. Trace: %s") errFlashNotFound = errors.New("Unable to get flash message. Trace: Cookie does not exists") - errNoForm = errors.New("Request has no any valid form") errReadBody = errors.New("While trying to read %s from the request body. Trace %s") errServeContent = errors.New("While trying to serve content to the client. Trace %s") ) diff --git a/context_test.go b/context_test.go index 9f112e99..be67e6df 100644 --- a/context_test.go +++ b/context_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "encoding/xml" "fmt" + "github.com/gavv/httpexpect" "github.com/kataras/iris" "github.com/kataras/iris/httptest" "github.com/valyala/fasthttp" @@ -211,6 +212,109 @@ type testBinderXMLData struct { Stars int `xml:"stars",json:"stars"` } +type testBinder struct { + //pointer of testBinderDataJSON or testBinderXMLData + vp interface{} + m iris.Unmarshaler + shouldError bool +} + +func (tj *testBinder) Decode(data []byte) error { + if tj.shouldError { + return fmt.Errorf("Should error") + } + return tj.m.Unmarshal(data, tj.vp) +} + +func testUnmarshaler(t *testing.T, tb *testBinder, + write func(ctx *iris.Context)) *httpexpect.Request { + + // a very dirty and awful way but here we must test in deep + // the custom object's decoder error with the custom + // unmarshaler result whenever the testUnmarshaler called. + if tb.shouldError == false { + tb.shouldError = true + testUnmarshaler(t, tb, nil) + tb.shouldError = false + } + + iris.ResetDefault() + h := func(ctx *iris.Context) { + err := ctx.UnmarshalBody(tb.vp, tb.m) + if tb.shouldError && err == nil { + t.Fatalf("Should prompted for error 'Should error' but not error returned from the custom decoder!") + } else if err != nil { + t.Fatalf("Error when parsing the body: %s", err.Error()) + } + if write != nil { + write(ctx) + } + } + + iris.Post("/bind_req_body", h) + + e := httptest.New(iris.Default, t) + return e.POST("/bind_req_body") +} + +// same as DecodeBody +// JSON, XML by DecodeBody passing the default unmarshalers +func TestContextBinders(t *testing.T) { + + passed := map[string]interface{}{"Username": "myusername", + "Mail": "mymail@iris-go.com", + "mydata": []string{"mydata1", "mydata2"}} + expectedObject := testBinderData{Username: "myusername", + Mail: "mymail@iris-go.com", + Data: []string{"mydata1", "mydata2"}} + + // JSON + vJSON := &testBinder{&testBinderData{}, + iris.UnmarshalerFunc(json.Unmarshal), false} + + testUnmarshaler( + t, + vJSON, + func(ctx *iris.Context) { + ctx.JSON(iris.StatusOK, vJSON.vp) + }). + WithJSON(passed). + Expect(). + Status(iris.StatusOK). + JSON().Object().Equal(expectedObject) + + // XML + expectedObj := testBinderXMLData{ + XMLName: xml.Name{Local: "info", Space: "info"}, + FirstAttr: "this is the first attr", + SecondAttr: "this is the second attr", + Name: "Iris web framework", + Birth: "13 March 2016", + Stars: 5758, + } + expectedAndPassedObjText := `<` + expectedObj.XMLName.Local + ` first="` + + expectedObj.FirstAttr + `" second="` + + expectedObj.SecondAttr + `">` + + expectedObj.Name + `` + + expectedObj.Birth + `` + + strconv.Itoa(expectedObj.Stars) + `` + + // JSON + vXML := &testBinder{&testBinderXMLData{}, + iris.UnmarshalerFunc(xml.Unmarshal), false} + testUnmarshaler( + t, + vXML, + func(ctx *iris.Context) { + ctx.XML(iris.StatusOK, vXML.vp) + }). + WithText(expectedAndPassedObjText). + Expect(). + Status(iris.StatusOK). + Body().Equal(expectedAndPassedObjText) + +} + func TestContextReadForm(t *testing.T) { iris.ResetDefault() @@ -233,113 +337,6 @@ func TestContextReadForm(t *testing.T) { e.POST("/form").WithForm(passed).Expect().Status(iris.StatusOK).JSON().Object().Equal(expectedObject) } -func TestContextReadJSON(t *testing.T) { - iris.ResetDefault() - iris.Post("/json", func(ctx *iris.Context) { - obj := testBinderData{} - err := ctx.ReadJSON(&obj) - if err != nil { - t.Fatalf("Error when parsing the JSON body: %s", err.Error()) - } - ctx.JSON(iris.StatusOK, obj) - }) - - iris.Post("/json_pointer", func(ctx *iris.Context) { - obj := &testBinderData{} - err := ctx.ReadJSON(obj) - if err != nil { - t.Fatalf("Error when parsing the JSON body: %s", err.Error()) - } - ctx.JSON(iris.StatusOK, obj) - }) - - e := httptest.New(iris.Default, t) - passed := map[string]interface{}{"Username": "myusername", "Mail": "mymail@iris-go.com", "mydata": []string{"mydata1", "mydata2"}} - expectedObject := testBinderData{Username: "myusername", Mail: "mymail@iris-go.com", Data: []string{"mydata1", "mydata2"}} - - e.POST("/json").WithJSON(passed).Expect().Status(iris.StatusOK).JSON().Object().Equal(expectedObject) - e.POST("/json_pointer").WithJSON(passed).Expect().Status(iris.StatusOK).JSON().Object().Equal(expectedObject) -} - -type testJSONBinderDataWithDecoder struct { - Username string - Mail string - Data []string `json:"mydata"` - shouldError bool -} - -func (tj *testJSONBinderDataWithDecoder) Decode(data []byte) error { - if tj.shouldError { - return fmt.Errorf("Should error") - } - return json.Unmarshal(data, tj) -} - -func TestContextReadJSONWithDecoder(t *testing.T) { - iris.ResetDefault() - iris.Post("/json_should_error", func(ctx *iris.Context) { - obj := testJSONBinderDataWithDecoder{shouldError: true} - err := ctx.ReadJSON(&obj) - if err == nil { - t.Fatalf("Should prompted for error 'Should error' but not error returned from the custom decoder!") - } - ctx.Write(err.Error()) - ctx.SetStatusCode(iris.StatusOK) - }) - - iris.Post("/json", func(ctx *iris.Context) { - obj := testJSONBinderDataWithDecoder{} - err := ctx.ReadJSON(&obj) - if err != nil { - t.Fatalf("Error when parsing the JSON body: %s", err.Error()) - } - ctx.JSON(iris.StatusOK, obj) - }) - - iris.Post("/json_pointer", func(ctx *iris.Context) { - obj := &testJSONBinderDataWithDecoder{} - err := ctx.ReadJSON(obj) - if err != nil { - t.Fatalf("Error when parsing the JSON body: %s", err.Error()) - } - ctx.JSON(iris.StatusOK, obj) - }) - - e := httptest.New(iris.Default, t) - passed := map[string]interface{}{"Username": "kataras", "Mail": "mymail@iris-go.com", "mydata": []string{"mydata1", "mydata2"}} - expectedObject := testJSONBinderDataWithDecoder{Username: "kataras", Mail: "mymail@iris-go.com", Data: []string{"mydata1", "mydata2"}} - - e.POST("/json_should_error").WithJSON(passed).Expect().Status(iris.StatusOK).Body().Equal("Should error") - e.POST("/json").WithJSON(passed).Expect().Status(iris.StatusOK).JSON().Object().Equal(expectedObject) - e.POST("/json_pointer").WithJSON(passed).Expect().Status(iris.StatusOK).JSON().Object().Equal(expectedObject) -} // no need for xml, it's exact the same. - -func TestContextReadXML(t *testing.T) { - iris.ResetDefault() - - iris.Post("/xml", func(ctx *iris.Context) { - obj := testBinderXMLData{} - err := ctx.ReadXML(&obj) - if err != nil { - t.Fatalf("Error when parsing the XML body: %s", err.Error()) - } - ctx.XML(iris.StatusOK, obj) - }) - - e := httptest.New(iris.Default, t) - expectedObj := testBinderXMLData{ - XMLName: xml.Name{Local: "info", Space: "info"}, - FirstAttr: "this is the first attr", - SecondAttr: "this is the second attr", - Name: "Iris web framework", - Birth: "13 March 2016", - Stars: 4064, - } - // so far no WithXML or .XML like WithJSON and .JSON on httpexpect I added a feature request as post issue and we're waiting - expectedBody := `<` + expectedObj.XMLName.Local + ` first="` + expectedObj.FirstAttr + `" second="` + expectedObj.SecondAttr + `">` + expectedObj.Name + `` + expectedObj.Birth + `` + strconv.Itoa(expectedObj.Stars) + `` - e.POST("/xml").WithText(expectedBody).Expect().Status(iris.StatusOK).Body().Equal(expectedBody) -} - // TestContextRedirectTo tests the named route redirect action func TestContextRedirectTo(t *testing.T) { iris.ResetDefault() @@ -728,38 +725,33 @@ func TestContextRenderRest(t *testing.T) { func TestContextPreRender(t *testing.T) { iris.ResetDefault() - errMsg1 := "thereIsAnError" - iris.UsePreRender(func(ctx *iris.Context, src string, binding interface{}, options ...map[string]interface{}) bool { - // put the 'Error' binding here, for the shake of the test - if b, isMap := binding.(map[string]interface{}); isMap { - b["Error"] = errMsg1 - } - // continue to the next prerender - return true - }) - errMsg2 := "thereIsASecondError" - iris.UsePreRender(func(ctx *iris.Context, src string, binding interface{}, options ...map[string]interface{}) bool { - // put the 'Error' binding here, for the shake of the test - if b, isMap := binding.(map[string]interface{}); isMap { - prev := b["Error"].(string) - msg := prev + errMsg2 - b["Error"] = msg - } - // DO NOT CONTINUE to the next prerender - return false - }) - errMsg3 := "thereisAThirdError" - iris.UsePreRender(func(ctx *iris.Context, src string, binding interface{}, options ...map[string]interface{}) bool { - // put the 'Error' binding here, for the shake of the test - if b, isMap := binding.(map[string]interface{}); isMap { - prev := b["Error"].(string) - msg := prev + errMsg3 - b["Error"] = msg + preRender := func(errMsg string, shouldContinue bool) iris.PreRender { + return func(ctx *iris.Context, + src string, + binding interface{}, + options ...map[string]interface{}) bool { + // put the 'Error' binding here, for the shake of the test + if b, isMap := binding.(map[string]interface{}); isMap { + msg := "" + if prevMsg := b["Error"]; prevMsg != nil { + // we have a previous message + msg += prevMsg.(string) + } + msg += errMsg + b["Error"] = msg + } + return shouldContinue } - // doesn't matters the return statement, we don't have other prerender - return true - }) + } + errMsg1 := "thereIsAnError" + errMsg2 := "thereIsASecondError" + errMsg3 := "thereisAThirdError" + // only errMsg1 and errMsg2 should be rendered because + // on errMsg2 we stop the execution + iris.UsePreRender(preRender(errMsg1, true)) + iris.UsePreRender(preRender(errMsg2, false)) + iris.UsePreRender(preRender(errMsg3, false)) // false doesn't matters here iris.Get("/", func(ctx *iris.Context) { ctx.RenderTemplateSource(iris.StatusOK, "

HI {{.Username}}. Error: {{.Error}}

", map[string]interface{}{"Username": "kataras"}) diff --git a/iris/get.go b/iris/get.go index 5088aca0..7b67e77a 100644 --- a/iris/get.go +++ b/iris/get.go @@ -1,4 +1,4 @@ -package main +package main // #nosec import ( "fmt" diff --git a/utils/exec.go b/utils/exec.go index d6f7730b..d990100a 100644 --- a/utils/exec.go +++ b/utils/exec.go @@ -1,4 +1,4 @@ -package utils +package utils // #nosec import ( "fmt"