@@ -12,6 +12,7 @@ import (
1212 "io"
1313 "io/fs"
1414 "log/slog"
15+ "math"
1516 "mime/multipart"
1617 "net/http"
1718 "net/http/httptest"
@@ -138,6 +139,24 @@ func TestContextRenderTemplate(t *testing.T) {
138139 }
139140}
140141
142+ func TestContextRenderTemplateError (t * testing.T ) {
143+ // we test that when template rendering fails, no response is sent to the client yet, so the global error handler can decide what to do
144+ e := New ()
145+ req := httptest .NewRequest (http .MethodPost , "/" , strings .NewReader (userJSON ))
146+ rec := httptest .NewRecorder ()
147+ c := e .NewContext (req , rec )
148+
149+ tmpl := & Template {
150+ templates : template .Must (template .New ("hello" ).Parse ("Hello, {{.}}!" )),
151+ }
152+ c .Echo ().Renderer = tmpl
153+ err := c .Render (http .StatusOK , "not_existing" , "Jon Snow" )
154+
155+ assert .EqualError (t , err , `template: no template "not_existing" associated with template "hello"` )
156+ assert .Equal (t , http .StatusOK , rec .Code ) // status code must not be sent to the client
157+ assert .Empty (t , rec .Body .String ()) // body must not be sent to the client
158+ }
159+
141160func TestContextRenderErrorsOnNoRenderer (t * testing.T ) {
142161 e := New ()
143162 req := httptest .NewRequest (http .MethodPost , "/" , strings .NewReader (userJSON ))
@@ -173,10 +192,9 @@ func TestContextStream(t *testing.T) {
173192}
174193
175194func TestContextHTML (t * testing.T ) {
176- e := New ()
177195 rec := httptest .NewRecorder ()
178196 req := httptest .NewRequest (http .MethodGet , "/" , nil )
179- c := e . NewContext (req , rec )
197+ c := NewContext (req , rec )
180198
181199 err := c .HTML (http .StatusOK , "Hi, Jon Snow" )
182200 if assert .NoError (t , err ) {
@@ -187,10 +205,9 @@ func TestContextHTML(t *testing.T) {
187205}
188206
189207func TestContextHTMLBlob (t * testing.T ) {
190- e := New ()
191208 rec := httptest .NewRecorder ()
192209 req := httptest .NewRequest (http .MethodGet , "/" , nil )
193- c := e . NewContext (req , rec )
210+ c := NewContext (req , rec )
194211
195212 err := c .HTMLBlob (http .StatusOK , []byte ("Hi, Jon Snow" ))
196213 if assert .NoError (t , err ) {
@@ -222,6 +239,24 @@ func TestContextJSONErrorsOut(t *testing.T) {
222239
223240 err := c .JSON (http .StatusOK , make (chan bool ))
224241 assert .EqualError (t , err , "json: unsupported type: chan bool" )
242+
243+ assert .Equal (t , http .StatusOK , rec .Code ) // status code must not be sent to the client
244+ assert .Empty (t , rec .Body .String ()) // body must not be sent to the client
245+ }
246+
247+ func TestContextJSONWithNotEchoResponse (t * testing.T ) {
248+ e := New ()
249+ rec := httptest .NewRecorder ()
250+ req := httptest .NewRequest (http .MethodPost , "/" , strings .NewReader (userJSON ))
251+ c := e .NewContext (req , rec )
252+
253+ c .SetResponse (rec )
254+
255+ err := c .JSON (http .StatusCreated , map [string ]float64 {"foo" : math .NaN ()})
256+ assert .EqualError (t , err , "json: unsupported value: NaN" )
257+
258+ assert .Equal (t , http .StatusOK , rec .Code ) // status code must not be sent to the client
259+ assert .Empty (t , rec .Body .String ()) // body must not be sent to the client
225260}
226261
227262func TestContextJSONPretty (t * testing.T ) {
0 commit comments