gin/render/render_test.go

595 lines
15 KiB
Go
Raw Normal View History

// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
2015-04-09 13:15:02 +03:00
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package render
import (
"encoding/xml"
"errors"
2015-04-09 13:15:02 +03:00
"html/template"
"net"
"net/http"
2015-04-09 13:15:02 +03:00
"net/http/httptest"
"strconv"
"strings"
2015-04-09 13:15:02 +03:00
"testing"
2023-05-10 12:19:26 +03:00
"github.com/gin-gonic/gin/internal/json"
2021-09-21 10:22:21 +03:00
testdata "github.com/gin-gonic/gin/testdata/protoexample"
2015-04-09 13:15:02 +03:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
2015-04-09 13:15:02 +03:00
)
2015-05-09 04:35:31 +03:00
// TODO unit tests
// test errors
2015-04-09 13:15:02 +03:00
func TestRenderJSON(t *testing.T) {
w := httptest.NewRecorder()
2022-03-21 04:43:17 +03:00
data := map[string]any{
"foo": "bar",
"html": "<b>",
}
(JSON{data}).WriteContentType(w)
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
2015-06-04 06:25:21 +03:00
err := (JSON{data}).Render(w)
2015-04-09 13:15:02 +03:00
require.NoError(t, err)
assert.Equal(t, "{\"foo\":\"bar\",\"html\":\"\\u003cb\\u003e\"}", w.Body.String())
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
2015-04-09 13:15:02 +03:00
}
func TestRenderJSONError(t *testing.T) {
w := httptest.NewRecorder()
data := make(chan int)
// json: unsupported type: chan int
require.Error(t, (JSON{data}).Render(w))
}
2015-04-09 13:15:02 +03:00
func TestRenderIndentedJSON(t *testing.T) {
w := httptest.NewRecorder()
2022-03-21 04:43:17 +03:00
data := map[string]any{
2015-04-09 13:15:02 +03:00
"foo": "bar",
"bar": "foo",
2015-05-18 16:45:24 +03:00
}
2015-06-04 06:25:21 +03:00
err := (IndentedJSON{data}).Render(w)
2015-04-09 13:15:02 +03:00
require.NoError(t, err)
assert.Equal(t, "{\n \"bar\": \"foo\",\n \"foo\": \"bar\"\n}", w.Body.String())
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
2015-04-09 13:15:02 +03:00
}
func TestRenderIndentedJSONPanics(t *testing.T) {
w := httptest.NewRecorder()
data := make(chan int)
// json: unsupported type: chan int
err := (IndentedJSON{data}).Render(w)
require.Error(t, err)
}
func TestRenderSecureJSON(t *testing.T) {
w1 := httptest.NewRecorder()
2022-03-21 04:43:17 +03:00
data := map[string]any{
"foo": "bar",
}
(SecureJSON{"while(1);", data}).WriteContentType(w1)
assert.Equal(t, "application/json; charset=utf-8", w1.Header().Get("Content-Type"))
err1 := (SecureJSON{"while(1);", data}).Render(w1)
require.NoError(t, err1)
assert.Equal(t, "{\"foo\":\"bar\"}", w1.Body.String())
assert.Equal(t, "application/json; charset=utf-8", w1.Header().Get("Content-Type"))
w2 := httptest.NewRecorder()
2022-03-21 04:43:17 +03:00
datas := []map[string]any{{
"foo": "bar",
}, {
"bar": "foo",
}}
err2 := (SecureJSON{"while(1);", datas}).Render(w2)
require.NoError(t, err2)
assert.Equal(t, "while(1);[{\"foo\":\"bar\"},{\"bar\":\"foo\"}]", w2.Body.String())
assert.Equal(t, "application/json; charset=utf-8", w2.Header().Get("Content-Type"))
}
func TestRenderSecureJSONFail(t *testing.T) {
w := httptest.NewRecorder()
data := make(chan int)
// json: unsupported type: chan int
err := (SecureJSON{"while(1);", data}).Render(w)
require.Error(t, err)
}
2018-04-26 06:52:19 +03:00
func TestRenderJsonpJSON(t *testing.T) {
w1 := httptest.NewRecorder()
2022-03-21 04:43:17 +03:00
data := map[string]any{
2018-04-26 06:52:19 +03:00
"foo": "bar",
}
(JsonpJSON{"x", data}).WriteContentType(w1)
assert.Equal(t, "application/javascript; charset=utf-8", w1.Header().Get("Content-Type"))
err1 := (JsonpJSON{"x", data}).Render(w1)
require.NoError(t, err1)
assert.Equal(t, "x({\"foo\":\"bar\"});", w1.Body.String())
2018-04-26 06:52:19 +03:00
assert.Equal(t, "application/javascript; charset=utf-8", w1.Header().Get("Content-Type"))
w2 := httptest.NewRecorder()
2022-03-21 04:43:17 +03:00
datas := []map[string]any{{
2018-04-26 06:52:19 +03:00
"foo": "bar",
}, {
"bar": "foo",
}}
err2 := (JsonpJSON{"x", datas}).Render(w2)
require.NoError(t, err2)
assert.Equal(t, "x([{\"foo\":\"bar\"},{\"bar\":\"foo\"}]);", w2.Body.String())
2018-04-26 06:52:19 +03:00
assert.Equal(t, "application/javascript; charset=utf-8", w2.Header().Get("Content-Type"))
}
2023-05-10 12:19:26 +03:00
type errorWriter struct {
bufString string
*httptest.ResponseRecorder
}
var _ http.ResponseWriter = (*errorWriter)(nil)
func (w *errorWriter) Write(buf []byte) (int, error) {
if string(buf) == w.bufString {
return 0, errors.New(`write "` + w.bufString + `" error`)
}
return w.ResponseRecorder.Write(buf)
}
func TestRenderJsonpJSONError(t *testing.T) {
ew := &errorWriter{
ResponseRecorder: httptest.NewRecorder(),
}
jsonpJSON := JsonpJSON{
Callback: "foo",
Data: map[string]string{
"foo": "bar",
},
}
cb := template.JSEscapeString(jsonpJSON.Callback)
ew.bufString = cb
err := jsonpJSON.Render(ew) // error was returned while writing callback
assert.Equal(t, `write "`+cb+`" error`, err.Error())
ew.bufString = `(`
err = jsonpJSON.Render(ew)
assert.Equal(t, `write "`+`(`+`" error`, err.Error())
data, _ := json.Marshal(jsonpJSON.Data) // error was returned while writing data
ew.bufString = string(data)
err = jsonpJSON.Render(ew)
assert.Equal(t, `write "`+string(data)+`" error`, err.Error())
ew.bufString = `);`
err = jsonpJSON.Render(ew)
assert.Equal(t, `write "`+`);`+`" error`, err.Error())
}
func TestRenderJsonpJSONError2(t *testing.T) {
w := httptest.NewRecorder()
2022-03-21 04:43:17 +03:00
data := map[string]any{
"foo": "bar",
}
(JsonpJSON{"", data}).WriteContentType(w)
assert.Equal(t, "application/javascript; charset=utf-8", w.Header().Get("Content-Type"))
e := (JsonpJSON{"", data}).Render(w)
require.NoError(t, e)
assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
assert.Equal(t, "application/javascript; charset=utf-8", w.Header().Get("Content-Type"))
}
2018-04-26 06:52:19 +03:00
func TestRenderJsonpJSONFail(t *testing.T) {
w := httptest.NewRecorder()
data := make(chan int)
// json: unsupported type: chan int
err := (JsonpJSON{"x", data}).Render(w)
require.Error(t, err)
2018-04-26 06:52:19 +03:00
}
func TestRenderAsciiJSON(t *testing.T) {
w1 := httptest.NewRecorder()
2022-03-21 04:43:17 +03:00
data1 := map[string]any{
"lang": "GO语言",
"tag": "<br>",
}
err := (AsciiJSON{data1}).Render(w1)
require.NoError(t, err)
assert.Equal(t, "{\"lang\":\"GO\\u8bed\\u8a00\",\"tag\":\"\\u003cbr\\u003e\"}", w1.Body.String())
assert.Equal(t, "application/json", w1.Header().Get("Content-Type"))
w2 := httptest.NewRecorder()
data2 := 3.1415926
err = (AsciiJSON{data2}).Render(w2)
require.NoError(t, err)
assert.Equal(t, "3.1415926", w2.Body.String())
}
func TestRenderAsciiJSONFail(t *testing.T) {
w := httptest.NewRecorder()
data := make(chan int)
// json: unsupported type: chan int
require.Error(t, (AsciiJSON{data}).Render(w))
}
func TestRenderPureJSON(t *testing.T) {
w := httptest.NewRecorder()
2022-03-21 04:43:17 +03:00
data := map[string]any{
"foo": "bar",
"html": "<b>",
}
err := (PureJSON{data}).Render(w)