diff --git a/http/errorpages/errorpages_test.go b/http/errorpages/errorpages_test.go index 4ab90f8f..00a8dc15 100644 --- a/http/errorpages/errorpages_test.go +++ b/http/errorpages/errorpages_test.go @@ -2,14 +2,16 @@ package errorpages import ( "fmt" + "io" "net/http" "net/http/httptest" "os" "testing" + "github.com/tj/assert" + "github.com/apex/up" "github.com/apex/up/config" - "github.com/tj/assert" ) var server = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -24,6 +26,13 @@ var server = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return } + if r.URL.Path == "/400/json" { + w.WriteHeader(400) + w.Header().Set("Content-Type", "application/json") + io.WriteString(w, `{ "error": "bad_request" }`) + return + } + if r.URL.Path == "/500" { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return @@ -36,9 +45,9 @@ var server = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "World") }) -func TestErrors_defaults(t *testing.T) { - os.Chdir("testdata") - defer os.Chdir("..") +func TestErrors_templates(t *testing.T) { + os.Chdir("testdata/templates") + defer os.Chdir("../..") c := &up.Config{Name: "app"} assert.NoError(t, c.Default(), "default") @@ -51,7 +60,7 @@ func TestErrors_dir(t *testing.T) { c := &up.Config{ Name: "app", ErrorPages: config.ErrorPages{ - Dir: "testdata", + Dir: "testdata/templates", }, } @@ -61,22 +70,72 @@ func TestErrors_dir(t *testing.T) { test(t, c) } -func test(t *testing.T, c *up.Config) { +func TestErrors_defaults(t *testing.T) { + os.Chdir("testdata/defaults") + defer os.Chdir("../..") + + c := &up.Config{Name: "app"} + assert.NoError(t, c.Default(), "default") + assert.NoError(t, c.Validate(), "validate") + + h, err := New(c, server) + assert.NoError(t, err, "init") + + t.Run("200", nonError(h)) + t.Run("accepts text/html", acceptsHTML(h)) + t.Run("accepts text/*", acceptsText(h)) + t.Run("does not accept html", doesNotAcceptHTML(h)) +} + +func TestErrors_disabled(t *testing.T) { + c := &up.Config{ + Name: "app", + ErrorPages: config.ErrorPages{ + Disable: true, + }, + } + + assert.NoError(t, c.Default(), "default") + assert.NoError(t, c.Validate(), "validate") + h, err := New(c, server) assert.NoError(t, err, "init") - t.Run("200", func(t *testing.T) { + t.Run("200", nonError(h)) + + t.Run("error", func(t *testing.T) { res := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/", nil) + req := httptest.NewRequest("GET", "/404", nil) h.ServeHTTP(res, req) - assert.Equal(t, 200, res.Code) - assert.Equal(t, "bar", res.Header().Get("X-Foo")) - assert.Equal(t, "text/plain", res.Header().Get("Content-Type")) - assert.Equal(t, "Hello World", res.Body.String()) + assert.Equal(t, 404, res.Code) + assert.Equal(t, "text/plain; charset=utf-8", res.Header().Get("Content-Type")) + assert.Equal(t, "Not Found\n", res.Body.String()) }) + t.Run("json error", func(t *testing.T) { + res := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/400/json", nil) + req.Header.Set("Accept", "application/json") + + h.ServeHTTP(res, req) + + assert.Equal(t, 400, res.Code) + assert.Equal(t, "application/json", res.Header().Get("Content-Type")) + assert.Equal(t, `{ "error": "bad_request" }`, res.Body.String()) + }) +} + +func test(t *testing.T, c *up.Config) { + h, err := New(c, server) + assert.NoError(t, err, "init") + + t.Run("200", nonError(h)) + t.Run("accepts text/html", acceptsHTML(h)) + t.Run("accepts text/*", acceptsText(h)) + t.Run("does not accept html", doesNotAcceptHTML(h)) + t.Run("exact", func(t *testing.T) { res := httptest.NewRecorder() req := httptest.NewRequest("GET", "/404", nil) @@ -101,8 +160,24 @@ func test(t *testing.T, c *up.Config) { assert.Equal(t, "text/html; charset=utf-8", res.Header().Get("Content-Type")) assert.Equal(t, "500 – Internal Server Error\n", res.Body.String()) }) +} - t.Run("default text/html", func(t *testing.T) { +func nonError(h http.Handler) func(t *testing.T) { + return func(t *testing.T) { + res := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/", nil) + + h.ServeHTTP(res, req) + + assert.Equal(t, 200, res.Code) + assert.Equal(t, "bar", res.Header().Get("X-Foo")) + assert.Equal(t, "text/plain", res.Header().Get("Content-Type")) + assert.Equal(t, "Hello World", res.Body.String()) + } +} + +func acceptsHTML(h http.Handler) func(t *testing.T) { + return func(t *testing.T) { res := httptest.NewRecorder() req := httptest.NewRequest("GET", "/400", nil) req.Header.Set("Accept", "text/html") @@ -116,9 +191,11 @@ func test(t *testing.T, c *up.Config) { assert.Contains(t, res.Body.String(), "Bad Request – 400", "title") assert.Contains(t, res.Body.String(), `Bad Request`, "status text") assert.Contains(t, res.Body.String(), `400`, "status code") - }) + } +} - t.Run("default text/*", func(t *testing.T) { +func acceptsText(h http.Handler) func(t *testing.T) { + return func(t *testing.T) { res := httptest.NewRecorder() req := httptest.NewRequest("GET", "/400", nil) req.Header.Set("Accept", "text/*") @@ -132,5 +209,19 @@ func test(t *testing.T, c *up.Config) { assert.Contains(t, res.Body.String(), "Bad Request – 400", "title") assert.Contains(t, res.Body.String(), `Bad Request`, "status text") assert.Contains(t, res.Body.String(), `400`, "status code") - }) + } +} + +func doesNotAcceptHTML(h http.Handler) func(t *testing.T) { + return func(t *testing.T) { + res := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/400/json", nil) + req.Header.Set("Accept", "application/json") + + h.ServeHTTP(res, req) + + assert.Equal(t, 400, res.Code) + assert.Equal(t, "application/json", res.Header().Get("Content-Type")) + assert.Equal(t, `{ "error": "bad_request" }`, res.Body.String()) + } } diff --git a/http/errorpages/testdata/index.html b/http/errorpages/testdata/defaults/index.html similarity index 100% rename from http/errorpages/testdata/index.html rename to http/errorpages/testdata/defaults/index.html diff --git a/http/errorpages/testdata/up.json b/http/errorpages/testdata/defaults/up.json similarity index 100% rename from http/errorpages/testdata/up.json rename to http/errorpages/testdata/defaults/up.json diff --git a/http/errorpages/testdata/404.html b/http/errorpages/testdata/templates/404.html similarity index 100% rename from http/errorpages/testdata/404.html rename to http/errorpages/testdata/templates/404.html diff --git a/http/errorpages/testdata/5xx.html b/http/errorpages/testdata/templates/5xx.html similarity index 100% rename from http/errorpages/testdata/5xx.html rename to http/errorpages/testdata/templates/5xx.html diff --git a/http/errorpages/testdata/templates/index.html b/http/errorpages/testdata/templates/index.html new file mode 100644 index 00000000..a8d87315 --- /dev/null +++ b/http/errorpages/testdata/templates/index.html @@ -0,0 +1 @@ +Index HTML diff --git a/http/errorpages/testdata/templates/up.json b/http/errorpages/testdata/templates/up.json new file mode 100644 index 00000000..fd1f8f63 --- /dev/null +++ b/http/errorpages/testdata/templates/up.json @@ -0,0 +1,3 @@ +{ + "name": "app" +}