package services import ( "bytes" "image/color" "image/jpeg" "testing" "github.com/disintegration/imaging" "go.uber.org/zap" ) func TestNewEnhancedImageService(t *testing.T) { logger := zap.NewNop() service := NewEnhancedImageService(logger) if service == nil { t.Error("NewEnhancedImageService() returned nil") } if service.logger == nil { t.Error("NewEnhancedImageService() returned service with nil logger") } } func TestGetSizeDimensions(t *testing.T) { tests := []struct { name string size ImageSize expectedWidth int expectedHeight int }{ { name: "thumbnail size", size: SizeThumbnail, expectedWidth: 100, expectedHeight: 100, }, { name: "small size", size: SizeSmall, expectedWidth: 200, expectedHeight: 200, }, { name: "medium size", size: SizeMedium, expectedWidth: 400, expectedHeight: 400, }, { name: "large size", size: SizeLarge, expectedWidth: 800, expectedHeight: 800, }, { name: "default size", size: ImageSize("unknown"), expectedWidth: 200, expectedHeight: 200, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { width, height := GetSizeDimensions(tt.size) if width != tt.expectedWidth { t.Errorf("GetSizeDimensions() width = %d, want %d", width, tt.expectedWidth) } if height != tt.expectedHeight { t.Errorf("GetSizeDimensions() height = %d, want %d", height, tt.expectedHeight) } }) } } func TestEnhancedImageService_resizeWithCropCenter(t *testing.T) { service := NewEnhancedImageService(zap.NewNop()) // Create a test image (500x300) testImg := imaging.New(500, 300, color.RGBA{255, 0, 0, 255}) // Resize to 200x200 resized := service.resizeWithCropCenter(testImg, 200, 200) bounds := resized.Bounds() if bounds.Dx() != 200 { t.Errorf("resizeWithCropCenter() width = %d, want 200", bounds.Dx()) } if bounds.Dy() != 200 { t.Errorf("resizeWithCropCenter() height = %d, want 200", bounds.Dy()) } } func TestEnhancedImageService_resizeMaintainAspectRatio(t *testing.T) { service := NewEnhancedImageService(zap.NewNop()) // Create a test image (500x300) testImg := imaging.New(500, 300, color.RGBA{255, 0, 0, 255}) // Resize maintaining aspect ratio (max 200x200) resized := service.resizeMaintainAspectRatio(testImg, 200, 200) bounds := resized.Bounds() // Should maintain aspect ratio (5:3) // Width should be 200, height should be 120 if bounds.Dx() != 200 { t.Errorf("resizeMaintainAspectRatio() width = %d, want 200", bounds.Dx()) } if bounds.Dy() != 120 { t.Errorf("resizeMaintainAspectRatio() height = %d, want 120", bounds.Dy()) } } func TestEnhancedImageService_encodeJPEG(t *testing.T) { service := NewEnhancedImageService(zap.NewNop()) // Create a test image testImg := imaging.New(100, 100, color.RGBA{255, 0, 0, 255}) // Encode as JPEG data, err := service.encodeJPEG(testImg, 85) if err != nil { t.Fatalf("encodeJPEG() error = %v", err) } if len(data) == 0 { t.Error("encodeJPEG() returned empty data") } // Verify it's valid JPEG _, err = jpeg.Decode(bytes.NewReader(data)) if err != nil { t.Errorf("encodeJPEG() produced invalid JPEG: %v", err) } } func TestEnhancedImageService_encodePNG(t *testing.T) { service := NewEnhancedImageService(zap.NewNop()) // Create a test image testImg := imaging.New(100, 100, color.RGBA{255, 0, 0, 255}) // Encode as PNG data, err := service.encodePNG(testImg) if err != nil { t.Fatalf("encodePNG() error = %v", err) } if len(data) == 0 { t.Error("encodePNG() returned empty data") } } // TestEnhancedImageService_GetImageDimensions would require proper multipart.FileHeader mock // This is tested indirectly through ProcessImage tests // func TestEnhancedImageService_GetImageDimensions(t *testing.T) { // // Implementation would require multipart.FileHeader mock // } func TestImageProcessingOptions_Defaults(t *testing.T) { options := ImageProcessingOptions{} // Test that defaults are applied in ProcessImage method if options.Quality <= 0 || options.Quality > 100 { options.Quality = 85 } if options.Format == "" { options.Format = FormatJPEG } if !options.MaintainAspectRatio { options.MaintainAspectRatio = true } if !options.CropCenter { options.CropCenter = true } if options.Quality != 85 { t.Errorf("Expected default quality 85, got %d", options.Quality) } if options.Format != FormatJPEG { t.Errorf("Expected default format JPEG, got %v", options.Format) } } // Note: Full integration tests would require: // 1. Real image files (JPEG, PNG, WebP) // 2. Multipart file headers // 3. Verification of processed image dimensions and quality // 4. Performance testing with large images // // Example integration test structure: // func TestEnhancedImageService_ProcessImage_Integration(t *testing.T) { // // Create test image file // testImg := createTestImageFile(t, 1000, 1000) // defer os.Remove(testImg) // // // Create multipart file header // fileHeader := createMultipartFileHeader(t, testImg) // // service := NewEnhancedImageService(zap.NewNop()) // // ctx := context.Background() // options := ImageProcessingOptions{ // Size: SizeSmall, // Format: FormatJPEG, // Quality: 85, // } // // result, err := service.ProcessImage(ctx, fileHeader, options) // if err != nil { // t.Fatalf("ProcessImage() error = %v", err) // } // // if result.Width != 200 || result.Height != 200 { // t.Errorf("ProcessImage() dimensions = %dx%d, want 200x200", result.Width, result.Height) // } // // if len(result.Data) == 0 { // t.Error("ProcessImage() returned empty data") // } // }