github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/fs/rc/params_test.go (about) 1 package rc 2 3 import ( 4 "errors" 5 "fmt" 6 "net/http" 7 "net/http/httptest" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 14 "github.com/rclone/rclone/fs" 15 ) 16 17 func TestErrParamNotFoundError(t *testing.T) { 18 e := ErrParamNotFound("key") 19 assert.Equal(t, "Didn't find key \"key\" in input", e.Error()) 20 } 21 22 func TestIsErrParamNotFound(t *testing.T) { 23 assert.Equal(t, true, IsErrParamNotFound(ErrParamNotFound("key"))) 24 assert.Equal(t, false, IsErrParamNotFound(nil)) 25 assert.Equal(t, false, IsErrParamNotFound(errors.New("potato"))) 26 } 27 28 func TestNotErrParamNotFound(t *testing.T) { 29 assert.Equal(t, false, NotErrParamNotFound(ErrParamNotFound("key"))) 30 assert.Equal(t, false, NotErrParamNotFound(nil)) 31 assert.Equal(t, true, NotErrParamNotFound(errors.New("potato"))) 32 } 33 34 func TestIsErrParamInvalid(t *testing.T) { 35 e := ErrParamInvalid{errors.New("potato")} 36 assert.Equal(t, true, IsErrParamInvalid(e)) 37 assert.Equal(t, false, IsErrParamInvalid(nil)) 38 assert.Equal(t, false, IsErrParamInvalid(errors.New("potato"))) 39 } 40 41 func TestReshape(t *testing.T) { 42 in := Params{ 43 "String": "hello", 44 "Float": 4.2, 45 } 46 var out struct { 47 String string 48 Float float64 49 } 50 require.NoError(t, Reshape(&out, in)) 51 assert.Equal(t, "hello", out.String) 52 assert.Equal(t, 4.2, out.Float) 53 var inCopy = Params{} 54 require.NoError(t, Reshape(&inCopy, out)) 55 assert.Equal(t, in, inCopy) 56 57 // Now a failure to marshal 58 var in2 func() 59 require.Error(t, Reshape(&inCopy, in2)) 60 61 // Now a failure to unmarshal 62 require.Error(t, Reshape(&out, "string")) 63 64 } 65 66 func TestParamsCopy(t *testing.T) { 67 in := Params{ 68 "ok": 1, 69 "x": "seventeen", 70 "nil": nil, 71 } 72 out := in.Copy() 73 assert.Equal(t, in, out) 74 if &in == &out { 75 t.Error("didn't copy") 76 } 77 } 78 79 func TestParamsGet(t *testing.T) { 80 in := Params{ 81 "ok": 1, 82 } 83 v1, e1 := in.Get("ok") 84 assert.NoError(t, e1) 85 assert.Equal(t, 1, v1) 86 v2, e2 := in.Get("notOK") 87 assert.Error(t, e2) 88 assert.Equal(t, nil, v2) 89 assert.Equal(t, ErrParamNotFound("notOK"), e2) 90 } 91 92 func TestParamsGetString(t *testing.T) { 93 in := Params{ 94 "string": "one", 95 "notString": 17, 96 } 97 v1, e1 := in.GetString("string") 98 assert.NoError(t, e1) 99 assert.Equal(t, "one", v1) 100 v2, e2 := in.GetString("notOK") 101 assert.Error(t, e2) 102 assert.Equal(t, "", v2) 103 assert.Equal(t, ErrParamNotFound("notOK"), e2) 104 v3, e3 := in.GetString("notString") 105 assert.Error(t, e3) 106 assert.Equal(t, "", v3) 107 assert.Equal(t, true, IsErrParamInvalid(e3), e3.Error()) 108 } 109 110 func TestParamsGetInt64(t *testing.T) { 111 for _, test := range []struct { 112 value interface{} 113 result int64 114 errString string 115 }{ 116 {"123", 123, ""}, 117 {"123x", 0, "couldn't parse"}, 118 {int(12), 12, ""}, 119 {int64(13), 13, ""}, 120 {float64(14), 14, ""}, 121 {float64(9.3e18), 0, "overflows int64"}, 122 {float64(-9.3e18), 0, "overflows int64"}, 123 } { 124 t.Run(fmt.Sprintf("%T=%v", test.value, test.value), func(t *testing.T) { 125 in := Params{ 126 "key": test.value, 127 } 128 v1, e1 := in.GetInt64("key") 129 if test.errString == "" { 130 require.NoError(t, e1) 131 assert.Equal(t, test.result, v1) 132 } else { 133 require.NotNil(t, e1) 134 require.Error(t, e1) 135 assert.Contains(t, e1.Error(), test.errString) 136 assert.Equal(t, int64(0), v1) 137 } 138 }) 139 } 140 in := Params{ 141 "notInt64": []string{"a", "b"}, 142 } 143 v2, e2 := in.GetInt64("notOK") 144 assert.Error(t, e2) 145 assert.Equal(t, int64(0), v2) 146 assert.Equal(t, ErrParamNotFound("notOK"), e2) 147 v3, e3 := in.GetInt64("notInt64") 148 assert.Error(t, e3) 149 assert.Equal(t, int64(0), v3) 150 assert.Equal(t, true, IsErrParamInvalid(e3), e3.Error()) 151 } 152 153 func TestParamsGetFloat64(t *testing.T) { 154 for _, test := range []struct { 155 value interface{} 156 result float64 157 errString string 158 }{ 159 {"123.1", 123.1, ""}, 160 {"123x1", 0, "couldn't parse"}, 161 {int(12), 12, ""}, 162 {int64(13), 13, ""}, 163 {float64(14), 14, ""}, 164 } { 165 t.Run(fmt.Sprintf("%T=%v", test.value, test.value), func(t *testing.T) { 166 in := Params{ 167 "key": test.value, 168 } 169 v1, e1 := in.GetFloat64("key") 170 if test.errString == "" { 171 require.NoError(t, e1) 172 assert.Equal(t, test.result, v1) 173 } else { 174 require.NotNil(t, e1) 175 require.Error(t, e1) 176 assert.Contains(t, e1.Error(), test.errString) 177 assert.Equal(t, float64(0), v1) 178 } 179 }) 180 } 181 in := Params{ 182 "notFloat64": []string{"a", "b"}, 183 } 184 v2, e2 := in.GetFloat64("notOK") 185 assert.Error(t, e2) 186 assert.Equal(t, float64(0), v2) 187 assert.Equal(t, ErrParamNotFound("notOK"), e2) 188 v3, e3 := in.GetFloat64("notFloat64") 189 assert.Error(t, e3) 190 assert.Equal(t, float64(0), v3) 191 assert.Equal(t, true, IsErrParamInvalid(e3), e3.Error()) 192 } 193 194 func TestParamsGetDuration(t *testing.T) { 195 for _, test := range []struct { 196 value interface{} 197 result time.Duration 198 errString string 199 }{ 200 {"86400", time.Hour * 24, ""}, 201 {"1y", time.Hour * 24 * 365, ""}, 202 {"60", time.Minute * 1, ""}, 203 {"0", 0, ""}, 204 {"-45", -time.Second * 45, ""}, 205 {"2", time.Second * 2, ""}, 206 {"2h4m7s", time.Hour*2 + 4*time.Minute + 7*time.Second, ""}, 207 {"3d", time.Hour * 24 * 3, ""}, 208 {"off", time.Duration(fs.DurationOff), ""}, 209 {"", 0, "parse duration"}, 210 {12, 0, "expecting string"}, 211 {"34y", time.Hour * 24 * 365 * 34, ""}, 212 {"30d", time.Hour * 24 * 30, ""}, 213 {"2M", time.Hour * 24 * 60, ""}, 214 {"wrong", 0, "parse duration"}, 215 } { 216 t.Run(fmt.Sprintf("%T=%v", test.value, test.value), func(t *testing.T) { 217 in := Params{ 218 "key": test.value, 219 } 220 v1, e1 := in.GetDuration("key") 221 if test.errString == "" { 222 require.NoError(t, e1) 223 assert.Equal(t, test.result, v1) 224 } else { 225 require.NotNil(t, e1) 226 require.Error(t, e1) 227 assert.Contains(t, e1.Error(), test.errString) 228 assert.Equal(t, time.Duration(0), v1) 229 } 230 }) 231 } 232 in := Params{ 233 "notDuration": []string{"a", "b"}, 234 } 235 v2, e2 := in.GetDuration("notOK") 236 assert.Error(t, e2) 237 assert.Equal(t, time.Duration(0), v2) 238 assert.Equal(t, ErrParamNotFound("notOK"), e2) 239 v3, e3 := in.GetDuration("notDuration") 240 assert.Error(t, e3) 241 assert.Equal(t, time.Duration(0), v3) 242 assert.Equal(t, true, IsErrParamInvalid(e3), e3.Error()) 243 } 244 245 func TestParamsGetBool(t *testing.T) { 246 for _, test := range []struct { 247 value interface{} 248 result bool 249 errString string 250 }{ 251 {true, true, ""}, 252 {false, false, ""}, 253 {"true", true, ""}, 254 {"false", false, ""}, 255 {"fasle", false, "couldn't parse"}, 256 {int(12), true, ""}, 257 {int(0), false, ""}, 258 {int64(13), true, ""}, 259 {int64(0), false, ""}, 260 {float64(14), true, ""}, 261 {float64(0), false, ""}, 262 } { 263 t.Run(fmt.Sprintf("%T=%v", test.value, test.value), func(t *testing.T) { 264 in := Params{ 265 "key": test.value, 266 } 267 v1, e1 := in.GetBool("key") 268 if test.errString == "" { 269 require.NoError(t, e1) 270 assert.Equal(t, test.result, v1) 271 } else { 272 require.NotNil(t, e1) 273 require.Error(t, e1) 274 assert.Contains(t, e1.Error(), test.errString) 275 assert.Equal(t, false, v1) 276 } 277 }) 278 } 279 in := Params{ 280 "notBool": []string{"a", "b"}, 281 } 282 v2, e2 := Params{}.GetBool("notOK") 283 assert.Error(t, e2) 284 assert.Equal(t, false, v2) 285 assert.Equal(t, ErrParamNotFound("notOK"), e2) 286 v3, e3 := in.GetBool("notBool") 287 assert.Error(t, e3) 288 assert.Equal(t, false, v3) 289 assert.Equal(t, true, IsErrParamInvalid(e3), e3.Error()) 290 } 291 292 func TestParamsGetStruct(t *testing.T) { 293 in := Params{ 294 "struct": Params{ 295 "String": "one", 296 "Float": 4.2, 297 }, 298 } 299 var out struct { 300 String string 301 Float float64 302 } 303 e1 := in.GetStruct("struct", &out) 304 assert.NoError(t, e1) 305 assert.Equal(t, "one", out.String) 306 assert.Equal(t, 4.2, out.Float) 307 308 e2 := in.GetStruct("notOK", &out) 309 assert.Error(t, e2) 310 assert.Equal(t, "one", out.String) 311 assert.Equal(t, 4.2, out.Float) 312 assert.Equal(t, ErrParamNotFound("notOK"), e2) 313 314 in["struct"] = "string" 315 e3 := in.GetStruct("struct", &out) 316 assert.Error(t, e3) 317 assert.Equal(t, "one", out.String) 318 assert.Equal(t, 4.2, out.Float) 319 assert.Equal(t, true, IsErrParamInvalid(e3), e3.Error()) 320 } 321 322 func TestParamsGetStructString(t *testing.T) { 323 in := Params{ 324 "struct": `{"String": "one", "Float": 4.2}`, 325 } 326 var out struct { 327 String string 328 Float float64 329 } 330 e1 := in.GetStruct("struct", &out) 331 assert.NoError(t, e1) 332 assert.Equal(t, "one", out.String) 333 assert.Equal(t, 4.2, out.Float) 334 } 335 336 func TestParamsGetStructMissingOK(t *testing.T) { 337 in := Params{ 338 "struct": Params{ 339 "String": "one", 340 "Float": 4.2, 341 }, 342 } 343 var out struct { 344 String string 345 Float float64 346 } 347 e1 := in.GetStructMissingOK("struct", &out) 348 assert.NoError(t, e1) 349 assert.Equal(t, "one", out.String) 350 assert.Equal(t, 4.2, out.Float) 351 352 e2 := in.GetStructMissingOK("notOK", &out) 353 assert.NoError(t, e2) 354 assert.Equal(t, "one", out.String) 355 assert.Equal(t, 4.2, out.Float) 356 357 in["struct"] = "string" 358 e3 := in.GetStructMissingOK("struct", &out) 359 assert.Error(t, e3) 360 assert.Equal(t, "one", out.String) 361 assert.Equal(t, 4.2, out.Float) 362 assert.Equal(t, true, IsErrParamInvalid(e3), e3.Error()) 363 } 364 365 func TestParamsGetHTTPRequest(t *testing.T) { 366 in := Params{} 367 req, err := in.GetHTTPRequest() 368 assert.Nil(t, req) 369 assert.Error(t, err) 370 assert.Equal(t, true, IsErrParamNotFound(err), err.Error()) 371 372 in = Params{ 373 "_request": 42, 374 } 375 req, err = in.GetHTTPRequest() 376 assert.Nil(t, req) 377 assert.Error(t, err) 378 assert.Equal(t, true, IsErrParamInvalid(err), err.Error()) 379 380 r := new(http.Request) 381 in = Params{ 382 "_request": r, 383 } 384 req, err = in.GetHTTPRequest() 385 assert.NotNil(t, req) 386 assert.NoError(t, err) 387 assert.Equal(t, r, req) 388 } 389 390 func TestParamsGetHTTPResponseWriter(t *testing.T) { 391 in := Params{} 392 wr, err := in.GetHTTPResponseWriter() 393 assert.Nil(t, wr) 394 assert.Error(t, err) 395 assert.Equal(t, true, IsErrParamNotFound(err), err.Error()) 396 397 in = Params{ 398 "_response": 42, 399 } 400 wr, err = in.GetHTTPResponseWriter() 401 assert.Nil(t, wr) 402 assert.Error(t, err) 403 assert.Equal(t, true, IsErrParamInvalid(err), err.Error()) 404 405 var w http.ResponseWriter = httptest.NewRecorder() 406 in = Params{ 407 "_response": w, 408 } 409 wr, err = in.GetHTTPResponseWriter() 410 assert.NotNil(t, wr) 411 assert.NoError(t, err) 412 assert.Equal(t, w, wr) 413 }