mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-17 21:01:26 +02:00
tpl/data: Misc header improvements, tests, allow multiple headers of same key
Closes #5617
This commit is contained in:
@@ -14,12 +14,16 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gohugoio/hugo/common/maps"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
)
|
||||
|
||||
@@ -46,12 +50,6 @@ func TestGetCSV(t *testing.T) {
|
||||
"gomeetup,city\nyes,Sydney\nyes,San Francisco\nyes,Stockholm,EXTRA\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
",",
|
||||
`http://error.no.sep/`,
|
||||
"gomeetup;city\nyes;Sydney\nyes;San Francisco\nyes;Stockholm\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
",",
|
||||
`http://nofound/404`,
|
||||
@@ -73,66 +71,54 @@ func TestGetCSV(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
} {
|
||||
msg := qt.Commentf("Test %d", i)
|
||||
|
||||
ns := newTestNs()
|
||||
c.Run(test.url, func(c *qt.C) {
|
||||
msg := qt.Commentf("Test %d", i)
|
||||
|
||||
// Setup HTTP test server
|
||||
var srv *httptest.Server
|
||||
srv, ns.client = getTestServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !haveHeader(r.Header, "Accept", "text/csv") && !haveHeader(r.Header, "Accept", "text/plain") {
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
ns := newTestNs()
|
||||
|
||||
// Setup HTTP test server
|
||||
var srv *httptest.Server
|
||||
srv, ns.client = getTestServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !hasHeaderValue(r.Header, "Accept", "text/csv") && !hasHeaderValue(r.Header, "Accept", "text/plain") {
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if r.URL.Path == "/404" {
|
||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Add("Content-type", "text/csv")
|
||||
|
||||
w.Write([]byte(test.content))
|
||||
})
|
||||
defer func() { srv.Close() }()
|
||||
|
||||
// Setup local test file for schema-less URLs
|
||||
if !strings.Contains(test.url, ":") && !strings.HasPrefix(test.url, "fail/") {
|
||||
f, err := ns.deps.Fs.Source.Create(filepath.Join(ns.deps.Cfg.GetString("workingDir"), test.url))
|
||||
c.Assert(err, qt.IsNil, msg)
|
||||
f.WriteString(test.content)
|
||||
f.Close()
|
||||
}
|
||||
|
||||
// Get on with it
|
||||
got, err := ns.GetCSV(test.sep, test.url)
|
||||
|
||||
if _, ok := test.expect.(bool); ok {
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 1)
|
||||
c.Assert(got, qt.IsNil)
|
||||
return
|
||||
}
|
||||
|
||||
if r.URL.Path == "/404" {
|
||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Add("Content-type", "text/csv")
|
||||
|
||||
w.Write([]byte(test.content))
|
||||
})
|
||||
defer func() { srv.Close() }()
|
||||
|
||||
// Setup local test file for schema-less URLs
|
||||
if !strings.Contains(test.url, ":") && !strings.HasPrefix(test.url, "fail/") {
|
||||
f, err := ns.deps.Fs.Source.Create(filepath.Join(ns.deps.Cfg.GetString("workingDir"), test.url))
|
||||
c.Assert(err, qt.IsNil, msg)
|
||||
f.WriteString(test.content)
|
||||
f.Close()
|
||||
}
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 0)
|
||||
c.Assert(got, qt.Not(qt.IsNil), msg)
|
||||
c.Assert(got, qt.DeepEquals, test.expect, msg)
|
||||
})
|
||||
|
||||
// Get on with it
|
||||
got, err := ns.GetCSV(test.sep, test.url)
|
||||
|
||||
if _, ok := test.expect.(bool); ok {
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 1)
|
||||
// c.Assert(err, msg, qt.Not(qt.IsNil))
|
||||
c.Assert(got, qt.IsNil)
|
||||
continue
|
||||
}
|
||||
|
||||
c.Assert(err, qt.IsNil, msg)
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 0)
|
||||
c.Assert(got, qt.Not(qt.IsNil), msg)
|
||||
c.Assert(got, qt.DeepEquals, test.expect, msg)
|
||||
|
||||
// Test user-defined headers as well
|
||||
gotHeader, _ := ns.GetCSV(test.sep, test.url, map[string]interface{}{"Accept-Charset": "utf-8", "Max-Forwards": "10"})
|
||||
|
||||
if _, ok := test.expect.(bool); ok {
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 1)
|
||||
// c.Assert(err, msg, qt.Not(qt.IsNil))
|
||||
c.Assert(got, qt.IsNil)
|
||||
continue
|
||||
}
|
||||
|
||||
c.Assert(err, qt.IsNil, msg)
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 0)
|
||||
c.Assert(gotHeader, qt.Not(qt.IsNil), msg)
|
||||
c.Assert(gotHeader, qt.DeepEquals, test.expect, msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,68 +164,153 @@ func TestGetJSON(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
|
||||
msg := qt.Commentf("Test %d", i)
|
||||
ns := newTestNs()
|
||||
c.Run(test.url, func(c *qt.C) {
|
||||
|
||||
// Setup HTTP test server
|
||||
var srv *httptest.Server
|
||||
srv, ns.client = getTestServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !haveHeader(r.Header, "Accept", "application/json") {
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
msg := qt.Commentf("Test %d", i)
|
||||
ns := newTestNs()
|
||||
|
||||
// Setup HTTP test server
|
||||
var srv *httptest.Server
|
||||
srv, ns.client = getTestServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !hasHeaderValue(r.Header, "Accept", "application/json") {
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if r.URL.Path == "/404" {
|
||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Add("Content-type", "application/json")
|
||||
|
||||
w.Write([]byte(test.content))
|
||||
})
|
||||
defer func() { srv.Close() }()
|
||||
|
||||
// Setup local test file for schema-less URLs
|
||||
if !strings.Contains(test.url, ":") && !strings.HasPrefix(test.url, "fail/") {
|
||||
f, err := ns.deps.Fs.Source.Create(filepath.Join(ns.deps.Cfg.GetString("workingDir"), test.url))
|
||||
c.Assert(err, qt.IsNil, msg)
|
||||
f.WriteString(test.content)
|
||||
f.Close()
|
||||
}
|
||||
|
||||
// Get on with it
|
||||
got, _ := ns.GetJSON(test.url)
|
||||
|
||||
if _, ok := test.expect.(bool); ok {
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 1)
|
||||
return
|
||||
}
|
||||
|
||||
if r.URL.Path == "/404" {
|
||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 0, msg)
|
||||
c.Assert(got, qt.Not(qt.IsNil), msg)
|
||||
c.Assert(got, qt.DeepEquals, test.expect)
|
||||
|
||||
w.Header().Add("Content-type", "application/json")
|
||||
|
||||
w.Write([]byte(test.content))
|
||||
})
|
||||
defer func() { srv.Close() }()
|
||||
|
||||
// Setup local test file for schema-less URLs
|
||||
if !strings.Contains(test.url, ":") && !strings.HasPrefix(test.url, "fail/") {
|
||||
f, err := ns.deps.Fs.Source.Create(filepath.Join(ns.deps.Cfg.GetString("workingDir"), test.url))
|
||||
c.Assert(err, qt.IsNil, msg)
|
||||
f.WriteString(test.content)
|
||||
f.Close()
|
||||
}
|
||||
|
||||
// Get on with it
|
||||
got, _ := ns.GetJSON(test.url)
|
||||
|
||||
if _, ok := test.expect.(bool); ok {
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 1)
|
||||
// c.Assert(err, msg, qt.Not(qt.IsNil))
|
||||
continue
|
||||
}
|
||||
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 0, msg)
|
||||
c.Assert(got, qt.Not(qt.IsNil), msg)
|
||||
c.Assert(got, qt.DeepEquals, test.expect)
|
||||
|
||||
// Test user-defined headers as well
|
||||
gotHeader, _ := ns.GetJSON(test.url, map[string]interface{}{"Accept-Charset": "utf-8", "Max-Forwards": "10"})
|
||||
|
||||
if _, ok := test.expect.(bool); ok {
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 1)
|
||||
// c.Assert(err, msg, qt.Not(qt.IsNil))
|
||||
continue
|
||||
}
|
||||
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 0, msg)
|
||||
c.Assert(gotHeader, qt.Not(qt.IsNil), msg)
|
||||
c.Assert(gotHeader, qt.DeepEquals, test.expect)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJoinURL(t *testing.T) {
|
||||
func TestHeaders(t *testing.T) {
|
||||
t.Parallel()
|
||||
c := qt.New(t)
|
||||
c.Assert(joinURL([]interface{}{"https://foo?id=", 32}), qt.Equals, "https://foo?id=32")
|
||||
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
headers interface{}
|
||||
assert func(c *qt.C, headers string)
|
||||
}{
|
||||
{
|
||||
`Misc header variants`,
|
||||
map[string]interface{}{
|
||||
"Accept-Charset": "utf-8",
|
||||
"Max-forwards": "10",
|
||||
"X-Int": 32,
|
||||
"X-Templ": template.HTML("a"),
|
||||
"X-Multiple": []string{"a", "b"},
|
||||
"X-MultipleInt": []int{3, 4},
|
||||
},
|
||||
func(c *qt.C, headers string) {
|
||||
c.Assert(headers, qt.Contains, "Accept-Charset: utf-8")
|
||||
c.Assert(headers, qt.Contains, "Max-Forwards: 10")
|
||||
c.Assert(headers, qt.Contains, "X-Int: 32")
|
||||
c.Assert(headers, qt.Contains, "X-Templ: a")
|
||||
c.Assert(headers, qt.Contains, "X-Multiple: a")
|
||||
c.Assert(headers, qt.Contains, "X-Multiple: b")
|
||||
c.Assert(headers, qt.Contains, "X-Multipleint: 3")
|
||||
c.Assert(headers, qt.Contains, "X-Multipleint: 4")
|
||||
c.Assert(headers, qt.Contains, "User-Agent: Hugo Static Site Generator")
|
||||
},
|
||||
},
|
||||
{
|
||||
`Params`,
|
||||
maps.Params{
|
||||
"Accept-Charset": "utf-8",
|
||||
},
|
||||
func(c *qt.C, headers string) {
|
||||
c.Assert(headers, qt.Contains, "Accept-Charset: utf-8")
|
||||
},
|
||||
},
|
||||
{
|
||||
`Override User-Agent`,
|
||||
map[string]interface{}{
|
||||
"User-Agent": "007",
|
||||
},
|
||||
func(c *qt.C, headers string) {
|
||||
c.Assert(headers, qt.Contains, "User-Agent: 007")
|
||||
},
|
||||
},
|
||||
} {
|
||||
|
||||
c.Run(test.name, func(c *qt.C) {
|
||||
|
||||
ns := newTestNs()
|
||||
|
||||
// Setup HTTP test server
|
||||
var srv *httptest.Server
|
||||
var headers bytes.Buffer
|
||||
srv, ns.client = getTestServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
c.Assert(r.URL.String(), qt.Equals, "http://gohugo.io/api?foo")
|
||||
w.Write([]byte("{}"))
|
||||
r.Header.Write(&headers)
|
||||
|
||||
})
|
||||
defer func() { srv.Close() }()
|
||||
|
||||
testFunc := func(fn func(args ...interface{}) error) {
|
||||
defer headers.Reset()
|
||||
err := fn("http://example.org/api", "?foo", test.headers)
|
||||
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(int(ns.deps.Log.LogCounters().ErrorCounter.Count()), qt.Equals, 0)
|
||||
test.assert(c, headers.String())
|
||||
}
|
||||
|
||||
testFunc(func(args ...interface{}) error {
|
||||
_, err := ns.GetJSON(args...)
|
||||
return err
|
||||
})
|
||||
testFunc(func(args ...interface{}) error {
|
||||
_, err := ns.GetCSV(",", args...)
|
||||
return err
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestToURLAndHeaders(t *testing.T) {
|
||||
t.Parallel()
|
||||
c := qt.New(t)
|
||||
url, headers := toURLAndHeaders([]interface{}{"https://foo?id=", 32})
|
||||
c.Assert(url, qt.Equals, "https://foo?id=32")
|
||||
c.Assert(headers, qt.IsNil)
|
||||
|
||||
url, headers = toURLAndHeaders([]interface{}{"https://foo?id=", 32, map[string]interface{}{"a": "b"}})
|
||||
c.Assert(url, qt.Equals, "https://foo?id=32")
|
||||
c.Assert(headers, qt.DeepEquals, map[string]interface{}{"a": "b"})
|
||||
}
|
||||
|
||||
func TestParseCSV(t *testing.T) {
|
||||
@@ -276,19 +347,3 @@ func TestParseCSV(t *testing.T) {
|
||||
c.Assert(act, qt.Equals, test.exp, msg)
|
||||
}
|
||||
}
|
||||
|
||||
func haveHeader(m http.Header, key, needle string) bool {
|
||||
var s []string
|
||||
var ok bool
|
||||
|
||||
if s, ok = m[key]; !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, v := range s {
|
||||
if v == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
Reference in New Issue
Block a user