github.com/Files-com/files-sdk-go/v3@v3.1.81/file/client_test.go (about) 1 package file 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "io" 8 fs2 "io/fs" 9 "log" 10 "os" 11 "path/filepath" 12 "strings" 13 "sync" 14 "testing" 15 "time" 16 17 files_sdk "github.com/Files-com/files-sdk-go/v3" 18 "github.com/Files-com/files-sdk-go/v3/file/manager" 19 "github.com/Files-com/files-sdk-go/v3/file/status" 20 "github.com/Files-com/files-sdk-go/v3/folder" 21 "github.com/Files-com/files-sdk-go/v3/ignore" 22 "github.com/Files-com/files-sdk-go/v3/lib" 23 "github.com/Files-com/files-sdk-go/v3/lib/test" 24 recorder "github.com/dnaeon/go-vcr/recorder" 25 "github.com/samber/lo" 26 "github.com/stretchr/testify/assert" 27 "github.com/stretchr/testify/require" 28 ) 29 30 func CreateClient(fixture string) (client *Client, r *recorder.Recorder, err error) { 31 client = &Client{} 32 client.Config, r, err = test.CreateConfig(fixture) 33 34 return client, r, err 35 } 36 37 func deletePath(client *Client, path string) { 38 err := client.Delete(files_sdk.FileDeleteParams{Path: path}) 39 var responseError files_sdk.ResponseError 40 ok := errors.As(err, &responseError) 41 if ok && responseError.Type == "not-found" { 42 } else if ok && responseError.Type == "processing-failure/folder-not-empty" { 43 err = client.Delete(files_sdk.FileDeleteParams{Path: path, Recursive: lib.Bool(true)}) 44 ok = errors.As(err, &responseError) 45 if ok && responseError.Type == "not-found" { 46 //noop 47 } else if ok { 48 panic(err) 49 } 50 } else if ok { 51 panic(err) 52 } 53 } 54 55 func ignoreSomeErrors(err error) { 56 if err != nil && !files_sdk.IsExist(err) { 57 panic(err) 58 } 59 } 60 61 func buildScenario(base string, client *Client) { 62 folderClient := folder.Client{Config: client.Config} 63 64 _, err := folderClient.Create(files_sdk.FolderCreateParams{Path: base}) 65 ignoreSomeErrors(err) 66 _, err = folderClient.Create(files_sdk.FolderCreateParams{Path: lib.UrlJoinNoEscape(base, "nested_1")}) 67 ignoreSomeErrors(err) 68 _, err = folderClient.Create(files_sdk.FolderCreateParams{Path: lib.UrlJoinNoEscape(base, "nested_1", "nested_2")}) 69 ignoreSomeErrors(err) 70 _, err = folderClient.Create(files_sdk.FolderCreateParams{Path: lib.UrlJoinNoEscape(base, "nested_1", "nested_2", "nested_3")}) 71 ignoreSomeErrors(err) 72 73 client.Upload() 74 75 err = client.Upload( 76 UploadWithSize(9), 77 UploadWithDestinationPath(lib.UrlJoinNoEscape(base, "nested_1", "nested_2", "3.text")), 78 UploadWithProvidedMtime(time.Date(2010, 11, 17, 20, 34, 58, 651387237, time.UTC)), 79 UploadWithReader(strings.NewReader("testing 3")), 80 ) 81 82 ignoreSomeErrors(err) 83 84 err = client.Upload( 85 UploadWithSize(9), 86 UploadWithDestinationPath(lib.UrlJoinNoEscape(base, "nested_1", "nested_2", "nested_3", "4.text")), 87 UploadWithProvidedMtime(time.Date(2010, 11, 17, 20, 34, 58, 651387237, time.UTC)), 88 UploadWithReader(strings.NewReader("testing 3")), 89 ) 90 ignoreSomeErrors(err) 91 } 92 93 func runDownloadScenario(path string, destination string, client *Client) map[string][]JobFile { 94 m := &sync.Mutex{} 95 results := make(map[string][]JobFile) 96 97 reporter := func(r JobFile) { 98 m.Lock() 99 results[r.File.Path] = append(results[r.File.Path], r) 100 m.Unlock() 101 } 102 103 job := client.Downloader( 104 DownloaderParams{RemotePath: path, LocalPath: destination, EventsReporter: CreateReporter(reporter)}, 105 ) 106 107 job.Start() 108 job.Wait() 109 110 return results 111 } 112 113 func CreateReporter(callback Reporter) EventsReporter { 114 return CreateFileEvents(callback, append(status.Excluded, append(status.Included, OnBytesChange(status.Uploading))...)...) 115 } 116 117 func TestClient_UploadFolder(t *testing.T) { 118 client, r, err := CreateClient("TestClient_UploadFolder") 119 if err != nil { 120 t.Fatal(err) 121 } 122 defer r.Stop() 123 124 assert := assert.New(t) 125 resultsMapMutex := sync.RWMutex{} 126 results := make(map[string][]ReporterCall) 127 128 job := client.Uploader( 129 UploaderParams{ 130 LocalPath: "../lib", 131 RemotePath: "golib", 132 EventsReporter: CreateReporter(func(status JobFile) { 133 resultsMapMutex.Lock() 134 results[status.RemotePath] = append(results[status.RemotePath], ReporterCall{JobFile: status, err: status.Err}) 135 resultsMapMutex.Unlock() 136 }), 137 Manager: manager.Default(), 138 }, 139 ) 140 141 job.Start() 142 job.Wait() 143 files, err := os.ReadDir("../lib") 144 assert.NoError(err) 145 gitIgnore, err := ignore.New() 146 assert.NoError(err) 147 for _, f := range files { 148 if f.IsDir() { 149 continue 150 } 151 if gitIgnore.MatchesPath(f.Name()) { 152 continue 153 } 154 remotePath := fmt.Sprintf("golib/lib/%v", f.Name()) 155 assert.Contains(results, remotePath) 156 lastStatuses, ok := results[remotePath] 157 if !ok { 158 continue 159 } 160 lastStatus := lastStatuses[len(lastStatuses)-1] 161 if lastStatus.Err != nil && strings.Contains(lastStatus.Err.Error(), "Requested interaction not found") { 162 assert.Equal(status.Errored, lastStatus.Status) 163 } else { 164 assert.Equal(status.Complete, lastStatus.Status) 165 assert.NoError(lastStatus.Err) 166 } 167 } 168 deletePath(client, "golib") 169 } 170 171 func TestClient_UploadFolder_Dot(t *testing.T) { 172 client, r, err := CreateClient("TestClient_UploadFolder_Dot") 173 if err != nil { 174 t.Fatal(err) 175 } 176 defer r.Stop() 177 178 assert := assert.New(t) 179 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 180 if err != nil { 181 log.Fatal(err) 182 } 183 defer os.RemoveAll(tmpDir) 184 185 resultsMapMutex := sync.RWMutex{} 186 results := make(map[string][]int64) 187 err = os.MkdirAll(filepath.Join(tmpDir, "dot"), 0755) 188 assert.NoError(err) 189 190 f1, _ := os.Create(filepath.Join(tmpDir, "dot/1.text")) 191 f1.Write([]byte("hello 1")) 192 f1.Close() 193 194 f2, _ := os.Create(filepath.Join(tmpDir, "dot/2.text")) 195 f2.Write([]byte("hello 2")) 196 f2.Close() 197 198 f3, _ := os.Create(filepath.Join(tmpDir, "dot/3.text")) 199 f3.Write([]byte("hello 3")) 200 f3.Close() 201 202 currentPwd, _ := os.Getwd() 203 err = os.Chdir(filepath.Join(tmpDir, "dot")) 204 defer func() { 205 os.Chdir(currentPwd) 206 os.RemoveAll(filepath.Join(tmpDir, "/dot")) 207 }() 208 assert.NoError(err) 209 210 ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second) 211 defer cancel() 212 213 job := client.Uploader( 214 UploaderParams{ 215 LocalPath: "." + string(os.PathSeparator), 216 RemotePath: "go-from-dot", 217 EventsReporter: CreateReporter(func(s JobFile) { 218 resultsMapMutex.Lock() 219 require.NoError(t, s.Err) 220 221 results[s.File.Path] = append(results[s.File.Path], s.TransferBytes) 222 resultsMapMutex.Unlock() 223 }), 224 }, files_sdk.WithContext(ctx)) 225 job.Start() 226 job.Wait() 227 assert.Contains(results, "go-from-dot/1.text") 228 assert.Contains(results, "go-from-dot/2.text") 229 assert.Contains(results, "go-from-dot/3.text") 230 assert.Equal(int64(7), job.Statuses[0].TransferBytes()) 231 assert.Equal(int64(7), job.Statuses[1].TransferBytes()) 232 assert.Equal(int64(7), job.Statuses[2].TransferBytes()) 233 234 deletePath(client, "go-from-dot") 235 } 236 237 func TestClient_UploadFolder_Relative(t *testing.T) { 238 client, r, err := CreateClient("TestClient_UploadFolder_Relative") 239 if err != nil { 240 t.Fatal(err) 241 } 242 defer r.Stop() 243 244 assert := assert.New(t) 245 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 246 if err != nil { 247 log.Fatal(err) 248 } 249 defer os.RemoveAll(tmpDir) 250 resultsMapMutex := sync.RWMutex{} 251 results := make(map[string][]int64) 252 253 err = os.MkdirAll(filepath.Join(tmpDir, "relative"), 0755) 254 assert.NoError(err) 255 256 f1, _ := os.Create(filepath.Join(tmpDir, "relative", "1.text")) 257 f1.Write([]byte("hello 1")) 258 f1.Close() 259 260 f2, _ := os.Create(filepath.Join(tmpDir, "relative", "2.text")) 261 f2.Write([]byte("hello 2")) 262 f2.Close() 263 264 f3, _ := os.Create(filepath.Join(tmpDir, "relative", "3.text")) 265 f3.Write([]byte("hello 3")) 266 f3.Close() 267 268 currentPwd, _ := os.Getwd() 269 err = os.Chdir(tmpDir) 270 defer os.Chdir(currentPwd) 271 assert.NoError(err) 272 273 job := client.Uploader( 274 UploaderParams{ 275 LocalPath: "relative" + string(os.PathSeparator), 276 RemotePath: "relative", 277 EventsReporter: CreateReporter(func(status JobFile) { 278 resultsMapMutex.Lock() 279 results[status.File.Path] = append(results[status.File.Path], status.TransferBytes) 280 resultsMapMutex.Unlock() 281 }), 282 }) 283 job.Start() 284 job.Wait() 285 assert.Contains(results, "relative/1.text") 286 assert.Contains(results, "relative/2.text") 287 assert.Contains(results, "relative/3.text") 288 assert.Equal(int64(7), job.Statuses[0].TransferBytes()) 289 assert.Equal(int64(7), job.Statuses[1].TransferBytes()) 290 assert.Equal(int64(7), job.Statuses[2].TransferBytes()) 291 assert.Equal(int64(21), job.TotalBytes(status.Valid...)) 292 assert.Equal(true, job.All(status.Ended...)) 293 294 deletePath(client, "relative") 295 } 296 297 func TestClient_Uploader(t *testing.T) { 298 client, r, err := CreateClient("TestClient_Uploader") 299 if err != nil { 300 t.Fatal(err) 301 } 302 defer r.Stop() 303 assert := assert.New(t) 304 305 uploadPath := ".." + string(os.PathSeparator) + "LICENSE" 306 job := client.Uploader(UploaderParams{LocalPath: uploadPath}) 307 job.Start() 308 job.Wait() 309 assert.Equal(true, job.Started.Called()) 310 assert.Equal(true, job.Scanning.Called()) 311 assert.Equal(true, job.EndScanning.Called()) 312 assert.Equal(true, job.Finished.Called()) 313 assert.Equal(false, job.Canceled.Called()) 314 assert.Equal("LICENSE", job.Files()[0].DisplayName) 315 assert.Equal(1, job.Count()) 316 assert.Equal(int64(1102), job.TotalBytes()) 317 assert.Equal(true, job.All(status.Ended...)) 318 319 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 320 if err != nil { 321 log.Fatal(err) 322 } 323 defer os.RemoveAll(tmpDir) 324 325 tempFile, err := os.CreateTemp(tmpDir, "LICENSE") 326 if err != nil { 327 panic(err) 328 } 329 file, err := client.DownloadToFile(files_sdk.FileDownloadParams{Path: "LICENSE"}, tempFile.Name()) 330 assert.NoError(err) 331 332 assert.Equal(file.DisplayName, "LICENSE") 333 334 downloadData, err := os.ReadFile(tempFile.Name()) 335 if err != nil { 336 panic(err) 337 } 338 localData, err := os.ReadFile(uploadPath) 339 if err != nil { 340 panic(err) 341 } 342 assert.Equal(string(downloadData), string(localData)) 343 defer os.Remove(tempFile.Name()) 344 } 345 346 func TestClient_UploadFile_To_Existing_Dir(t *testing.T) { 347 client, r, err := CreateClient("TestClient_UploadFile_To_Existing_Dir") 348 if err != nil { 349 t.Fatal(err) 350 } 351 defer r.Stop() 352 assert := assert.New(t) 353 354 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 355 if err != nil { 356 log.Fatal(err) 357 } 358 defer os.RemoveAll(tmpDir) 359 360 folderClient := folder.Client{Config: client.Config} 361 _, err = folderClient.Create(files_sdk.FolderCreateParams{Path: "docs"}) 362 defer deletePath(client, "docs") 363 364 assert.NoError(err) 365 uploadPath := ".." + string(os.PathSeparator) + "LICENSE" 366 job := client.Uploader(UploaderParams{LocalPath: uploadPath, RemotePath: "docs"}) 367 job.Start() 368 job.Wait() 369 tempFile, err := os.CreateTemp(tmpDir, "LICENSE") 370 if err != nil { 371 panic(err) 372 } 373 file, err := client.DownloadToFile(files_sdk.FileDownloadParams{Path: "docs/LICENSE"}, tempFile.Name()) 374 assert.NoError(err) 375 376 assert.Equal(file.DisplayName, "LICENSE") 377 378 downloadData, err := os.ReadFile(tempFile.Name()) 379 if err != nil { 380 panic(err) 381 } 382 localData, err := os.ReadFile(uploadPath) 383 if err != nil { 384 panic(err) 385 } 386 assert.Equal(string(downloadData), string(localData)) 387 defer os.Remove(tempFile.Name()) 388 } 389 390 func TestClient_UploadFile_To_NonExistingPath(t *testing.T) { 391 client, r, err := CreateClient("TestClient_UploadFile_To_NonExistingPath") 392 if err != nil { 393 t.Fatal(err) 394 } 395 defer r.Stop() 396 assert := assert.New(t) 397 398 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 399 if err != nil { 400 log.Fatal(err) 401 } 402 defer os.RemoveAll(tmpDir) 403 404 deletePath(client, "taco") 405 uploadPath := ".." + string(os.PathSeparator) + "LICENSE" 406 job := client.Uploader(UploaderParams{LocalPath: uploadPath, RemotePath: "taco"}) 407 defer deletePath(client, "taco") 408 job.Start() 409 job.Wait() 410 tempFile, _ := os.CreateTemp(tmpDir, "LICENSE") 411 _, err = filepath.Abs(filepath.Dir(tempFile.Name())) 412 if err != nil { 413 panic(err) 414 } 415 file, err := client.DownloadToFile(files_sdk.FileDownloadParams{Path: "taco"}, tempFile.Name()) 416 assert.NoError(err) 417 418 assert.Equal("taco", file.DisplayName, "because the docs did not exist as a folder it becomes the file") 419 420 downloadData, err := os.ReadFile(tempFile.Name()) 421 assert.NoError(err) 422 localData, err := os.ReadFile(uploadPath) 423 if err != nil { 424 panic(err) 425 } 426 assert.Equal(string(downloadData), string(localData)) 427 defer os.Remove(tempFile.Name()) 428 } 429 430 func TestClient_UploadFile_To_NonExistingPath_WithSlash(t *testing.T) { 431 client, r, err := CreateClient("TestClient_UploadFile_To_NonExistingPath_WithSlash") 432 if err != nil { 433 t.Fatal(err) 434 } 435 defer r.Stop() 436 assert := assert.New(t) 437 438 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 439 if err != nil { 440 log.Fatal(err) 441 } 442 defer os.RemoveAll(tmpDir) 443 444 assert.NoError(err) 445 uploadPath := ".." + string(os.PathSeparator) + "LICENSE" 446 deletePath(client, "docs") 447 job := client.Uploader(UploaderParams{LocalPath: uploadPath, RemotePath: "docs/"}) 448 defer deletePath(client, "docs") 449 job.Start() 450 job.Wait() 451 tempFile, err := os.CreateTemp(tmpDir, "LICENSE") 452 if err != nil { 453 panic(err) 454 } 455 file, err := client.DownloadToFile(files_sdk.FileDownloadParams{Path: "docs/LICENSE"}, tempFile.Name()) 456 assert.NoError(err) 457 458 assert.Equal("file", file.Type) 459 assert.Equal("LICENSE", file.DisplayName) 460 461 downloadData, err := os.ReadFile(tempFile.Name()) 462 if err != nil { 463 panic(err) 464 } 465 localData, err := os.ReadFile(uploadPath) 466 if err != nil { 467 panic(err) 468 } 469 assert.Equal(string(downloadData), string(localData)) 470 defer os.Remove(tempFile.Name()) 471 } 472 473 func TestClient_UploadFolder_as_file2(t *testing.T) { 474 client, r, err := CreateClient("TestClient_UploadFolder_as_file2") 475 if err != nil { 476 t.Fatal(err) 477 } 478 defer r.Stop() 479 assert := assert.New(t) 480 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 481 if err != nil { 482 log.Fatal(err) 483 } 484 defer os.RemoveAll(tmpDir) 485 486 uploadPath := ".." + string(os.PathSeparator) + "LICENSE" 487 job := client.Uploader(UploaderParams{LocalPath: uploadPath}) 488 job.Start() 489 job.Wait() 490 491 assert.Equal(int64(1102), job.TransferBytes()) 492 assert.Equal(int64(1102), job.TotalBytes()) 493 494 tempFile, err := os.CreateTemp(tmpDir, "LICENSE") 495 if err != nil { 496 panic(err) 497 } 498 file, err := client.DownloadToFile(files_sdk.FileDownloadParams{Path: "LICENSE"}, tempFile.Name()) 499 assert.NoError(err) 500 501 assert.Equal(file.DisplayName, "LICENSE") 502 503 downloadData, err := os.ReadFile(tempFile.Name()) 504 if err != nil { 505 panic(err) 506 } 507 localData, err := os.ReadFile(uploadPath) 508 if err != nil { 509 panic(err) 510 } 511 assert.Equal(string(downloadData), string(localData)) 512 defer os.Remove(tempFile.Name()) 513 } 514 515 func TestClient_UploadFolder_RemotePathWithStartingSlash(t *testing.T) { 516 client, r, err := CreateClient("TestClient_UploadFolder_RemotePathWithStartingSlash") 517 if err != nil { 518 t.Fatal(err) 519 } 520 defer r.Stop() 521 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 522 if err != nil { 523 log.Fatal(err) 524 } 525 defer os.RemoveAll(tmpDir) 526 527 err = os.MkdirAll(filepath.Join(tmpDir, "test"), 0755) 528 assert.NoError(t, err) 529 530 f1, _ := os.Create(filepath.Join(tmpDir, "test", "1.text")) 531 f1.Write([]byte("hello 1")) 532 f1.Close() 533 534 f2, _ := os.Create(filepath.Join(tmpDir, "test", "2.text")) 535 f2.Write([]byte("hello 2")) 536 f2.Close() 537 538 f3, _ := os.Create(filepath.Join(tmpDir, "test", "3.text")) 539 f3.Write([]byte("hello 3")) 540 f3.Close() 541 job := client.Uploader(UploaderParams{LocalPath: filepath.Join(tmpDir, "test"), RemotePath: "/test", Manager: manager.Sync()}) 542 job.Start() 543 job.Wait() 544 assert.NoError(t, job.Statuses[0].Err()) 545 assert.Len(t, job.Statuses, 3) 546 dir, _ := filepath.Split(job.Statuses[0].RemotePath()) 547 assert.Equal(t, "test/test/", dir) 548 } 549 550 func TestClient_UploadFolder_ZeroByteFile(t *testing.T) { 551 client, r, err := CreateClient("TestClient_UploadFolder_ZeroByteFile") 552 if err != nil { 553 t.Fatal(err) 554 } 555 defer r.Stop() 556 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 557 if err != nil { 558 log.Fatal(err) 559 } 560 defer os.RemoveAll(tmpDir) 561 err = os.MkdirAll(filepath.Join(tmpDir, "zero_byte_folder"), 0755) 562 assert.NoError(t, err) 563 564 f1, _ := os.Create(filepath.Join(tmpDir, "zero_byte_folder", "zero-byte-file.text")) 565 f1.Close() 566 567 job := client.Uploader(UploaderParams{LocalPath: filepath.Join(tmpDir, "zero_byte_folder"), RemotePath: "", Manager: manager.Sync()}) 568 job.Start() 569 job.Wait() 570 require.Len(t, job.Statuses, 1) 571 assert.NoError(t, job.Statuses[0].Err()) 572 assert.Equal(t, "zero_byte_folder/zero-byte-file.text", job.Statuses[0].RemotePath()) 573 574 job = client.Downloader(DownloaderParams{RemotePath: "zero_byte_folder", LocalPath: tmpDir + string(os.PathSeparator)}) 575 job.Start() 576 job.Wait() 577 require.Len(t, job.Statuses, 1) 578 assert.NoError(t, job.Statuses[0].Err()) 579 } 580 581 func TestClient_DownloadFolder(t *testing.T) { 582 client, r, err := CreateClient("TestClient_DownloadFolder") 583 if err != nil { 584 t.Fatal(err) 585 } 586 defer r.Stop() 587 588 buildScenario("TestClient_DownloadFolder", client) 589 590 assert := assert.New(t) 591 592 it, err := client.ListFor(files_sdk.FolderListForParams{ 593 ListParams: files_sdk.ListParams{PerPage: 1}, 594 Path: "TestClient_DownloadFolder/nested_1/nested_2", 595 }) 596 597 assert.NoError(err) 598 files := files_sdk.FileCollection{} 599 for it.Next() { 600 files = append(files, it.File()) 601 } 602 603 assert.Len(files, 2, "something is wrong with cursor") 604 605 results := runDownloadScenario("TestClient_DownloadFolder", "download/", client) 606 assert.NoError(err) 607 assert.Equal(int64(9), results["TestClient_DownloadFolder/nested_1/nested_2/3.text"][2].TransferBytes) 608 assert.Equal(int64(9), results["TestClient_DownloadFolder/nested_1/nested_2/nested_3/4.text"][2].TransferBytes) 609 os.RemoveAll("download") 610 } 611 612 func TestClient_DownloadFolder_Smart(t *testing.T) { 613 client, r, err := CreateClient("TestClient_DownloadFolder_Smart") 614 if err != nil { 615 t.Fatal(err) 616 } 617 defer r.Stop() 618 defer os.RemoveAll("download") 619 620 buildScenario("TestClient_DownloadFolder_Smart", client) 621 622 results := runDownloadScenario(lib.UrlJoinNoEscape("TestClient_DownloadFolder_Smart", "nested_1", "nested_2", "3.text"), "download"+string(os.PathSeparator), client) 623 for _, result := range results { 624 for _, f := range result { 625 require.NoError(t, f.Err) 626 } 627 } 628 629 assert.Len(t, results["TestClient_DownloadFolder_Smart/nested_1/nested_2/3.text"], 3) 630 assert.Equal(t, int64(9), results["TestClient_DownloadFolder_Smart/nested_1/nested_2/3.text"][2].TransferBytes) 631 632 results2 := runDownloadScenario(lib.UrlJoinNoEscape("TestClient_DownloadFolder_Smart", "nested_1", "nested_2")+"/", "download", client) 633 634 assert.NoError(t, err) 635 636 path, err := os.Getwd() 637 assert.NoError(t, err) 638 639 require.Len(t, results2["TestClient_DownloadFolder_Smart/nested_1/nested_2/3.text"], 3) 640 assert.Equal(t, int64(9), results2["TestClient_DownloadFolder_Smart/nested_1/nested_2/3.text"][2].TransferBytes) 641 assert.Equal(t, filepath.Join(path, "download", "3.text"), results2["TestClient_DownloadFolder_Smart/nested_1/nested_2/3.text"][2].LocalPath) 642 fileInfo, err := os.Stat(filepath.Join(path, "download", "3.text")) 643 require.NoError(t, err) 644 assert.Equal(t, int64(9), fileInfo.Size()) 645 require.Len(t, results2["TestClient_DownloadFolder_Smart/nested_1/nested_2/nested_3/4.text"], 3) 646 assert.Equal(t, int64(9), results2["TestClient_DownloadFolder_Smart/nested_1/nested_2/nested_3/4.text"][2].TransferBytes) 647 assert.Equal(t, filepath.Join(path, "download", "nested_3", "4.text"), results2["TestClient_DownloadFolder_Smart/nested_1/nested_2/nested_3/4.text"][2].LocalPath) 648 } 649 650 func TestClient_DownloadFolder_file_to_file(t *testing.T) { 651 client, r, err := CreateClient("TestClient_DownloadFolder_file_to_file") 652 if err != nil { 653 t.Fatal(err) 654 } 655 defer r.Stop() 656 657 buildScenario("TestClient_DownloadFolder_file_to_file", client) 658 assert := assert.New(t) 659 660 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 661 if err != nil { 662 log.Fatal(err) 663 } 664 defer os.RemoveAll(tmpDir) 665 666 results := runDownloadScenario(lib.UrlJoinNoEscape("TestClient_DownloadFolder_file_to_file", "nested_1", "nested_2", "3.text"), filepath.Join(tmpDir, "3.text"), client) 667 assert.NoError(err) 668 for _, result := range results { 669 for _, f := range result { 670 require.NoError(t, f.Err) 671 } 672 } 673 assert.Equal(int64(9), results["TestClient_DownloadFolder_file_to_file/nested_1/nested_2/3.text"][2].TransferBytes) 674 } 675 676 func TestClient_DownloadFolder_file_to_implicit(t *testing.T) { 677 client, r, err := CreateClient("TestClient_DownloadFolder_file_to_implicit") 678 if err != nil { 679 t.Fatal(err) 680 } 681 defer r.Stop() 682 683 buildScenario("file_to_implicit", client) 684 assert := assert.New(t) 685 results := runDownloadScenario(lib.UrlJoinNoEscape("file_to_implicit", "nested_1", "nested_2", "3.text"), "", client) 686 assert.NoError(err) 687 for _, result := range results { 688 for _, f := range result { 689 require.NoError(t, f.Err) 690 } 691 } 692 assert.Equal(int64(9), results["file_to_implicit/nested_1/nested_2/3.text"][2].TransferBytes) 693 os.RemoveAll("3.text") 694 } 695 696 func TestClient_DownloadFolder_file_only(t *testing.T) { 697 client, r, err := CreateClient("TestClient_DownloadFolder_file_only") 698 if err != nil { 699 t.Fatal(err) 700 } 701 defer r.Stop() 702 703 err = client.Upload( 704 UploadWithSize(5), 705 UploadWithDestinationPath("i am at the root.text"), 706 UploadWithProvidedMtime(time.Date(2010, 11, 17, 20, 34, 58, 651387237, time.UTC)), 707 UploadWithReader(strings.NewReader("hello")), 708 ) 709 710 require.NoError(t, err) 711 712 assert := assert.New(t) 713 results := runDownloadScenario("i am at the root.text", "", client) 714 assert.NoError(err) 715 for _, result := range results { 716 for _, f := range result { 717 require.NoError(t, f.Err) 718 } 719 } 720 require.Len(t, results["i am at the root.text"], 3) 721 assert.Equal(int64(5), results["i am at the root.text"][2].TransferBytes) 722 os.RemoveAll("i am at the root.text") 723 } 724 725 func TestClient_Downloader_Delete_Source(t *testing.T) { 726 client, r, err := CreateClient("TestClient_Downloader_Delete_Source") 727 if err != nil { 728 t.Fatal(err) 729 } 730 defer r.Stop() 731 assert := assert.New(t) 732 733 folderClient := folder.Client{Config: client.Config} 734 735 folderClient.Create(files_sdk.FolderCreateParams{Path: "test-delete-source"}) 736 737 err = client.Upload( 738 UploadWithSize(9), 739 UploadWithDestinationPath(lib.UrlJoinNoEscape("test-delete-source", "test.text")), 740 UploadWithProvidedMtime(time.Date(2010, 11, 17, 20, 34, 58, 651387237, time.UTC)), 741 UploadWithReader(strings.NewReader("testing 3")), 742 ) 743 744 require.NoError(t, err) 745 localPath, err := os.MkdirTemp("", "TestClient_Downloader_Delete_Source") 746 require.NoError(t, err) 747 748 job := client.Downloader( 749 DownloaderParams{RemotePath: "test-delete-source", LocalPath: localPath}, 750 ) 751 var fi JobFile 752 var log status.Log 753 job.RegisterFileEvent(func(f JobFile) { 754 fi = f 755 log, err = DeleteSource{Config: client.Config, Direction: job.Direction}.Call(f) 756 }, status.Complete) 757 job.Start() 758 <-job.Finished.C 759 assert.NoError(err) 760 assert.Equal("delete source", log.Action) 761 assert.Equal(fi.RemotePath, log.Path) 762 763 _, err = client.Find(files_sdk.FileFindParams{Path: lib.UrlJoinNoEscape("test-delete-source", "test.text")}) 764 require.NotNil(t, err) 765 assert.Equal("Not Found - `Not Found`", err.Error()) 766 os.RemoveAll("test.text") 767 } 768 769 func TestClient_Downloader_Move_Source(t *testing.T) { 770 client, r, err := CreateClient("TestClient_Downloader_Move_Source") 771 if err != nil { 772 t.Fatal(err) 773 } 774 defer r.Stop() 775 assert := assert.New(t) 776 777 folderClient := folder.Client{Config: client.Config} 778 779 folderClient.Create(files_sdk.FolderCreateParams{Path: "test-move-source"}) 780 781 err = client.Upload( 782 UploadWithSize(9), 783 UploadWithDestinationPath(lib.UrlJoinNoEscape("test-move-source", "test.text")), 784 UploadWithProvidedMtime(time.Date(2010, 11, 17, 20, 34, 58, 651387237, time.UTC)), 785 UploadWithReader(strings.NewReader("testing 3")), 786 ) 787 require.NoError(t, err) 788 localPath, err := os.MkdirTemp("", "TestClient_Downloader_Move_Source") 789 require.NoError(t, err) 790 job := client.Downloader( 791 DownloaderParams{RemotePath: "test-move-source", LocalPath: localPath}, 792 ) 793 var log status.Log 794 job.RegisterFileEvent(func(f JobFile) { 795 log, err = MoveSource{Config: client.Config, Direction: job.Direction, Path: "test-moved-source"}.Call(f) 796 }, status.Complete) 797 job.Start() 798 job.Wait() 799 800 require.NoError(t, err) 801 assert.Equal("move source", log.Action) 802 assert.Equal(filepath.Join("test-moved-source", "test.text"), log.Path) 803 804 _, err = client.Find(files_sdk.FileFindParams{Path: lib.UrlJoinNoEscape("test-move-source", "test.text")}) 805 assert.Equal("Not Found - `Not Found`", err.Error()) 806 _, err = client.Find(files_sdk.FileFindParams{Path: lib.UrlJoinNoEscape("test-moved-source", "test.text")}) 807 assert.NoError(err) 808 os.RemoveAll("test.text") 809 } 810 811 func TestClient_UploadFolder_Move_Source(t *testing.T) { 812 client, r, err := CreateClient("TestClient_UploadFolder_Move_Source") 813 if err != nil { 814 t.Fatal(err) 815 } 816 defer r.Stop() 817 assert := assert.New(t) 818 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 819 if err != nil { 820 log.Fatal(err) 821 } 822 defer os.RemoveAll(tmpDir) 823 var log status.Log 824 825 defer os.RemoveAll(tmpDir) 826 err = os.MkdirAll(filepath.Join(tmpDir, "move-source"), 0755) 827 assert.NoError(err) 828 829 tempFile, err := os.Create(filepath.Join(tmpDir, "move-source", "upload-move-source.text")) 830 assert.NoError(err) 831 tempFile.Write([]byte("testing")) 832 require.NoError(t, tempFile.Close()) 833 job := client.Uploader(UploaderParams{LocalPath: tempFile.Name()}) 834 job.RegisterFileEvent(func(f JobFile) { 835 fmt.Println("RegisterFileEvent") 836 log, err = MoveSource{Config: client.Config, Direction: job.Direction, Path: filepath.Join(tmpDir, "move-source", "test-moved-source.text")}.Call(f) 837 }, status.Complete) 838 job.Start() 839 job.Wait() 840 assert.Equal(false, job.Any(status.Errored)) 841 assert.NoError(err) 842 assert.Equal("move source", log.Action) 843 assert.Equal(filepath.Join(tmpDir, "move-source", "test-moved-source.text"), log.Path) 844 stat, err := os.Stat(log.Path) 845 require.NoError(t, err) 846 assert.Equal("test-moved-source.text", stat.Name()) 847 tempFile.Close() 848 } 849 850 func TestClient_UploadFolder_Move_Source_Missing_Dir(t *testing.T) { 851 client, r, err := CreateClient("TestClient_UploadFolder_Move_Source_Missing_Dir") 852 if err != nil { 853 t.Fatal(err) 854 } 855 defer r.Stop() 856 assert := assert.New(t) 857 858 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 859 if err != nil { 860 log.Fatal(err) 861 } 862 defer os.RemoveAll(tmpDir) 863 864 var log status.Log 865 err = os.MkdirAll(filepath.Join(tmpDir, "move-source-dir"), 0755) 866 assert.NoError(err) 867 tempFile, err := os.Create(filepath.Join(tmpDir, "move-source-dir", "upload-move-source.text")) 868 assert.NoError(err) 869 tempFile.Write([]byte("testing")) 870 tempFile.Close() 871 job := client.Uploader(UploaderParams{LocalPath: filepath.Join(tmpDir, "move-source-dir") + string(os.PathSeparator)}) 872 job.RegisterFileEvent(func(f JobFile) { 873 log, err = MoveSource{Config: client.Config, Direction: job.Direction, Path: filepath.Join(tmpDir, "moved-source-dir")}.Call(f) 874 }, status.Complete) 875 job.Start() 876 job.Wait() 877 erroredFile, ok := job.Find(status.Errored) 878 if ok { 879 assert.NoError(erroredFile.Err(), erroredFile.LocalPath()) 880 } 881 require.Equal(t, false, job.Any(status.Errored), "") 882 assert.NoError(err) 883 assert.Equal("move source", log.Action) 884 assert.Equal(filepath.Join(tmpDir, "moved-source-dir", "upload-move-source.text"), log.Path) 885 stat, err := os.Stat(log.Path) 886 assert.NoError(err) 887 assert.Equal("upload-move-source.text", stat.Name()) 888 assert.Equal(false, stat.IsDir()) 889 890 _, err = os.Stat(filepath.Join(tmpDir, "move-source-dir", "upload-move-source.text")) 891 assert.Equal(true, os.IsNotExist(err)) 892 } 893 894 func TestClient_Downloader_Move_Source_Missing_Dir(t *testing.T) { 895 client, r, err := CreateClient("TestClient_Downloader_Move_Source_Missing_Dir") 896 if err != nil { 897 t.Fatal(err) 898 } 899 defer r.Stop() 900 assert := assert.New(t) 901 902 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 903 if err != nil { 904 log.Fatal(err) 905 } 906 defer os.RemoveAll(tmpDir) 907 908 buildScenario("TestClient_Downloader_Move_Source_Missing_Dir", client) 909 os.MkdirAll(filepath.Join(tmpDir, "TestClient_Downloader_Move_Source_Missing_Dir"), 0755) 910 911 logChan := make(chan status.Log) 912 errChan := make(chan error) 913 job := client.Downloader( 914 DownloaderParams{ 915 RemotePath: "TestClient_Downloader_Move_Source_Missing_Dir", 916 LocalPath: filepath.Join(tmpDir, "TestClient_Downloader_Move_Source_Missing_Dir") + string(os.PathSeparator), 917 }, 918 ) 919 job.RegisterFileEvent(func(f JobFile) { 920 moveLog, err := MoveSource{Config: client.Config, Direction: job.Direction, Path: "TestClient_Downloader_Move_Source_Missing_Dir-moved"}.Call(f) 921 logChan <- moveLog 922 errChan <- err 923 }, status.Complete) 924 job.Start() 925 926 fileValues := []string{ 927 "TestClient_Downloader_Move_Source_Missing_Dir-moved/nested_1/nested_2/3.text", 928 "TestClient_Downloader_Move_Source_Missing_Dir-moved/nested_1/nested_2/nested_3/4.text", 929 } 930 files := make(map[string]string) 931 files[fileValues[0]] = fileValues[0] 932 files[fileValues[1]] = fileValues[1] 933 934 log1 := <-logChan 935 assert.Equal("move source", log1.Action) 936 assert.Equal(files[lib.Path{Path: log1.Path}.NormalizePathSystemForAPI().String()], lib.Path{Path: log1.Path}.NormalizePathSystemForAPI().String()) 937 assert.NoError(<-errChan) 938 939 log2 := <-logChan 940 assert.Equal("move source", log2.Action) 941 assert.Equal(files[lib.Path{Path: log2.Path}.NormalizePathSystemForAPI().String()], lib.Path{Path: log2.Path}.NormalizePathSystemForAPI().String()) 942 assert.NoError(<-errChan) 943 944 job.Wait() 945 946 assert.Equal(false, job.Any(status.Errored)) 947 948 movedDir, err := client.Find(files_sdk.FileFindParams{Path: "TestClient_Downloader_Move_Source_Missing_Dir-moved"}) 949 assert.NoError(err) 950 assert.Equal("TestClient_Downloader_Move_Source_Missing_Dir-moved", movedDir.Path) 951 assert.Equal("directory", movedDir.Type) 952 } 953 954 func TestClient_UploadFile_Delete_Source(t *testing.T) { 955 client, r, err := CreateClient("TestClient_UploadFile_Delete_Source") 956 if err != nil { 957 t.Fatal(err) 958 } 959 defer r.Stop() 960 assert := assert.New(t) 961 tmpDir, err := os.MkdirTemp(os.TempDir(), "client_test") 962 if err != nil { 963 log.Fatal(err) 964 } 965 defer os.RemoveAll(tmpDir) 966 967 var log status.Log 968 tempFile, err := os.Create(filepath.Join(tmpDir, "upload-delete-source.text")) 969 assert.NoError(err) 970 tempFile.Write([]byte("testing")) 971 require.NoError(t, tempFile.Close()) 972 var fi JobFile 973 job := client.Uploader(UploaderParams{LocalPath: tempFile.Name()}) 974 job.RegisterFileEvent(func(f JobFile) { 975 fi = f 976 log, err = DeleteSource{Config: client.Config, Direction: job.Direction}.Call(f) 977 }, status.Complete) 978 job.Start() 979 job.Wait() 980 assert.Equal(false, job.Any(status.Errored)) 981 assert.NoError(err) 982 assert.Equal("delete source", log.Action) 983 assert.Equal(fi.LocalPath, log.Path) 984 tempFile.Close() 985 os.Remove(tempFile.Name()) 986 } 987 988 func TestClient_Uploader_Files(t *testing.T) { 989 client, r, err := CreateClient("TestClient_Uploader_Files") 990 if err != nil { 991 t.Fatal(err) 992 } 993 defer r.Stop() 994 assert := assert.New(t) 995 tmpDir := t.TempDir() 996 997 filesAndStatus := []struct { 998 name string 999 status string 1000 size int 1001 }{{name: "1 (1).text", status: "complete", size: 24}, {name: "2.text", status: "complete", size: 24}, {name: "3.pdf", status: "ignored"}} 1002 var filePaths []string 1003 for _, file := range filesAndStatus { 1004 f, err := os.Create(filepath.Join(tmpDir, file.name)) 1005 assert.NoError(err) 1006 f.Write([]byte("hello how are you doing?")) 1007 f.Close() 1008 if file.status == "complete" { 1009 filePaths = append(filePaths, f.Name()) 1010 } 1011 } 1012 1013 job := client.Uploader(UploaderParams{LocalPath: tmpDir + string(os.PathSeparator), LocalPaths: filePaths}) 1014 job.Start() 1015 job.Wait() 1016 1017 assert.Len(job.Statuses, 2) 1018 assert.Equal(filePaths[0], job.Statuses[0].LocalPath()) 1019 assert.Equal(status.Complete, job.Statuses[0].Status()) 1020 assert.NoError(job.Statuses[0].Err()) 1021 1022 assert.Equal(filePaths[1], job.Statuses[1].LocalPath()) 1023 assert.Equal(status.Complete, job.Statuses[1].Status()) 1024 assert.NoError(job.Statuses[1].Err()) 1025 } 1026 1027 func TestClient_Uploader_Directories(t *testing.T) { 1028 client, r, err := CreateClient("TestClient_Uploader_Directories") 1029 if err != nil { 1030 t.Fatal(err) 1031 } 1032 defer r.Stop() 1033 assert := assert.New(t) 1034 tmpDir := t.TempDir() 1035 1036 filesAndStatus := []struct { 1037 name string 1038 status string 1039 size int 1040 }{{name: "A/1.text", status: "complete", size: 24}, {name: "B/2.text", status: "complete", size: 24}, {name: "B/Z/4.text", status: "complete", size: 24}, {name: "3.text", status: "complete", size: 24}} 1041 for index, file := range filesAndStatus { 1042 file.name = filepath.Join(tmpDir, file.name) 1043 require.NoError(t, os.MkdirAll(filepath.Dir(file.name), 0750)) 1044 filesAndStatus[index] = file 1045 f, err := os.Create(file.name) 1046 assert.NoError(err) 1047 f.Write([]byte("hello how are you doing?")) 1048 f.Close() 1049 } 1050 1051 job := client.Uploader( 1052 UploaderParams{ 1053 LocalPath: tmpDir + string(os.PathSeparator), 1054 LocalPaths: []string{ 1055 filepath.Join(tmpDir, "A") + string(os.PathSeparator), 1056 filepath.Join(tmpDir, "B") + string(os.PathSeparator), 1057 filepath.Join(tmpDir, "3.text"), 1058 }, 1059 }, 1060 ) 1061 job.Start() 1062 job.Wait() 1063 1064 require.Equal(t, 4, len(job.Statuses), "the right number of files did not upload") 1065 assert.Equal(filesAndStatus[0].name, job.Statuses[0].LocalPath()) 1066 assert.Equal("1.text", job.Statuses[0].RemotePath()) 1067 assert.Equal(status.Complete, job.Statuses[0].Status()) 1068 assert.NoError(job.Statuses[0].Err()) 1069 1070 assert.Equal(filesAndStatus[1].name, job.Statuses[1].LocalPath()) 1071 assert.Equal("2.text", job.Statuses[1].RemotePath()) 1072 assert.Equal(status.Complete, job.Statuses[1].Status()) 1073 assert.NoError(job.Statuses[1].Err()) 1074 1075 assert.Equal(filesAndStatus[2].name, job.Statuses[2].LocalPath()) 1076 assert.Equal("Z/4.text", job.Statuses[2].RemotePath()) 1077 assert.Equal(status.Complete, job.Statuses[2].Status()) 1078 assert.NoError(job.Statuses[2].Err()) 1079 1080 assert.Equal(filesAndStatus[3].name, job.Statuses[3].LocalPath()) 1081 assert.Equal("3.text", job.Statuses[3].RemotePath()) 1082 assert.Equal(status.Complete, job.Statuses[3].Status()) 1083 assert.NoError(job.Statuses[3].Err()) 1084 } 1085 1086 func TestClient_ListForRecursive(t *testing.T) { 1087 client, r, err := CreateClient("TestClient_ListForRecursive") 1088 if err != nil { 1089 t.Fatal(err) 1090 } 1091 defer r.Stop() 1092 assert := assert.New(t) 1093 buildScenario("TestClient_ListForRecursive", client) 1094 1095 it, _ := client.ListForRecursive(files_sdk.FolderListForParams{Path: "/TestClient_ListForRecursive"}) 1096 var files []RecursiveItem 1097 for it.Next() { 1098 files = append(files, it.Resource()) 1099 } 1100 1101 paths := lo.Map[RecursiveItem, string](files, func(item RecursiveItem, index int) string { 1102 return item.Path 1103 }) 1104 assert.Contains(paths, "TestClient_ListForRecursive") 1105 assert.Contains(paths, "TestClient_ListForRecursive/nested_1") 1106 assert.Contains(paths, "TestClient_ListForRecursive/nested_1/nested_2") 1107 assert.Contains(paths, "TestClient_ListForRecursive/nested_1/nested_2/nested_3") 1108 assert.Contains(paths, "TestClient_ListForRecursive/nested_1/nested_2/nested_3/4.text") 1109 assert.Contains(paths, "TestClient_ListForRecursive/nested_1/nested_2/3.text") 1110 } 1111 1112 func TestClient_ListForRecursiveInsensitive(t *testing.T) { 1113 client, r, err := CreateClient("TestClient_ListForRecursiveInsensitive") 1114 if err != nil { 1115 t.Fatal(err) 1116 } 1117 defer r.Stop() 1118 assert := assert.New(t) 1119 buildScenario("TestClient_ListForRecursiveInsensitive", client) 1120 1121 it, _ := client.ListForRecursive(files_sdk.FolderListForParams{Path: "/TestcLient_listforrecursiveinseNsitive"}) 1122 var files []RecursiveItem 1123 for it.Next() { 1124 files = append(files, it.Resource()) 1125 } 1126 1127 require.Equal(t, 6, len(files)) 1128 paths := lo.Map[RecursiveItem, string](files, func(item RecursiveItem, index int) string { 1129 return item.Path 1130 }) 1131 assert.Contains(paths, "TestClient_ListForRecursiveInsensitive") 1132 assert.Contains(paths, "TestClient_ListForRecursiveInsensitive/nested_1") 1133 assert.Contains(paths, "TestClient_ListForRecursiveInsensitive/nested_1/nested_2") 1134 assert.Contains(paths, "TestClient_ListForRecursiveInsensitive/nested_1/nested_2/nested_3") 1135 assert.Contains(paths, "TestClient_ListForRecursiveInsensitive/nested_1/nested_2/nested_3/4.text") 1136 assert.Contains(paths, "TestClient_ListForRecursiveInsensitive/nested_1/nested_2/3.text") 1137 } 1138 1139 func TestClient_ListForRecursive_Error(t *testing.T) { 1140 client, r, err := CreateClient("TestClient_ListForRecursive_Error") 1141 if err != nil { 1142 t.Fatal(err) 1143 } 1144 defer r.Stop() 1145 assert := assert.New(t) 1146 it, err := client.ListForRecursive(files_sdk.FolderListForParams{Path: "TestClient_ListForRecursive-Not-Found"}) 1147 var files []interface{} 1148 if err == nil { 1149 for it.Next() { 1150 files = append(files, it.Current()) 1151 } 1152 } 1153 1154 assert.Equal(len(files), 0) 1155 assert.Equal("open TestClient_ListForRecursive-Not-Found: Authentication Required - `Unauthorized. The API key or Session token is either missing or invalid.`", err.Error()) 1156 } 1157 1158 func TestClient_ListForRecursive_Root(t *testing.T) { 1159 client, r, err := CreateClient("TestClient_ListForRecursive_Root") 1160 if err != nil { 1161 t.Fatal(err) 1162 } 1163 defer r.Stop() 1164 assert := assert.New(t) 1165 ctx, cancel := context.WithCancel(context.Background()) 1166 defer cancel() 1167 it, _ := client.ListForRecursive(files_sdk.FolderListForParams{Path: ""}, files_sdk.WithContext(ctx)) 1168 recursiveItems := make([]RecursiveItem, 0) 1169 for it.Next() { 1170 if it.Err() != nil { 1171 assert.NoError(it.Err()) 1172 continue 1173 } 1174 1175 recursiveItems = append(recursiveItems, it.Resource()) 1176 assert.NotEqual(it.Resource().Path, "") 1177 } 1178 paths := lo.Map[RecursiveItem, string](recursiveItems, func(item RecursiveItem, index int) string { 1179 return item.Path 1180 }) 1181 assert.Len(paths, 4) 1182 errs := lo.Map[RecursiveItem, error](recursiveItems, func(item RecursiveItem, index int) error { 1183 return item.Err() 1184 }) 1185 errs = lo.Reject[error](errs, func(err error, index int) bool { 1186 return err == nil 1187 }) 1188 assert.ElementsMatch([]string{"azure", "aws-sftp"}, []string{errs[0].(*fs2.PathError).Path, errs[1].(*fs2.PathError).Path}) 1189 } 1190 1191 func TestClient_UploadFile(t *testing.T) { 1192 client, r, err := CreateClient("TestClient_UploadFile") 1193 if err != nil { 1194 t.Fatal(err) 1195 } 1196 fileName := filepath.Join(t.TempDir(), "anything") 1197 file, err := os.Create(fileName) 1198 require.NoError(t, err) 1199 file.Write([]byte("anything")) 1200 file.Close() 1201 1202 err = client.UploadFile(fileName, "test/anything") 1203 require.NoError(t, err) 1204 1205 sdkFile, err := client.Find(files_sdk.FileFindParams{Path: "test/anything"}) 1206 require.NoError(t, err) 1207 require.Equal(t, sdkFile.DisplayName, "anything") 1208 fs := (&FS{}).Init(client.Config, false).WithContext(context.Background()).(fs2.FS) 1209 fsFile, err := fs.Open("test/anything") 1210 require.NoError(t, err) 1211 fileBytes, err := io.ReadAll(fsFile) 1212 require.NoError(t, err) 1213 require.Equal(t, "anything", string(fileBytes)) 1214 r.Stop() 1215 } 1216 1217 func TestClient_ListFor(t *testing.T) { 1218 client, r, err := CreateClient("TestClient_ListFor") 1219 if err != nil { 1220 t.Fatal(err) 1221 } 1222 1223 buildScenario("TestClient_DownloadFolder", client) 1224 1225 assert := assert.New(t) 1226 1227 it, err := client.ListFor(files_sdk.FolderListForParams{ 1228 ListParams: files_sdk.ListParams{PerPage: 1}, 1229 Path: "TestClient_DownloadFolder/nested_1/nested_2", 1230 }) 1231 1232 assert.NoError(err) 1233 var files []files_sdk.File 1234 for it.Next() { 1235 if it.File().Type == "directory" { 1236 subIt, _ := it.Iterate(it.File().Identifier()) 1237 for subIt.Next() { 1238 subFile := subIt.Current().(files_sdk.File) 1239 files = append(files, subFile) 1240 loadedFile, err := it.LoadResource(subFile.Identifier()) 1241 assert.NoError(err) 1242 assert.Equal(subFile, loadedFile, "LoadResource with Identifier matches file from list") 1243 } 1244 } 1245 files = append(files, it.File()) 1246 1247 } 1248 paths := lo.Map[files_sdk.File, string](files, func(item files_sdk.File, index int) string { 1249 return item.Path 1250 }) 1251 assert.Equal([]string{ 1252 "TestClient_DownloadFolder/nested_1/nested_2/nested_3/4.text", 1253 "TestClient_DownloadFolder/nested_1/nested_2/nested_3", 1254 "TestClient_DownloadFolder/nested_1/nested_2/3.text", 1255 }, paths) 1256 1257 r.Stop() 1258 }