1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
16 "git.arvados.org/arvados.git/sdk/go/arvadostest"
17 check "gopkg.in/check.v1"
23 token string // default is ActiveTokenV2; use noToken to omit
24 param map[string]interface{}
25 attrs map[string]interface{}
29 // variations on request formatting
40 const noToken = "(no token)"
42 func (tr *testReq) Request() *http.Request {
43 param := map[string]interface{}{}
44 for k, v := range tr.param {
49 // caller provided a buffer
52 for k, v := range tr.attrs {
53 if tr.jsonStringParam {
54 j, err := json.Marshal(v)
63 } else if tr.attrs != nil {
64 if tr.jsonStringParam {
65 j, err := json.Marshal(tr.attrs)
69 param[tr.attrsKey] = string(j)
71 param[tr.attrsKey] = tr.attrs
74 tr.body = bytes.NewBuffer(nil)
75 err := json.NewEncoder(tr.body).Encode(param)
80 values := make(url.Values)
81 for k, v := range param {
82 if vs, ok := v.(string); ok && !tr.jsonStringParam {
85 jv, err := json.Marshal(v)
89 values.Set(k, string(jv))
93 jattrs, err := json.Marshal(tr.attrs)
97 values.Set(tr.attrsKey, string(jattrs))
99 tr.body = bytes.NewBuffer(nil)
100 io.WriteString(tr.body, values.Encode())
108 path = "example/test/path"
110 req := httptest.NewRequest(method, "https://an.example/"+path, tr.body)
113 token = arvadostest.ActiveTokenV2
115 if token != noToken {
116 req.Header.Set("Authorization", "Bearer "+token)
119 req.Header.Set("Content-Type", "application/json")
120 } else if tr.header.Get("Content-Type") == "" {
121 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
123 for k, v := range tr.header {
124 req.Header[k] = append([]string(nil), v...)
129 func (tr *testReq) bodyContent() string {
130 return string(tr.body.Bytes())
133 func (s *RouterSuite) TestAttrsInBody(c *check.C) {
134 attrs := map[string]interface{}{"foo": "bar"}
136 multipartBody := new(bytes.Buffer)
137 multipartWriter := multipart.NewWriter(multipartBody)
138 multipartWriter.WriteField("attrs", `{"foo":"bar"}`)
139 multipartWriter.Close()
141 for _, tr := range []testReq{
142 {attrsKey: "model_name", json: true, attrs: attrs},
143 {attrsKey: "model_name", json: true, attrs: attrs, jsonAttrsTop: true},
144 {attrsKey: "model_name", json: true, attrs: attrs, jsonAttrsTop: true, jsonStringParam: true},
145 {attrsKey: "model_name", json: true, attrs: attrs, jsonAttrsTop: false, jsonStringParam: true},
146 {body: multipartBody, header: http.Header{"Content-Type": []string{multipartWriter.FormDataContentType()}}},
148 c.Logf("tr: %#v", tr)
150 params, err := s.rtr.loadRequestParams(req, tr.attrsKey)
151 c.Logf("params: %#v", params)
152 c.Assert(err, check.IsNil)
153 c.Check(params, check.NotNil)
154 c.Assert(params["attrs"], check.FitsTypeOf, map[string]interface{}{})
155 c.Check(params["attrs"].(map[string]interface{})["foo"], check.Equals, "bar")
159 func (s *RouterSuite) TestBoolParam(c *check.C) {
160 testKey := "ensure_unique_name"
162 for i, tr := range []testReq{
163 {method: "POST", param: map[string]interface{}{testKey: false}, json: true},
164 {method: "POST", param: map[string]interface{}{testKey: false}},
165 {method: "POST", param: map[string]interface{}{testKey: "false"}},
166 {method: "POST", param: map[string]interface{}{testKey: "0"}},
167 {method: "POST", param: map[string]interface{}{testKey: ""}},
169 c.Logf("#%d, tr: %#v", i, tr)
171 c.Logf("tr.body: %s", tr.bodyContent())
172 params, err := s.rtr.loadRequestParams(req, tr.attrsKey)
173 c.Logf("params: %#v", params)
174 c.Assert(err, check.IsNil)
175 c.Check(params, check.NotNil)
176 c.Check(params[testKey], check.Equals, false)
179 for i, tr := range []testReq{
180 {method: "POST", param: map[string]interface{}{testKey: true}, json: true},
181 {method: "POST", param: map[string]interface{}{testKey: true}},
182 {method: "POST", param: map[string]interface{}{testKey: "true"}},
183 {method: "POST", param: map[string]interface{}{testKey: "1"}},
185 c.Logf("#%d, tr: %#v", i, tr)
187 c.Logf("tr.body: %s", tr.bodyContent())
188 params, err := s.rtr.loadRequestParams(req, tr.attrsKey)
189 c.Logf("params: %#v", params)
190 c.Assert(err, check.IsNil)
191 c.Check(params, check.NotNil)
192 c.Check(params[testKey], check.Equals, true)
196 func (s *RouterSuite) TestOrderParam(c *check.C) {
197 for i, tr := range []testReq{
198 {method: "POST", param: map[string]interface{}{"order": ""}, json: true},
199 {method: "POST", param: map[string]interface{}{"order": ""}, json: false},
200 {method: "POST", param: map[string]interface{}{"order": []string{}}, json: true},
201 {method: "POST", param: map[string]interface{}{"order": []string{}}, json: false},
202 {method: "POST", param: map[string]interface{}{}, json: true},
203 {method: "POST", param: map[string]interface{}{}, json: false},
205 c.Logf("#%d, tr: %#v", i, tr)
207 params, err := s.rtr.loadRequestParams(req, tr.attrsKey)
208 c.Assert(err, check.IsNil)
209 c.Assert(params, check.NotNil)
210 if order, ok := params["order"]; ok && order != nil {
211 c.Check(order, check.DeepEquals, []interface{}{})
215 for i, tr := range []testReq{
216 {method: "POST", param: map[string]interface{}{"order": "foo,bar desc"}, json: true},
217 {method: "POST", param: map[string]interface{}{"order": "foo,bar desc"}, json: false},
218 {method: "POST", param: map[string]interface{}{"order": "[\"foo\", \"bar desc\"]"}, json: false},
219 {method: "POST", param: map[string]interface{}{"order": []string{"foo", "bar desc"}}, json: true},
220 {method: "POST", param: map[string]interface{}{"order": []string{"foo", "bar desc"}}, json: false},
222 c.Logf("#%d, tr: %#v", i, tr)
224 params, err := s.rtr.loadRequestParams(req, tr.attrsKey)
225 c.Assert(err, check.IsNil)
226 if _, ok := params["order"].([]string); ok {
227 c.Check(params["order"], check.DeepEquals, []string{"foo", "bar desc"})
229 c.Check(params["order"], check.DeepEquals, []interface{}{"foo", "bar desc"})