diff options
author | Frédéric Guillot <fred@miniflux.net> | 2018-10-07 18:42:43 -0700 |
---|---|---|
committer | Frédéric Guillot <fred@miniflux.net> | 2018-10-08 15:31:58 -0700 |
commit | 1f58b37a5e86603b16e137031c36f37580e9d410 (patch) | |
tree | 337a7299e91fe7640b64489357dfe7c0f00e2313 /http/response/builder_test.go | |
parent | ddfe969d6cbc8d23326cb9a3ca9a265d4e9d3e45 (diff) |
Refactor HTTP response builder
Diffstat (limited to 'http/response/builder_test.go')
-rw-r--r-- | http/response/builder_test.go | 351 |
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) + } +} |