aboutsummaryrefslogtreecommitdiffhomepage
path: root/http/response/builder_test.go
diff options
context:
space:
mode:
authorGravatar Frédéric Guillot <fred@miniflux.net>2018-10-07 18:42:43 -0700
committerGravatar Frédéric Guillot <fred@miniflux.net>2018-10-08 15:31:58 -0700
commit1f58b37a5e86603b16e137031c36f37580e9d410 (patch)
tree337a7299e91fe7640b64489357dfe7c0f00e2313 /http/response/builder_test.go
parentddfe969d6cbc8d23326cb9a3ca9a265d4e9d3e45 (diff)
Refactor HTTP response builder
Diffstat (limited to 'http/response/builder_test.go')
-rw-r--r--http/response/builder_test.go351
1 files changed, 351 insertions, 0 deletions
diff --git a/http/response/builder_test.go b/http/response/builder_test.go
new file mode 100644
index 0000000..f4fef47
--- /dev/null
+++ b/http/response/builder_test.go
@@ -0,0 +1,351 @@
+// Copyright 2018 Frédéric Guillot. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+package response // import "miniflux.app/http/response"
+
+import (
+ "errors"
+ "net/http"
+ "net/http/httptest"
+ "strings"
+ "testing"
+ "time"
+)
+
+func TestResponseHasCommonHeaders(t *testing.T) {
+ r, err := http.NewRequest("GET", "/", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).Write()
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ headers := map[string]string{
+ "X-XSS-Protection": "1; mode=block",
+ "X-Content-Type-Options": "nosniff",
+ "X-Frame-Options": "DENY",
+ "Content-Security-Policy": "default-src 'self'; img-src *; media-src *; frame-src *; child-src *",
+ }
+
+ for header, expected := range headers {
+ actual := resp.Header.Get(header)
+ if actual != expected {
+ t.Fatalf(`Unexpected header value, got %q instead of %q`, actual, expected)
+ }
+ }
+}
+
+func TestBuildResponseWithCustomStatusCode(t *testing.T) {
+ r, err := http.NewRequest("GET", "/", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithStatus(http.StatusNotAcceptable).Write()
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ expectedStatusCode := http.StatusNotAcceptable
+ if resp.StatusCode != expectedStatusCode {
+ t.Fatalf(`Unexpected status code, got %d instead of %d`, resp.StatusCode, expectedStatusCode)
+ }
+}
+
+func TestBuildResponseWithCustomHeader(t *testing.T) {
+ r, err := http.NewRequest("GET", "/", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithHeader("X-My-Header", "Value").Write()
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ expected := "Value"
+ actual := resp.Header.Get("X-My-Header")
+ if actual != expected {
+ t.Fatalf(`Unexpected header value, got %q instead of %q`, actual, expected)
+ }
+}
+
+func TestBuildResponseWithAttachment(t *testing.T) {
+ r, err := http.NewRequest("GET", "/", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithAttachment("my_file.pdf").Write()
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ expected := "attachment; filename=my_file.pdf"
+ actual := resp.Header.Get("Content-Disposition")
+ if actual != expected {
+ t.Fatalf(`Unexpected header value, got %q instead of %q`, actual, expected)
+ }
+}
+
+func TestBuildResponseWithError(t *testing.T) {
+ r, err := http.NewRequest("GET", "/", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithBody(errors.New("Some error")).Write()
+ })
+
+ handler.ServeHTTP(w, r)
+
+ expectedBody := `Some error`
+ actualBody := w.Body.String()
+ if actualBody != expectedBody {
+ t.Fatalf(`Unexpected body, got %s instead of %s`, actualBody, expectedBody)
+ }
+}
+
+func TestBuildResponseWithByteBody(t *testing.T) {
+ r, err := http.NewRequest("GET", "/", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithBody([]byte("body")).Write()
+ })
+
+ handler.ServeHTTP(w, r)
+
+ expectedBody := `body`
+ actualBody := w.Body.String()
+ if actualBody != expectedBody {
+ t.Fatalf(`Unexpected body, got %s instead of %s`, actualBody, expectedBody)
+ }
+}
+
+func TestBuildResponseWithCachingEnabled(t *testing.T) {
+ r, err := http.NewRequest("GET", "/", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithCaching("etag", 1*time.Minute, func(b *Builder) {
+ b.WithBody("cached body")
+ b.Write()
+ })
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ expectedStatusCode := http.StatusOK
+ if resp.StatusCode != expectedStatusCode {
+ t.Fatalf(`Unexpected status code, got %d instead of %d`, resp.StatusCode, expectedStatusCode)
+ }
+
+ expectedBody := `cached body`
+ actualBody := w.Body.String()
+ if actualBody != expectedBody {
+ t.Fatalf(`Unexpected body, got %s instead of %s`, actualBody, expectedBody)
+ }
+
+ expectedHeader := "public"
+ actualHeader := resp.Header.Get("Cache-Control")
+ if actualHeader != expectedHeader {
+ t.Fatalf(`Unexpected cache control header, got %q instead of %q`, actualHeader, expectedHeader)
+ }
+
+ if resp.Header.Get("Expires") == "" {
+ t.Fatalf(`Expires header should not be empty`)
+ }
+}
+
+func TestBuildResponseWithCachingAndEtag(t *testing.T) {
+ r, err := http.NewRequest("GET", "/", nil)
+ r.Header.Set("If-None-Match", "etag")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithCaching("etag", 1*time.Minute, func(b *Builder) {
+ b.WithBody("cached body")
+ b.Write()
+ })
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ expectedStatusCode := http.StatusNotModified
+ if resp.StatusCode != expectedStatusCode {
+ t.Fatalf(`Unexpected status code, got %d instead of %d`, resp.StatusCode, expectedStatusCode)
+ }
+
+ expectedBody := ``
+ actualBody := w.Body.String()
+ if actualBody != expectedBody {
+ t.Fatalf(`Unexpected body, got %s instead of %s`, actualBody, expectedBody)
+ }
+
+ expectedHeader := "public"
+ actualHeader := resp.Header.Get("Cache-Control")
+ if actualHeader != expectedHeader {
+ t.Fatalf(`Unexpected cache control header, got %q instead of %q`, actualHeader, expectedHeader)
+ }
+
+ if resp.Header.Get("Expires") == "" {
+ t.Fatalf(`Expires header should not be empty`)
+ }
+}
+
+func TestBuildResponseWithGzipCompression(t *testing.T) {
+ body := strings.Repeat("a", compressionThreshold+1)
+ r, err := http.NewRequest("GET", "/", nil)
+ r.Header.Set("Accept-Encoding", "gzip, deflate, br")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithBody(body).Write()
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ expected := "gzip"
+ actual := resp.Header.Get("Content-Encoding")
+ if actual != expected {
+ t.Fatalf(`Unexpected header value, got %q instead of %q`, actual, expected)
+ }
+}
+
+func TestBuildResponseWithDeflateCompression(t *testing.T) {
+ body := strings.Repeat("a", compressionThreshold+1)
+ r, err := http.NewRequest("GET", "/", nil)
+ r.Header.Set("Accept-Encoding", "deflate")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithBody(body).Write()
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ expected := "deflate"
+ actual := resp.Header.Get("Content-Encoding")
+ if actual != expected {
+ t.Fatalf(`Unexpected header value, got %q instead of %q`, actual, expected)
+ }
+}
+
+func TestBuildResponseWithCompressionDisabled(t *testing.T) {
+ body := strings.Repeat("a", compressionThreshold+1)
+ r, err := http.NewRequest("GET", "/", nil)
+ r.Header.Set("Accept-Encoding", "deflate")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithBody(body).WithoutCompression().Write()
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ expected := ""
+ actual := resp.Header.Get("Content-Encoding")
+ if actual != expected {
+ t.Fatalf(`Unexpected header value, got %q instead of %q`, actual, expected)
+ }
+}
+
+func TestBuildResponseWithDeflateCompressionAndSmallPayload(t *testing.T) {
+ body := strings.Repeat("a", compressionThreshold)
+ r, err := http.NewRequest("GET", "/", nil)
+ r.Header.Set("Accept-Encoding", "deflate")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithBody(body).Write()
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ expected := ""
+ actual := resp.Header.Get("Content-Encoding")
+ if actual != expected {
+ t.Fatalf(`Unexpected header value, got %q instead of %q`, actual, expected)
+ }
+}
+
+func TestBuildResponseWithoutCompressionHeader(t *testing.T) {
+ body := strings.Repeat("a", compressionThreshold+1)
+ r, err := http.NewRequest("GET", "/", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ w := httptest.NewRecorder()
+
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ New(w, r).WithBody(body).Write()
+ })
+
+ handler.ServeHTTP(w, r)
+ resp := w.Result()
+
+ expected := ""
+ actual := resp.Header.Get("Content-Encoding")
+ if actual != expected {
+ t.Fatalf(`Unexpected header value, got %q instead of %q`, actual, expected)
+ }
+}