From 0a28628c02d486512dc7e62eb54ccfd27eaa0a27 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 10 Jun 2013 13:02:40 -0900 Subject: [PATCH] Add Cors and OPTIONS route unit tests Move creating the router and populating the routes to a separate function outside of ListenAndServe to allow unit tests to make assertions on the configured routes and handler funcs. --- api.go | 23 ++++++++++++++++------- api_test.go | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/api.go b/api.go index 3831f326f2..cc00849a60 100644 --- a/api.go +++ b/api.go @@ -709,9 +709,8 @@ func writeCorsHeaders(w http.ResponseWriter, r *http.Request) { w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS") } -func ListenAndServe(addr string, srv *Server, logging bool) error { +func createRouter(srv *Server, logging bool) (*mux.Router, error) { r := mux.NewRouter() - log.Printf("Listening for HTTP on %s\n", addr) m := map[string]map[string]func(*Server, float64, http.ResponseWriter, *http.Request, map[string]string) error{ "GET": { @@ -788,12 +787,22 @@ func ListenAndServe(addr string, srv *Server, logging bool) error { } r.Path("/v{version:[0-9.]+}" + localRoute).Methods(localMethod).HandlerFunc(f) r.Path(localRoute).Methods(localMethod).HandlerFunc(f) - r.Methods("OPTIONS").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if srv.enableCors { - writeCorsHeaders(w, r) - } - }) } } + r.Methods("OPTIONS").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if srv.enableCors { + writeCorsHeaders(w, r) + } + }) + return r, nil +} + +func ListenAndServe(addr string, srv *Server, logging bool) error { + log.Printf("Listening for HTTP on %s\n", addr) + + r, err := createRouter(srv, logging) + if err != nil { + return err + } return http.ListenAndServe(addr, r) } diff --git a/api_test.go b/api_test.go index e464e51108..748bcf812c 100644 --- a/api_test.go +++ b/api_test.go @@ -1239,6 +1239,32 @@ func TestDeleteContainers(t *testing.T) { } } +func TestOptionsRoute(t *testing.T) { + runtime, err := newTestRuntime() + if err != nil { + t.Fatal(err) + } + defer nuke(runtime) + + srv := &Server{runtime: runtime, enableCors: true} + + r := httptest.NewRecorder() + router, err := createRouter(srv, false) + if err != nil { + t.Fatal(err) + } + + req, err := http.NewRequest("OPTIONS", "/", nil) + if err != nil { + t.Fatal(err) + } + + router.ServeHTTP(r, req) + if r.Code != 200 { + t.Errorf("Expected response for OPTIONS request to be \"200\", %v found.", r.Code) + } +} + func TestGetEnabledCors(t *testing.T) { runtime, err := newTestRuntime() if err != nil { @@ -1250,12 +1276,24 @@ func TestGetEnabledCors(t *testing.T) { r := httptest.NewRecorder() - if err := getVersion(srv, API_VERSION, r, nil, nil); err != nil { + router, err := createRouter(srv, false) + if err != nil { t.Fatal(err) } + req, err := http.NewRequest("GET", "/version", nil) + if err != nil { + t.Fatal(err) + } + + router.ServeHTTP(r, req) + if r.Code != 200 { + t.Errorf("Expected response for OPTIONS request to be \"200\", %v found.", r.Code) + } + allowOrigin := r.Header().Get("Access-Control-Allow-Origin") allowHeaders := r.Header().Get("Access-Control-Allow-Headers") + allowMethods := r.Header().Get("Access-Control-Allow-Methods") if allowOrigin != "*" { t.Errorf("Expected header Access-Control-Allow-Origin to be \"*\", %s found.", allowOrigin) @@ -1263,6 +1301,9 @@ func TestGetEnabledCors(t *testing.T) { if allowHeaders != "Origin, X-Requested-With, Content-Type, Accept" { t.Errorf("Expected header Access-Control-Allow-Headers to be \"Origin, X-Requested-With, Content-Type, Accept\", %s found.", allowHeaders) } + if allowMethods != "GET, POST, DELETE, PUT, OPTIONS" { + t.Errorf("Expected hearder Access-Control-Allow-Methods to be \"GET, POST, DELETE, PUT, OPTIONS\", %s found.", allowMethods) + } } func TestDeleteImages(t *testing.T) {