Merge branch 'develop' of https://github.com/beego/beego into develop
This commit is contained in:
commit
9b418271cc
@ -1,5 +1,6 @@
|
||||
# developing
|
||||
- Add http client and option func. [4455](https://github.com/beego/beego/issues/4455)
|
||||
- Add: Resp() method for web.Controller. [4588](https://github.com/beego/beego/pull/4588)
|
||||
- Web mock and test support. [4565](https://github.com/beego/beego/pull/4565) [4574](https://github.com/beego/beego/pull/4574)
|
||||
- Error codes definition of cache module. [4493](https://github.com/beego/beego/pull/4493)
|
||||
- Remove generateCommentRoute http hook. Using `bee generate routers` commands instead.[4486](https://github.com/beego/beego/pull/4486) [bee PR 762](https://github.com/beego/bee/pull/762)
|
||||
@ -37,6 +38,7 @@
|
||||
- Feature issue #4402 finish router get example. [4416](https://github.com/beego/beego/pull/4416)
|
||||
- Proposal: Add Bind() method for `web.Controller` [4491](https://github.com/beego/beego/issues/4579)
|
||||
- Optimize AddAutoPrefix: only register one router in case-insensitive mode. [4582](https://github.com/beego/beego/pull/4582)
|
||||
- Init exceptMethod by using reflection. [4583](https://github.com/beego/beego/pull/4583)
|
||||
|
||||
## Fix Sonar
|
||||
- [4473](https://github.com/beego/beego/pull/4473)
|
||||
|
||||
@ -21,8 +21,6 @@ import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"gopkg.in/yaml.v2"
|
||||
"html/template"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
@ -37,6 +35,8 @@ import (
|
||||
"github.com/beego/beego/v2/server/web/context"
|
||||
"github.com/beego/beego/v2/server/web/context/param"
|
||||
"github.com/beego/beego/v2/server/web/session"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -436,6 +436,22 @@ func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
|
||||
}
|
||||
return URLFor(endpoint, values...)
|
||||
}
|
||||
// Resp sends response based on the Accept Header
|
||||
// By default response will be in JSON
|
||||
func (c *Controller) Resp(data interface{}) error {
|
||||
accept := c.Ctx.Input.Header("Accept")
|
||||
switch accept {
|
||||
case context.ApplicationYAML:
|
||||
c.Data["yaml"] = data
|
||||
return c.ServeYAML()
|
||||
case context.ApplicationXML, context.TextXML:
|
||||
c.Data["xml"] = data
|
||||
return c.ServeXML()
|
||||
default:
|
||||
c.Data["json"] = data
|
||||
return c.ServeJSON()
|
||||
}
|
||||
}
|
||||
|
||||
// ServeJSON sends a json response with encoding charset.
|
||||
func (c *Controller) ServeJSON(encoding ...bool) error {
|
||||
|
||||
@ -15,16 +15,18 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/beego/beego/v2/server/web/context"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetInt(t *testing.T) {
|
||||
@ -244,3 +246,67 @@ func TestBindYAML(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "FOO", s.Foo)
|
||||
}
|
||||
|
||||
type TestRespController struct {
|
||||
Controller
|
||||
}
|
||||
|
||||
func (t *TestRespController) TestResponse() {
|
||||
type S struct {
|
||||
Foo string `json:"foo" xml:"foo" yaml:"foo"`
|
||||
}
|
||||
|
||||
bar := S{Foo: "bar"}
|
||||
|
||||
_ = t.Resp(bar)
|
||||
}
|
||||
|
||||
type respTestCase struct {
|
||||
Accept string
|
||||
ExpectedContentLength int64
|
||||
ExpectedResponse string
|
||||
}
|
||||
|
||||
func TestControllerResp(t *testing.T) {
|
||||
// test cases
|
||||
tcs := []respTestCase{
|
||||
{Accept: context.ApplicationJSON, ExpectedContentLength: 18, ExpectedResponse: "{\n \"foo\": \"bar\"\n}"},
|
||||
{Accept: context.ApplicationXML, ExpectedContentLength: 25, ExpectedResponse: "<S>\n <foo>bar</foo>\n</S>"},
|
||||
{Accept: context.ApplicationYAML, ExpectedContentLength: 9, ExpectedResponse: "foo: bar\n"},
|
||||
{Accept: "OTHER", ExpectedContentLength: 18, ExpectedResponse: "{\n \"foo\": \"bar\"\n}"},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
testControllerRespTestCases(t, tc)
|
||||
}
|
||||
}
|
||||
|
||||
func testControllerRespTestCases(t *testing.T, tc respTestCase) {
|
||||
// create fake GET request
|
||||
r, _ := http.NewRequest("GET", "/", nil)
|
||||
r.Header.Set("Accept", tc.Accept)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
// setup the handler
|
||||
handler := NewControllerRegister()
|
||||
handler.Add("/", &TestRespController{}, WithRouterMethods(&TestRespController{}, "get:TestResponse"))
|
||||
handler.ServeHTTP(w, r)
|
||||
|
||||
response := w.Result()
|
||||
if response.ContentLength != tc.ExpectedContentLength {
|
||||
t.Errorf("TestResponse() unable to validate content length %d for %s", response.ContentLength, tc.Accept)
|
||||
}
|
||||
|
||||
if response.StatusCode != http.StatusOK {
|
||||
t.Errorf("TestResponse() failed to validate response code for %s", tc.Accept)
|
||||
}
|
||||
|
||||
bodyBytes, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
t.Errorf("TestResponse() failed to parse response body for %s", tc.Accept)
|
||||
}
|
||||
bodyString := string(bodyBytes)
|
||||
if bodyString != tc.ExpectedResponse {
|
||||
t.Errorf("TestResponse() failed to validate response body '%s' for %s", bodyString, tc.Accept)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,13 +2,12 @@ package web
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"mime"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/beego/beego/v2/server/web/context"
|
||||
"github.com/beego/beego/v2/server/web/session"
|
||||
"mime"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// register MIME type with content type
|
||||
@ -95,4 +94,4 @@ func registerGzip() error {
|
||||
)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -69,20 +69,8 @@ var (
|
||||
"UNLOCK": true,
|
||||
}
|
||||
// these web.Controller's methods shouldn't reflect to AutoRouter
|
||||
exceptMethod = []string{"Abort", "CheckXSRFCookie", "CustomAbort", "DelSession",
|
||||
"DestroySession", "Finish", "GetBool", "GetControllerAndAction",
|
||||
"GetFile", "GetFiles", "GetFloat", "GetInt", "GetInt16",
|
||||
"GetInt32", "GetInt64", "GetInt8", "GetSecureCookie", "GetSession",
|
||||
"GetString", "GetStrings", "GetUint16", "GetUint32", "GetUint64",
|
||||
"GetUint8", "HandlerFunc", "Init", "Input",
|
||||
"IsAjax", "Mapping", "ParseForm",
|
||||
"Prepare", "Redirect", "Render", "RenderBytes",
|
||||
"RenderString", "SaveToFile", "SaveToFileWithBuffer", "SaveToFileWithBuffer",
|
||||
"ServeFormatted", "ServeJSON", "ServeJSONP", "ServeXML", "ServeYAML",
|
||||
"SessionRegenerateID", "SetData", "SetSecureCookie", "SetSession", "StartSession",
|
||||
"StopRun", "URLFor", "URLMapping", "XSRFFormHTML",
|
||||
"XSRFToken",
|
||||
}
|
||||
// see registerControllerExceptMethods
|
||||
exceptMethod = initExceptMethod()
|
||||
|
||||
urlPlaceholder = "{{placeholder}}"
|
||||
// DefaultAccessLogFilter will skip the accesslog if return true
|
||||
@ -116,6 +104,17 @@ func ExceptMethodAppend(action string) {
|
||||
exceptMethod = append(exceptMethod, action)
|
||||
}
|
||||
|
||||
func initExceptMethod() []string {
|
||||
res := make([]string, 0, 32)
|
||||
c := &Controller{}
|
||||
t := reflect.TypeOf(c)
|
||||
for i := 0; i < t.NumMethod(); i++ {
|
||||
m := t.Method(i)
|
||||
res = append(res, m.Name)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// ControllerInfo holds information about the controller.
|
||||
type ControllerInfo struct {
|
||||
pattern string
|
||||
|
||||
@ -137,10 +137,12 @@ func TestUrlFor(t *testing.T) {
|
||||
func TestUrlFor3(t *testing.T) {
|
||||
handler := NewControllerRegister()
|
||||
handler.AddAuto(&TestController{})
|
||||
if a := handler.URLFor("TestController.Myext"); a != "/test/myext" && a != "/Test/Myext" {
|
||||
a := handler.URLFor("TestController.Myext")
|
||||
if a != "/test/myext" && a != "/Test/Myext" {
|
||||
t.Errorf("TestController.Myext must equal to /test/myext, but get " + a)
|
||||
}
|
||||
if a := handler.URLFor("TestController.GetURL"); a != "/test/geturl" && a != "/Test/GetURL" {
|
||||
a = handler.URLFor("TestController.GetURL")
|
||||
if a != "/test/geturl" && a != "/Test/GetURL" {
|
||||
t.Errorf("TestController.GetURL must equal to /test/geturl, but get " + a)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user