diff --git a/content_type.go b/content_type.go index b11a680..beda1c0 100644 --- a/content_type.go +++ b/content_type.go @@ -24,6 +24,7 @@ const ( ContentTypeEventStream ) +// GetContentType returns the ContentType parsed from the given MIME media type string. func GetContentType(s string) ContentType { s = strings.TrimSpace(strings.Split(s, ";")[0]) switch s { @@ -64,6 +65,8 @@ func GetRequestContentType(r *http.Request) ContentType { return GetContentType(r.Header.Get("Content-Type")) } +// GetAcceptedContentType returns the ContentType requested by the client based on +// the context or the request Accept header. func GetAcceptedContentType(r *http.Request) ContentType { if contentType, ok := r.Context().Value(ContentTypeCtxKey).(ContentType); ok { return contentType diff --git a/content_type_test.go b/content_type_test.go new file mode 100644 index 0000000..f74b58c --- /dev/null +++ b/content_type_test.go @@ -0,0 +1,62 @@ +package render + +import ( + "net/http" + "net/http/httptest" + "testing" +) + +func TestGetContentType(t *testing.T) { + tests := []struct { + input string + want ContentType + }{ + {"text/plain", ContentTypePlainText}, + {"text/html", ContentTypeHTML}, + {"application/xhtml+xml", ContentTypeHTML}, + {"application/json", ContentTypeJSON}, + {"text/javascript", ContentTypeJSON}, + {"text/xml", ContentTypeXML}, + {"application/xml", ContentTypeXML}, + {"application/x-www-form-urlencoded", ContentTypeForm}, + {"text/event-stream", ContentTypeEventStream}, + {"application/json; charset=utf-8", ContentTypeJSON}, + {"unknown/type", ContentTypeUnknown}, + } + + for _, tt := range tests { + got := GetContentType(tt.input) + if got != tt.want { + t.Errorf("GetContentType(%q) = %v, want %v", tt.input, got, tt.want) + } + } +} + +func TestGetAcceptedContentType(t *testing.T) { + req := httptest.NewRequest("GET", "/", nil) + req.Header.Set("Accept", "application/json, text/plain") + + if got := GetAcceptedContentType(req); got != ContentTypeJSON { + t.Errorf("GetAcceptedContentType() = %v, want %v", got, ContentTypeJSON) + } + + reqEmpty := httptest.NewRequest("GET", "/", nil) + if got := GetAcceptedContentType(reqEmpty); got != ContentTypePlainText { + t.Errorf("GetAcceptedContentType() for empty Accept = %v, want %v", got, ContentTypePlainText) + } +} + +func TestSetContentType(t *testing.T) { + handler := SetContentType(ContentTypeJSON)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if got := GetRequestContentType(r); got != ContentTypeJSON { + t.Errorf("GetRequestContentType inside handler = %v, want %v", got, ContentTypeJSON) + } + if got := GetAcceptedContentType(r); got != ContentTypeJSON { + t.Errorf("GetAcceptedContentType inside handler = %v, want %v", got, ContentTypeJSON) + } + })) + + req := httptest.NewRequest("GET", "/", nil) + w := httptest.NewRecorder() + handler.ServeHTTP(w, req) +} diff --git a/render.go b/render.go index 75a90e2..04996ac 100644 --- a/render.go +++ b/render.go @@ -24,7 +24,7 @@ func Bind(r *http.Request, v Binder) error { return binder(r, v) } -// Render renders a single payload and respond to the client request. +// Render renders a single payload and responds to the client request. func Render(w http.ResponseWriter, r *http.Request, v Renderer) error { if err := renderer(w, r, v); err != nil { return err