Wox/wox.core/plugin/system/browser_bookmark_test.go

277 lines
9.8 KiB
Go

package system
import (
"context"
"os"
"path/filepath"
"testing"
"wox/common"
"wox/plugin"
"wox/setting/definition"
"github.com/stretchr/testify/assert"
)
func TestBrowserBookmarkPlugin_loadBookmarkFromFile(t *testing.T) {
// Create a temporary bookmark file for testing
tempDir := t.TempDir()
bookmarkFile := filepath.Join(tempDir, "Bookmarks")
// Sample bookmark JSON content (more realistic format)
bookmarkContent := `{
"roots": {
"bookmark_bar": {
"children": [
{
"date_added": "13285874237000000",
"date_last_used": "0",
"guid": "00000000-0000-4000-A000-000000000001",
"id": "5",
"name": "Google",
"type": "url",
"url": "https://www.google.com"
},
{
"date_added": "13285874237000000",
"date_last_used": "0",
"guid": "00000000-0000-4000-A000-000000000002",
"id": "6",
"name": "GitHub",
"type": "url",
"url": "https://github.com"
}
]
}
}
}`
err := os.WriteFile(bookmarkFile, []byte(bookmarkContent), 0644)
assert.NoError(t, err)
// Create plugin instance
plugin := &BrowserBookmarkPlugin{}
plugin.api = &mockAPI{}
// Test loading bookmarks
ctx := context.Background()
bookmarks := plugin.loadBookmarkFromFile(ctx, bookmarkFile, "TestBrowser")
// Verify results
assert.Len(t, bookmarks, 2)
if len(bookmarks) >= 2 {
assert.Equal(t, "Google", bookmarks[0].Name)
assert.Equal(t, "https://www.google.com", bookmarks[0].Url)
assert.Equal(t, "GitHub", bookmarks[1].Name)
assert.Equal(t, "https://github.com", bookmarks[1].Url)
}
}
func TestBrowserBookmarkPlugin_ChromeBookmarkPaths(t *testing.T) {
plugin := &BrowserBookmarkPlugin{}
plugin.api = &mockAPI{}
ctx := context.Background()
// Test Windows Chrome path - only if Chrome is installed
if os.Getenv("LOCALAPPDATA") != "" {
chromeDir := filepath.Join(os.Getenv("LOCALAPPDATA"), "Google", "Chrome", "User Data")
if _, err := os.Stat(chromeDir); err == nil {
t.Log("Chrome detected on Windows, testing Chrome bookmark loading")
bookmarks := plugin.loadChromeBookmarkInWindows(ctx, "Default")
// Should return a slice (even if empty) and not panic
assert.NotNil(t, bookmarks)
assert.IsType(t, []Bookmark{}, bookmarks)
t.Logf("Chrome Windows test: found %d bookmarks", len(bookmarks))
} else {
t.Log("Chrome not found on Windows, skipping Chrome bookmark test")
}
}
// Test macOS Chrome path - only if Chrome is installed
homeDir, _ := os.UserHomeDir()
if homeDir != "" {
chromeDir := filepath.Join(homeDir, "Library", "Application Support", "Google", "Chrome")
if _, err := os.Stat(chromeDir); err == nil {
t.Log("Chrome detected on macOS, testing Chrome bookmark loading")
bookmarks := plugin.loadChromeBookmarkInMacos(ctx, "Default")
assert.NotNil(t, bookmarks)
} else {
t.Log("Chrome not found on macOS, skipping Chrome bookmark test")
}
}
// Test Linux Chrome path - only if Chrome is installed
if homeDir, _ := os.UserHomeDir(); homeDir != "" {
chromeDir := filepath.Join(homeDir, ".config", "google-chrome")
if _, err := os.Stat(chromeDir); err == nil {
t.Log("Chrome detected on Linux, testing Chrome bookmark loading")
bookmarks := plugin.loadChromeBookmarkInLinux(ctx, "Default")
assert.NotNil(t, bookmarks)
} else {
t.Log("Chrome not found on Linux, skipping Chrome bookmark test")
}
}
}
func TestBrowserBookmarkPlugin_EdgeBookmarkPaths(t *testing.T) {
plugin := &BrowserBookmarkPlugin{}
plugin.api = &mockAPI{}
ctx := context.Background()
// Test Windows Edge path - only if Edge is installed
if os.Getenv("LOCALAPPDATA") != "" {
edgeDir := filepath.Join(os.Getenv("LOCALAPPDATA"), "Microsoft", "Edge", "User Data")
if _, err := os.Stat(edgeDir); err == nil {
t.Log("Edge detected on Windows, testing Edge bookmark loading")
// Check if Default profile exists
defaultProfilePath := filepath.Join(edgeDir, "Default")
if _, err := os.Stat(defaultProfilePath); err == nil {
t.Logf("Default profile found at: %s", defaultProfilePath)
// Check if Bookmarks file exists
bookmarkFile := filepath.Join(defaultProfilePath, "Bookmarks")
if _, err := os.Stat(bookmarkFile); err == nil {
t.Logf("Bookmarks file found at: %s", bookmarkFile)
// Read and log first 500 characters of bookmark file for debugging
content, err := os.ReadFile(bookmarkFile)
if err == nil {
contentStr := string(content)
if len(contentStr) > 500 {
contentStr = contentStr[:500] + "..."
}
t.Logf("Bookmark file content preview: %s", contentStr)
} else {
t.Logf("Error reading bookmark file: %v", err)
}
} else {
t.Logf("Bookmarks file not found at: %s", bookmarkFile)
}
} else {
t.Logf("Default profile not found at: %s", defaultProfilePath)
// List available profiles
entries, err := os.ReadDir(edgeDir)
if err == nil {
t.Log("Available profiles:")
for _, entry := range entries {
if entry.IsDir() {
t.Logf(" - %s", entry.Name())
}
}
}
}
bookmarks := plugin.loadEdgeBookmarkInWindows(ctx, "Default")
// Should return a slice (even if empty) and not panic
assert.NotNil(t, bookmarks)
t.Logf("Edge Windows test: found %d bookmarks", len(bookmarks))
} else {
t.Log("Edge not found on Windows, skipping Edge bookmark test")
}
}
// Test macOS Edge path - only if Edge is installed
homeDir, _ := os.UserHomeDir()
if homeDir != "" {
edgeDir := filepath.Join(homeDir, "Library", "Application Support", "Microsoft Edge")
if _, err := os.Stat(edgeDir); err == nil {
t.Log("Edge detected on macOS, testing Edge bookmark loading")
bookmarks := plugin.loadEdgeBookmarkInMacos(ctx, "Default")
assert.NotNil(t, bookmarks)
} else {
t.Log("Edge not found on macOS, skipping Edge bookmark test")
}
}
// Test Linux Edge path - only if Edge is installed
if homeDir, _ := os.UserHomeDir(); homeDir != "" {
edgeDir := filepath.Join(homeDir, ".config", "microsoft-edge")
if _, err := os.Stat(edgeDir); err == nil {
t.Log("Edge detected on Linux, testing Edge bookmark loading")
bookmarks := plugin.loadEdgeBookmarkInLinux(ctx, "Default")
assert.NotNil(t, bookmarks)
} else {
t.Log("Edge not found on Linux, skipping Edge bookmark test")
}
}
}
func TestBrowserBookmarkPlugin_RemoveDuplicateBookmarks(t *testing.T) {
plugin := &BrowserBookmarkPlugin{}
plugin.api = &mockAPI{}
// Create test bookmarks with duplicates
bookmarks := []Bookmark{
{Name: "Google", Url: "https://www.google.com"},
{Name: "GitHub", Url: "https://github.com"},
{Name: "Google", Url: "https://www.google.com"}, // Duplicate
{Name: "Stack Overflow", Url: "https://stackoverflow.com"},
{Name: "GitHub", Url: "https://github.com"}, // Duplicate
{Name: "Google", Url: "https://www.google.cn"}, // Different URL, should keep
{Name: "Google Search", Url: "https://www.google.com"}, // Different name, should keep
}
// Remove duplicates
result := plugin.removeDuplicateBookmarks(bookmarks)
// Verify results
assert.Len(t, result, 5) // Should have 5 unique bookmarks
// Verify each bookmark exists and is unique
seen := make(map[string]bool)
for _, bookmark := range result {
key := bookmark.Name + "|" + bookmark.Url
assert.False(t, seen[key], "Duplicate bookmark found: %s", key)
seen[key] = true
}
// Verify that we have the expected unique combinations
expectedKeys := []string{
"Google|https://www.google.com",
"GitHub|https://github.com",
"Stack Overflow|https://stackoverflow.com",
"Google|https://www.google.cn",
"Google Search|https://www.google.com",
}
for _, expectedKey := range expectedKeys {
assert.True(t, seen[expectedKey], "Expected bookmark not found: %s", expectedKey)
}
}
// Mock API for testing
type mockAPI struct{}
func (m *mockAPI) Log(ctx context.Context, level plugin.LogLevel, msg string) {
// Output log messages during testing
if testing.Verbose() {
println("LOG:", msg)
}
}
func (m *mockAPI) Notify(ctx context.Context, msg string) {}
func (m *mockAPI) GetTranslation(ctx context.Context, key string) string { return key }
func (m *mockAPI) GetSetting(ctx context.Context, key string) string { return "" }
func (m *mockAPI) SaveSetting(ctx context.Context, key string, value string, isGlobal bool) {
}
func (m *mockAPI) GetAllSettings(ctx context.Context) map[string]string { return nil }
func (m *mockAPI) OpenSettingDialog(ctx context.Context) {}
func (m *mockAPI) HideApp(ctx context.Context) {}
func (m *mockAPI) ShowApp(ctx context.Context) {}
func (m *mockAPI) ChangeQuery(ctx context.Context, query common.PlainQuery) {}
func (m *mockAPI) RestartApp(ctx context.Context) {}
func (m *mockAPI) ReloadPlugin(ctx context.Context, pluginId string) {}
func (m *mockAPI) RemovePlugin(ctx context.Context, pluginId string) {}
func (m *mockAPI) OnSettingChanged(ctx context.Context, callback func(key string, value string)) {}
func (m *mockAPI) OnGetDynamicSetting(context.Context, func(string) definition.PluginSettingDefinitionItem) {
}
func (m *mockAPI) OnDeepLink(ctx context.Context, callback func(arguments map[string]string)) {}
func (m *mockAPI) OnUnload(ctx context.Context, callback func()) {}
func (m *mockAPI) RegisterQueryCommands(ctx context.Context, commands []plugin.MetadataCommand) {}
func (m *mockAPI) AIChatStream(ctx context.Context, model common.Model, conversations []common.Conversation, options common.ChatOptions, callback common.ChatStreamFunc) error {
return nil
}
func (m *mockAPI) OnMRURestore(ctx context.Context, callback func(mruData plugin.MRUData) (*plugin.QueryResult, error)) {
}