diff options
| author | s <[email protected]> | 2025-11-13 14:43:15 -0500 |
|---|---|---|
| committer | s <[email protected]> | 2025-11-13 14:43:15 -0500 |
| commit | 344a6f6415c3c1b593677adec3b8844e0839971b (patch) | |
| tree | b05291ecdf21917b27e9e234eeb997c2706966d5 /internal/formatter/buckets_test.go | |
| parent | a5fc01a03753c9a18ddeaf13610dd99b4b311b80 (diff) | |
| download | dborg-344a6f6415c3c1b593677adec3b8844e0839971b.tar.gz dborg-344a6f6415c3c1b593677adec3b8844e0839971b.zip | |
created pretty printing for all commandsv1.0.0
Diffstat (limited to 'internal/formatter/buckets_test.go')
| -rw-r--r-- | internal/formatter/buckets_test.go | 509 |
1 files changed, 509 insertions, 0 deletions
diff --git a/internal/formatter/buckets_test.go b/internal/formatter/buckets_test.go new file mode 100644 index 0000000..eabddf0 --- /dev/null +++ b/internal/formatter/buckets_test.go @@ -0,0 +1,509 @@ +package formatter + +import ( + "bytes" + "os" + "testing" + + "git.db.org.ai/dborg/internal/models" +) + +func TestFormatBucketsResults(t *testing.T) { + tests := []struct { + name string + response *models.BucketsSearchResponse + asJSON bool + wantErr bool + }{ + { + name: "format_buckets_with_multiple_types", + response: &models.BucketsSearchResponse{ + Credits: models.CreditsInfo{ + Unlimited: true, + }, + Results: map[string]any{ + "buckets": []any{ + map[string]any{ + "bucket": "test-bucket.s3.amazonaws.com", + "fileCount": float64(1500), + "id": float64(1), + "type": "aws", + }, + map[string]any{ + "bucket": "another.s3-eu-west-1.amazonaws.com", + "fileCount": float64(250), + "id": float64(2), + "type": "aws", + }, + map[string]any{ + "bucket": "storage.googleapis.com", + "fileCount": float64(10000), + "id": float64(3), + "type": "gcp", + }, + map[string]any{ + "bucket": "spaces.digitaloceanspaces.com", + "fileCount": float64(0), + "id": float64(4), + "type": "dos", + }, + }, + }, + }, + asJSON: false, + wantErr: false, + }, + { + name: "format_empty_buckets", + response: &models.BucketsSearchResponse{ + Credits: models.CreditsInfo{ + Remaining: 100, + Unlimited: false, + }, + Results: nil, + }, + asJSON: false, + wantErr: false, + }, + { + name: "format_json_output", + response: &models.BucketsSearchResponse{ + Credits: models.CreditsInfo{ + Unlimited: true, + }, + Results: map[string]any{ + "buckets": []any{ + map[string]any{ + "bucket": "test.s3.amazonaws.com", + "type": "aws", + }, + }, + }, + }, + asJSON: true, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + oldStdout := os.Stdout + r, w, _ := os.Pipe() + os.Stdout = w + + err := FormatBucketsResults(tt.response, tt.asJSON) + + w.Close() + var buf bytes.Buffer + buf.ReadFrom(r) + os.Stdout = oldStdout + + if (err != nil) != tt.wantErr { + t.Errorf("FormatBucketsResults() error = %v, wantErr %v", err, tt.wantErr) + return + } + + output := buf.String() + if !tt.asJSON && tt.response.Results != nil { + if output == "" { + t.Error("Expected non-empty output for non-JSON formatting") + } + } + }) + } +} + +func TestFormatBucketFilesResults(t *testing.T) { + tests := []struct { + name string + response *models.BucketsFilesSearchResponse + asJSON bool + wantErr bool + }{ + { + name: "format_files_grouped_by_bucket", + response: &models.BucketsFilesSearchResponse{ + Credits: models.CreditsInfo{ + Unlimited: true, + }, + Results: map[string]any{ + "files": []any{ + map[string]any{ + "bucket": "test-bucket.s3.amazonaws.com", + "file": "documents/report.pdf", + "url": "https://test-bucket.s3.amazonaws.com/documents/report.pdf", + "size": float64(1024000), + "lastModified": "2024-01-01T00:00:00Z", + }, + map[string]any{ + "bucket": "test-bucket.s3.amazonaws.com", + "file": "images/logo.png", + "url": "https://test-bucket.s3.amazonaws.com/images/logo.png", + "size": float64(50000), + }, + map[string]any{ + "bucket": "another-bucket.s3.amazonaws.com", + "file": "data.json", + "url": "https://another-bucket.s3.amazonaws.com/data.json", + }, + }, + }, + }, + asJSON: false, + wantErr: false, + }, + { + name: "format_empty_files", + response: &models.BucketsFilesSearchResponse{ + Credits: models.CreditsInfo{ + Remaining: 50, + Unlimited: false, + }, + Results: map[string]any{ + "files": []any{}, + }, + }, + asJSON: false, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + oldStdout := os.Stdout + r, w, _ := os.Pipe() + os.Stdout = w + + err := FormatBucketFilesResults(tt.response, tt.asJSON) + + w.Close() + var buf bytes.Buffer + buf.ReadFrom(r) + os.Stdout = oldStdout + + if (err != nil) != tt.wantErr { + t.Errorf("FormatBucketFilesResults() error = %v, wantErr %v", err, tt.wantErr) + return + } + }) + } +} + +func TestGetBucketTypeHeader(t *testing.T) { + tests := []struct { + name string + bucketType string + wantNonEmpty bool + }{ + { + name: "aws_header", + bucketType: "aws", + wantNonEmpty: true, + }, + { + name: "gcp_header", + bucketType: "gcp", + wantNonEmpty: true, + }, + { + name: "dos_header", + bucketType: "dos", + wantNonEmpty: true, + }, + { + name: "unknown_header", + bucketType: "custom", + wantNonEmpty: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := getBucketTypeHeader(tt.bucketType) + if tt.wantNonEmpty && got == "" { + t.Errorf("getBucketTypeHeader() returned empty string for %s", tt.bucketType) + } + }) + } +} + +func TestFormatFileCount(t *testing.T) { + tests := []struct { + name string + count int + want bool + }{ + { + name: "small_count", + count: 10, + want: true, + }, + { + name: "medium_count", + count: 500, + want: true, + }, + { + name: "large_count", + count: 5000, + want: true, + }, + { + name: "very_large_count", + count: 50000, + want: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := formatFileCount(tt.count) + if tt.want && got == "" { + t.Errorf("formatFileCount() returned empty for count %d", tt.count) + } + }) + } +} + +func TestFormatNumber(t *testing.T) { + tests := []struct { + name string + n int + want string + }{ + { + name: "small_number", + n: 999, + want: "999", + }, + { + name: "thousand", + n: 1000, + want: "1,000", + }, + { + name: "million", + n: 1000000, + want: "1,000,000", + }, + { + name: "random_large", + n: 12345678, + want: "12,345,678", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := formatNumber(tt.n) + if got != tt.want { + t.Errorf("formatNumber() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetExtensionColor(t *testing.T) { + tests := []struct { + name string + ext string + want string + }{ + { + name: "pdf_extension", + ext: "pdf", + want: ColorBlue, + }, + { + name: "image_extension", + ext: "png", + want: ColorGreen, + }, + { + name: "video_extension", + ext: "mp4", + want: ColorMagenta, + }, + { + name: "archive_extension", + ext: "zip", + want: ColorYellow, + }, + { + name: "database_extension", + ext: "sql", + want: ColorRed, + }, + { + name: "config_extension", + ext: "json", + want: ColorCyan, + }, + { + name: "unknown_extension", + ext: "xyz", + want: ColorWhite, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := getExtensionColor(tt.ext) + if got != tt.want { + t.Errorf("getExtensionColor() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestTruncateBucketName(t *testing.T) { + tests := []struct { + name string + bucket string + wantLen int + }{ + { + name: "short_name", + bucket: "test-bucket", + wantLen: 50, + }, + { + name: "long_aws_bucket", + bucket: "very-long-bucket-name-that-exceeds-the-limit.s3.amazonaws.com", + wantLen: 60, + }, + { + name: "long_gcp_bucket", + bucket: "extremely-long-google-cloud-storage-bucket-name.storage.googleapis.com", + wantLen: 80, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := truncateBucketName(tt.bucket) + if len(got) > tt.wantLen { + t.Errorf("truncateBucketName() length = %d, want <= %d", len(got), tt.wantLen) + } + }) + } +} + +func TestExtractFileNameFromURL(t *testing.T) { + tests := []struct { + name string + url string + want string + }{ + { + name: "simple_filename", + url: "https://bucket.s3.amazonaws.com/file.pdf", + want: "file.pdf", + }, + { + name: "filename_with_path", + url: "https://bucket.s3.amazonaws.com/path/to/document.docx", + want: "document.docx", + }, + { + name: "filename_with_query", + url: "https://bucket.s3.amazonaws.com/image.jpg?version=123", + want: "image.jpg", + }, + { + name: "encoded_filename", + url: "https://bucket.s3.amazonaws.com/my%20file%20name.pdf", + want: "my%20file%20name.pdf", + }, + { + name: "no_filename", + url: "https://bucket.s3.amazonaws.com/", + want: "index", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := extractFileNameFromURL(tt.url) + if got != tt.want { + t.Errorf("extractFileNameFromURL() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestExtractBucketFromURL(t *testing.T) { + tests := []struct { + name string + url string + want string + }{ + { + name: "aws_s3_url", + url: "https://my-bucket.s3.amazonaws.com/file.pdf", + want: "my-bucket.s3.amazonaws.com", + }, + { + name: "digitalocean_spaces", + url: "https://space.nyc3.digitaloceanspaces.com/path/file.jpg", + want: "space.nyc3.digitaloceanspaces.com", + }, + { + name: "gcp_storage", + url: "https://bucket.storage.googleapis.com/data.json", + want: "bucket.storage.googleapis.com", + }, + { + name: "http_url", + url: "http://bucket.example.com/file.txt", + want: "bucket.example.com", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := extractBucketFromURL(tt.url) + if got != tt.want { + t.Errorf("extractBucketFromURL() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDecodeURLEncoding(t *testing.T) { + tests := []struct { + name string + s string + want string + }{ + { + name: "spaces", + s: "my%20file%20name.pdf", + want: "my file name.pdf", + }, + { + name: "parentheses", + s: "document%28final%29.docx", + want: "document(final).docx", + }, + { + name: "underscores", + s: "test_file_name.jpg", + want: "test file name.jpg", + }, + { + name: "mixed", + s: "WhatsApp%20Image_2021%2810%29.jpeg", + want: "WhatsApp Image 2021(10).jpeg", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := decodeURLEncoding(tt.s) + if got != tt.want { + t.Errorf("decodeURLEncoding() = %v, want %v", got, tt.want) + } + }) + } +} |
