package converters import ( "testing" "github.com/yaoapp/yao/config" kbtypes "github.com/yaoapp/yao/kb/types" "github.com/yaoapp/yao/test" ) func TestVideo_Make(t *testing.T) { // Setup test.Prepare(&testing.T{}, config.Conf) defer test.Clean() video := &Video{} t.Run("should use global FFmpeg configuration as defaults", func(t *testing.T) { // Set up global FFmpeg configuration globalFFmpegConfig := &kbtypes.FFmpegConfig{ FFmpegPath: "/usr/local/bin/ffmpeg", FFprobePath: "/usr/local/bin/ffprobe", EnableGPU: true, GPUIndex: 0, MaxProcesses: 8, MaxThreads: 16, } kbtypes.SetGlobalFFmpeg(globalFFmpegConfig) // Clean up after test defer kbtypes.SetGlobalFFmpeg(nil) option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, "audio": map[string]interface{}{ "converter": "__yao.whisper", "properties": map[string]interface{}{ "connector": "openai.whisper-1", }, }, }, } // This will fail because converters factory isn't set up in tests // but we can verify the global config would be used _, err := video.Make(option) if err == nil { t.Error("Expected error due to mock factory limitation") } // In real usage with proper factory setup, this would work // and would use global FFmpeg configuration as defaults }) t.Run("properties should override global FFmpeg configuration", func(t *testing.T) { // Set up global FFmpeg configuration globalFFmpegConfig := &kbtypes.FFmpegConfig{ FFmpegPath: "/usr/local/bin/ffmpeg", FFprobePath: "/usr/local/bin/ffprobe", EnableGPU: true, GPUIndex: 0, MaxProcesses: 8, MaxThreads: 16, } kbtypes.SetGlobalFFmpeg(globalFFmpegConfig) // Clean up after test defer kbtypes.SetGlobalFFmpeg(nil) option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "ffmpeg_path": "/opt/ffmpeg/bin/ffmpeg", // Override global path "ffprobe_path": "/opt/ffmpeg/bin/ffprobe", // Override global path "enable_gpu": false, // Override global GPU setting "gpu_index": 1, // Override global GPU index "max_threads": 8, // Override global max threads "max_concurrency": 4, // Override global max processes "keyframe_interval": 5.0, // Video-specific setting "max_keyframes": 10, // Video-specific setting "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, "audio": map[string]interface{}{ "converter": "__yao.whisper", "properties": map[string]interface{}{ "connector": "openai.whisper-1", }, }, }, } // This will fail because converters factory isn't set up in tests // but the properties would override the global configuration _, err := video.Make(option) if err == nil { t.Error("Expected error due to mock factory limitation") } // In real usage, this would use overridden values instead of global config }) t.Run("should work without global FFmpeg configuration", func(t *testing.T) { // Ensure no global FFmpeg configuration is set kbtypes.SetGlobalFFmpeg(nil) option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "ffmpeg_path": "/usr/bin/ffmpeg", "ffprobe_path": "/usr/bin/ffprobe", "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, "audio": map[string]interface{}{ "converter": "__yao.whisper", "properties": map[string]interface{}{ "connector": "openai.whisper-1", }, }, }, } // This will fail because converters factory isn't set up in tests _, err := video.Make(option) if err == nil { t.Error("Expected error due to mock factory limitation") } // In real usage, this would work and use hardcoded defaults for unspecified FFmpeg settings }) t.Run("should handle numeric type conversions", func(t *testing.T) { option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "keyframe_interval": 15, // int instead of float64 "max_keyframes": 25.0, // float64 instead of int "max_concurrency": 6.0, // float64 instead of int "gpu_index": 2.0, // float64 instead of int "max_threads": 12.0, // float64 instead of int "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, "audio": map[string]interface{}{ "converter": "__yao.whisper", "properties": map[string]interface{}{ "connector": "openai.whisper-1", }, }, }, } // This will fail because converters factory isn't set up in tests _, err := video.Make(option) if err == nil { t.Error("Expected error due to mock factory limitation") } // In real usage, this would work and properly convert numeric types }) } func TestVideo_AutoDetect(t *testing.T) { video := &Video{ Autodetect: []string{".mp4", ".mov", ".avi", "video/mp4", "video/quicktime"}, MatchPriority: 10, } t.Run("should detect .mp4 files", func(t *testing.T) { match, priority, err := video.AutoDetect("movie.mp4", "") if err != nil { t.Errorf("Expected no error, got %v", err) } if !match { t.Error("Expected match for .mp4 file") } if priority != 10 { t.Errorf("Expected priority 10, got %d", priority) } }) t.Run("should detect .mov files", func(t *testing.T) { match, priority, err := video.AutoDetect("video.mov", "") if err != nil { t.Errorf("Expected no error, got %v", err) } if !match { t.Error("Expected match for .mov file") } if priority != 10 { t.Errorf("Expected priority 10, got %d", priority) } }) t.Run("should detect by content type", func(t *testing.T) { match, priority, err := video.AutoDetect("unknown", "video/mp4") if err != nil { t.Errorf("Expected no error, got %v", err) } if !match { t.Error("Expected match for video/mp4 content type") } if priority != 10 { t.Errorf("Expected priority 10, got %d", priority) } }) t.Run("should not detect unsupported files", func(t *testing.T) { match, priority, err := video.AutoDetect("audio.mp3", "audio/mpeg") if err != nil { t.Errorf("Expected no error, got %v", err) } if match { t.Error("Expected no match for .mp3 file") } if priority != 0 { t.Errorf("Expected priority 0, got %d", priority) } }) t.Run("empty autodetect should not match", func(t *testing.T) { emptyVideo := &Video{} match, priority, err := emptyVideo.AutoDetect("video.mp4", "video/mp4") if err != nil { t.Errorf("Expected no error, got %v", err) } if match { t.Error("Expected no match when autodetect is empty") } if priority != 0 { t.Errorf("Expected priority 0, got %d", priority) } }) } func TestVideo_Schema(t *testing.T) { video := &Video{} schema, err := video.Schema(nil, "en") if err != nil { t.Errorf("Expected no error, got %v", err) } if schema == nil { t.Error("Expected non-nil schema from factory.GetSchemaFromBindata") } }