1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
16 "git.arvados.org/arvados.git/sdk/go/arvados"
17 "git.arvados.org/arvados.git/sdk/go/arvadostest"
18 check "gopkg.in/check.v1"
24 token string // default is ActiveTokenV2; use noToken to omit
25 param map[string]interface{}
26 attrs map[string]interface{}
30 // variations on request formatting
41 const noToken = "(no token)"
43 func (tr *testReq) Request() *http.Request {
44 param := map[string]interface{}{}
45 for k, v := range tr.param {
50 // caller provided a buffer
53 for k, v := range tr.attrs {
54 if tr.jsonStringParam {
55 j, err := json.Marshal(v)
64 } else if tr.attrs != nil {
65 if tr.jsonStringParam {
66 j, err := json.Marshal(tr.attrs)
70 param[tr.attrsKey] = string(j)
72 param[tr.attrsKey] = tr.attrs
75 tr.body = bytes.NewBuffer(nil)
76 err := json.NewEncoder(tr.body).Encode(param)
81 values := make(url.Values)
82 for k, v := range param {
83 if vs, ok := v.(string); ok && !tr.jsonStringParam {
86 jv, err := json.Marshal(v)
90 values.Set(k, string(jv))
94 jattrs, err := json.Marshal(tr.attrs)
98 values.Set(tr.attrsKey, string(jattrs))
100 tr.body = bytes.NewBuffer(nil)
101 io.WriteString(tr.body, values.Encode())
109 path = "example/test/path"
111 req := httptest.NewRequest(method, "https://an.example/"+path, tr.body)
114 token = arvadostest.ActiveTokenV2
116 if token != noToken {
117 req.Header.Set("Authorization", "Bearer "+token)
120 req.Header.Set("Content-Type", "application/json")
121 } else if tr.header.Get("Content-Type") == "" {
122 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
124 for k, v := range tr.header {
125 req.Header[k] = append([]string(nil), v...)
130 func (tr *testReq) bodyContent() string {
131 return string(tr.body.Bytes())
134 func (s *RouterSuite) TestAttrsInBody(c *check.C) {
135 attrs := map[string]interface{}{"foo": "bar"}
137 multipartBody := new(bytes.Buffer)
138 multipartWriter := multipart.NewWriter(multipartBody)
139 multipartWriter.WriteField("attrs", `{"foo":"bar"}`)
140 multipartWriter.Close()
142 for _, tr := range []testReq{
143 {attrsKey: "model_name", json: true, attrs: attrs},
144 {attrsKey: "model_name", json: true, attrs: attrs, jsonAttrsTop: true},
145 {attrsKey: "model_name", json: true, attrs: attrs, jsonAttrsTop: true, jsonStringParam: true},
146 {attrsKey: "model_name", json: true, attrs: attrs, jsonAttrsTop: false, jsonStringParam: true},
147 {body: multipartBody, header: http.Header{"Content-Type": []string{multipartWriter.FormDataContentType()}}},
149 c.Logf("tr: %#v", tr)
151 var opts struct{ Attrs struct{ Foo string } }
152 params, err := s.rtr.loadRequestParams(req, tr.attrsKey, &opts)
153 c.Logf("params: %#v", params)
154 c.Assert(err, check.IsNil)
155 c.Check(params, check.NotNil)
156 c.Check(opts.Attrs.Foo, check.Equals, "bar")
157 if c.Check(params["attrs"], check.FitsTypeOf, map[string]interface{}{}) {
158 c.Check(params["attrs"].(map[string]interface{})["foo"], check.Equals, "bar")
163 func (s *RouterSuite) TestBoolParam(c *check.C) {
164 testKey := "ensure_unique_name"
166 for i, tr := range []testReq{
167 {method: "POST", param: map[string]interface{}{testKey: false}, json: true},
168 {method: "POST", param: map[string]interface{}{testKey: false}},
169 {method: "POST", param: map[string]interface{}{testKey: "false"}},
170 {method: "POST", param: map[string]interface{}{testKey: "0"}},
171 {method: "POST", param: map[string]interface{}{testKey: ""}},
173 c.Logf("#%d, tr: %#v", i, tr)
175 c.Logf("tr.body: %s", tr.bodyContent())
176 var opts struct{ EnsureUniqueName bool }
177 params, err := s.rtr.loadRequestParams(req, tr.attrsKey, &opts)
178 c.Logf("params: %#v", params)
179 c.Assert(err, check.IsNil)
180 c.Check(opts.EnsureUniqueName, check.Equals, false)
181 if c.Check(params, check.NotNil) {
182 c.Check(params[testKey], check.Equals, false)
186 for i, tr := range []testReq{
187 {method: "POST", param: map[string]interface{}{testKey: true}, json: true},
188 {method: "POST", param: map[string]interface{}{testKey: true}},
189 {method: "POST", param: map[string]interface{}{testKey: "true"}},
190 {method: "POST", param: map[string]interface{}{testKey: "1"}},
192 c.Logf("#%d, tr: %#v", i, tr)
194 c.Logf("tr.body: %s", tr.bodyContent())
196 EnsureUniqueName bool `json:"ensure_unique_name"`
198 params, err := s.rtr.loadRequestParams(req, tr.attrsKey, &opts)
199 c.Logf("params: %#v", params)
200 c.Assert(err, check.IsNil)
201 c.Check(opts.EnsureUniqueName, check.Equals, true)
202 if c.Check(params, check.NotNil) {
203 c.Check(params[testKey], check.Equals, true)
208 func (s *RouterSuite) TestOrderParam(c *check.C) {
209 for i, tr := range []testReq{
210 {method: "POST", param: map[string]interface{}{"order": ""}, json: true},
211 {method: "POST", param: map[string]interface{}{"order": ""}, json: false},
212 {method: "POST", param: map[string]interface{}{"order": []string{}}, json: true},
213 {method: "POST", param: map[string]interface{}{"order": []string{}}, json: false},
214 {method: "POST", param: map[string]interface{}{}, json: true},
215 {method: "POST", param: map[string]interface{}{}, json: false},
217 c.Logf("#%d, tr: %#v", i, tr)
219 params, err := s.rtr.loadRequestParams(req, tr.attrsKey, nil)
220 c.Assert(err, check.IsNil)
221 c.Assert(params, check.NotNil)
222 if order, ok := params["order"]; ok && order != nil {
223 c.Check(order, check.DeepEquals, []interface{}{})
227 for i, tr := range []testReq{
228 {method: "POST", param: map[string]interface{}{"order": "foo,bar desc"}, json: true},
229 {method: "POST", param: map[string]interface{}{"order": "foo,bar desc"}, json: false},
230 {method: "POST", param: map[string]interface{}{"order": "[\"foo\", \"bar desc\"]"}, json: false},
231 {method: "POST", param: map[string]interface{}{"order": []string{"foo", "bar desc"}}, json: true},
232 {method: "POST", param: map[string]interface{}{"order": []string{"foo", "bar desc"}}, json: false},
234 c.Logf("#%d, tr: %#v", i, tr)
236 var opts arvados.ListOptions
237 params, err := s.rtr.loadRequestParams(req, tr.attrsKey, &opts)
238 c.Assert(err, check.IsNil)
239 c.Check(opts.Order, check.DeepEquals, []string{"foo", "bar desc"})
240 if _, ok := params["order"].([]string); ok {
241 c.Check(params["order"], check.DeepEquals, []string{"foo", "bar desc"})
243 c.Check(params["order"], check.DeepEquals, []interface{}{"foo", "bar desc"})