+
+func (s *RouterIntegrationSuite) TestHEAD(c *check.C) {
+ _, rr, _ := doRequest(c, s.rtr, arvadostest.ActiveTokenV2, "HEAD", "/arvados/v1/containers/"+arvadostest.QueuedContainerUUID, nil, nil)
+ c.Check(rr.Code, check.Equals, http.StatusOK)
+}
+
+func (s *RouterIntegrationSuite) TestRouteNotFound(c *check.C) {
+ token := arvadostest.ActiveTokenV2
+ req := (&testReq{
+ method: "POST",
+ path: "arvados/v1/collections/" + arvadostest.FooCollection + "/error404pls",
+ token: token,
+ }).Request()
+ rr := httptest.NewRecorder()
+ s.rtr.ServeHTTP(rr, req)
+ c.Check(rr.Code, check.Equals, http.StatusNotFound)
+ c.Logf("body: %q", rr.Body.String())
+ var j map[string]interface{}
+ err := json.Unmarshal(rr.Body.Bytes(), &j)
+ c.Check(err, check.IsNil)
+ c.Logf("decoded: %v", j)
+ c.Assert(j["errors"], check.FitsTypeOf, []interface{}{})
+ c.Check(j["errors"].([]interface{})[0], check.Equals, "API endpoint not found")
+}
+
+func (s *RouterIntegrationSuite) TestCORS(c *check.C) {
+ token := arvadostest.ActiveTokenV2
+ req := (&testReq{
+ method: "OPTIONS",
+ path: "arvados/v1/collections/" + arvadostest.FooCollection,
+ header: http.Header{"Origin": {"https://example.com"}},
+ token: token,
+ }).Request()
+ rr := httptest.NewRecorder()
+ s.rtr.ServeHTTP(rr, req)
+ c.Check(rr.Code, check.Equals, http.StatusOK)
+ c.Check(rr.Body.String(), check.HasLen, 0)
+ c.Check(rr.Result().Header.Get("Access-Control-Allow-Origin"), check.Equals, "*")
+ for _, hdr := range []string{"Authorization", "Content-Type"} {
+ c.Check(rr.Result().Header.Get("Access-Control-Allow-Headers"), check.Matches, ".*"+hdr+".*")
+ }
+ for _, method := range []string{"GET", "HEAD", "PUT", "POST", "PATCH", "DELETE"} {
+ c.Check(rr.Result().Header.Get("Access-Control-Allow-Methods"), check.Matches, ".*"+method+".*")
+ }
+
+ for _, unsafe := range []string{"login", "logout", "auth", "auth/foo", "login/?blah"} {
+ req := (&testReq{
+ method: "OPTIONS",
+ path: unsafe,
+ header: http.Header{"Origin": {"https://example.com"}},
+ token: token,
+ }).Request()
+ rr := httptest.NewRecorder()
+ s.rtr.ServeHTTP(rr, req)
+ c.Check(rr.Code, check.Equals, http.StatusOK)
+ c.Check(rr.Body.String(), check.HasLen, 0)
+ c.Check(rr.Result().Header.Get("Access-Control-Allow-Origin"), check.Equals, "")
+ c.Check(rr.Result().Header.Get("Access-Control-Allow-Methods"), check.Equals, "")
+ c.Check(rr.Result().Header.Get("Access-Control-Allow-Headers"), check.Equals, "")
+
+ req = (&testReq{
+ method: "POST",
+ path: unsafe,
+ header: http.Header{"Origin": {"https://example.com"}},
+ token: token,
+ }).Request()
+ rr = httptest.NewRecorder()
+ s.rtr.ServeHTTP(rr, req)
+ c.Check(rr.Result().Header.Get("Access-Control-Allow-Origin"), check.Equals, "")
+ c.Check(rr.Result().Header.Get("Access-Control-Allow-Methods"), check.Equals, "")
+ c.Check(rr.Result().Header.Get("Access-Control-Allow-Headers"), check.Equals, "")
+ }
+}
+
+func doRequest(c *check.C, rtr http.Handler, token, method, path string, hdrs http.Header, body io.Reader) (*http.Request, *httptest.ResponseRecorder, map[string]interface{}) {
+ req := httptest.NewRequest(method, path, body)
+ for k, v := range hdrs {
+ req.Header[k] = v
+ }
+ req.Header.Set("Authorization", "Bearer "+token)
+ rr := httptest.NewRecorder()
+ rtr.ServeHTTP(rr, req)
+ c.Logf("response body: %s", rr.Body.String())
+ var jresp map[string]interface{}
+ err := json.Unmarshal(rr.Body.Bytes(), &jresp)
+ c.Check(err, check.IsNil)
+ return req, rr, jresp
+}