package converters import ( "testing" kbtypes "github.com/yaoapp/yao/kb/types" ) func TestOffice_Make(t *testing.T) { office := &Office{} t.Run("nil option should return error for missing vision converter", func(t *testing.T) { _, err := office.Make(nil) if err == nil { t.Error("Expected error for missing vision converter") } if err.Error() != "vision converter is required for office document processing" { t.Errorf("Expected specific error message, got: %v", err) } }) t.Run("empty option should return error for missing vision converter", func(t *testing.T) { option := &kbtypes.ProviderOption{} _, err := office.Make(option) if err == nil { t.Error("Expected error for missing vision converter") } if err.Error() != "vision converter is required for office document processing" { t.Errorf("Expected specific error message, got: %v", err) } }) t.Run("option with office processing properties should set all values", func(t *testing.T) { option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "max_concurrency": 8, "temp_dir": "/tmp/office", "cleanup_temp": false, "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, "video": map[string]interface{}{ "converter": "__yao.video", "properties": map[string]interface{}{ "keyframe_interval": 10.0, }, }, "audio": map[string]interface{}{ "converter": "__yao.whisper", "properties": map[string]interface{}{ "connector": "openai.whisper", }, }, }, } // This will fail because converter factories aren't set up in tests _, err := office.Make(option) if err == nil { t.Error("Expected error due to mock factory limitation") } // In real usage, this would work with proper factory setup }) t.Run("numeric values should handle both int and float64", func(t *testing.T) { option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "max_concurrency": 6.0, // float64 -> int "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, }, } // This will fail due to factory setup, but we're testing the parsing logic _, err := office.Make(option) // We expect error due to vision converter factory not being set up if err == nil { t.Error("Expected error due to test limitations") } }) t.Run("boolean values should be handled correctly", func(t *testing.T) { option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "cleanup_temp": true, "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, }, } // This will fail due to factory setup, but we're testing the parsing logic _, err := office.Make(option) // We expect error due to vision converter factory not being set up if err == nil { t.Error("Expected error due to test limitations") } }) t.Run("invalid property types should be ignored", func(t *testing.T) { option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "max_concurrency": "invalid", // invalid type "temp_dir": 123, // invalid type "cleanup_temp": "invalid", // invalid type "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, }, } // This will fail due to factory setup, but we're testing the parsing logic _, err := office.Make(option) // We expect error due to vision converter factory not being set up if err == nil { t.Error("Expected error due to test limitations") } }) t.Run("only vision converter should work", func(t *testing.T) { option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, }, } // This will fail due to factory setup, but we're testing the parsing logic _, err := office.Make(option) // We expect error due to vision converter factory not being set up if err == nil { t.Error("Expected error due to test limitations") } }) t.Run("invalid vision converter should return error", func(t *testing.T) { option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "vision": "invalid_format", // should be a map }, } _, err := office.Make(option) if err == nil { t.Error("Expected error for invalid vision converter format") } }) t.Run("invalid video converter should return error", func(t *testing.T) { option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, "video": []string{"invalid"}, // should be a map }, } _, err := office.Make(option) if err == nil { t.Error("Expected error for invalid video converter format") } }) t.Run("invalid audio converter should return error", func(t *testing.T) { option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, "audio": 123, // should be a map }, } _, err := office.Make(option) if err == nil { t.Error("Expected error for invalid audio converter format") } }) t.Run("partial properties should use defaults for missing values", func(t *testing.T) { option := &kbtypes.ProviderOption{ Properties: map[string]interface{}{ "max_concurrency": 12, "vision": map[string]interface{}{ "converter": "__yao.vision", "properties": map[string]interface{}{ "connector": "openai.gpt-4o-mini", }, }, // temp_dir and cleanup_temp should use defaults }, } // This will fail due to factory setup, but we're testing the parsing logic _, err := office.Make(option) // We expect error due to vision converter factory not being set up if err == nil { t.Error("Expected error due to test limitations") } }) } func TestOffice_AutoDetect(t *testing.T) { office := &Office{ Autodetect: []string{".docx", ".pptx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, MatchPriority: 10, } t.Run("should detect .docx files", func(t *testing.T) { match, priority, err := office.AutoDetect("document.docx", "") if err != nil { t.Errorf("Expected no error, got %v", err) } if !match { t.Error("Expected match for .docx file") } if priority != 10 { t.Errorf("Expected priority 10, got %d", priority) } }) t.Run("should detect .pptx files", func(t *testing.T) { match, priority, err := office.AutoDetect("presentation.pptx", "") if err != nil { t.Errorf("Expected no error, got %v", err) } if !match { t.Error("Expected match for .pptx 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 := office.AutoDetect("unknown", "application/vnd.openxmlformats-officedocument.wordprocessingml.document") if err != nil { t.Errorf("Expected no error, got %v", err) } if !match { t.Error("Expected match for Word document 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 := office.AutoDetect("image.jpg", "image/jpeg") if err != nil { t.Errorf("Expected no error, got %v", err) } if match { t.Error("Expected no match for .jpg file") } if priority != 0 { t.Errorf("Expected priority 0, got %d", priority) } }) t.Run("should not detect old Office formats", func(t *testing.T) { match, priority, err := office.AutoDetect("document.doc", "application/msword") if err != nil { t.Errorf("Expected no error, got %v", err) } if match { t.Error("Expected no match for .doc file (old format)") } if priority != 0 { t.Errorf("Expected priority 0, got %d", priority) } }) t.Run("empty autodetect should not match", func(t *testing.T) { emptyOffice := &Office{} match, priority, err := emptyOffice.AutoDetect("document.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document") 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 TestOffice_Schema(t *testing.T) { office := &Office{} schema, err := office.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") } }