+ // POST & PUT
+ uuid = arvadostest.FooCollection
+ j, err := json.Marshal([]string{"uuid", "description"})
+ c.Assert(err, check.IsNil)
+ for _, method := range []string{"PUT", "POST"} {
+ desc := "Today is " + time.Now().String()
+ reqBody := "{\"description\":\"" + desc + "\"}"
+ var resp map[string]interface{}
+ var rr *httptest.ResponseRecorder
+ if method == "PUT" {
+ _, rr, resp = doRequest(c, s.rtr, token, method, "/arvados/v1/collections/"+uuid+"?select="+string(j), nil, bytes.NewReader([]byte(reqBody)))
+ } else {
+ _, rr, resp = doRequest(c, s.rtr, token, method, "/arvados/v1/collections?select="+string(j), nil, bytes.NewReader([]byte(reqBody)))
+ }
+ c.Check(rr.Code, check.Equals, http.StatusOK)
+ c.Check(resp["kind"], check.Equals, "arvados#collection")
+ c.Check(resp["uuid"], check.HasLen, 27)
+ c.Check(resp["description"], check.Equals, desc)
+ c.Check(resp["manifest_text"], check.IsNil)
+ }
+}
+
+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