1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-08 06:25:37 -05:00
Files
DankMaterialShell/core/internal/plugins/registry_test.go
2025-11-12 23:12:31 -05:00

327 lines
8.6 KiB
Go

package plugins
import (
"encoding/json"
"path/filepath"
"testing"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type mockGitClient struct {
cloneFunc func(path string, url string) error
pullFunc func(path string) error
hasUpdatesFunc func(path string) (bool, error)
}
func (m *mockGitClient) PlainClone(path string, url string) error {
if m.cloneFunc != nil {
return m.cloneFunc(path, url)
}
return nil
}
func (m *mockGitClient) Pull(path string) error {
if m.pullFunc != nil {
return m.pullFunc(path)
}
return nil
}
func (m *mockGitClient) HasUpdates(path string) (bool, error) {
if m.hasUpdatesFunc != nil {
return m.hasUpdatesFunc(path)
}
return false, nil
}
func TestNewRegistry(t *testing.T) {
registry, err := NewRegistry()
assert.NoError(t, err)
assert.NotNil(t, registry)
assert.NotEmpty(t, registry.cacheDir)
}
func TestGetCacheDir(t *testing.T) {
cacheDir := getCacheDir()
assert.Contains(t, cacheDir, "/tmp/dankdots-plugin-registry")
}
func setupTestRegistry(t *testing.T) (*Registry, afero.Fs, string) {
fs := afero.NewMemMapFs()
tmpDir := "/test-cache"
registry := &Registry{
fs: fs,
cacheDir: tmpDir,
plugins: []Plugin{},
git: &mockGitClient{},
}
return registry, fs, tmpDir
}
func createTestPlugin(t *testing.T, fs afero.Fs, dir string, filename string, plugin Plugin) {
pluginsDir := filepath.Join(dir, "plugins")
err := fs.MkdirAll(pluginsDir, 0755)
require.NoError(t, err)
data, err := json.Marshal(plugin)
require.NoError(t, err)
err = afero.WriteFile(fs, filepath.Join(pluginsDir, filename), data, 0644)
require.NoError(t, err)
}
func TestLoadPlugins(t *testing.T) {
t.Run("loads valid plugin files", func(t *testing.T) {
registry, fs, tmpDir := setupTestRegistry(t)
plugin1 := Plugin{
Name: "TestPlugin1",
Capabilities: []string{"dankbar-widget"},
Category: "monitoring",
Repo: "https://github.com/test/plugin1",
Author: "Test Author",
Description: "Test plugin 1",
Compositors: []string{"niri"},
Distro: []string{"any"},
}
plugin2 := Plugin{
Name: "TestPlugin2",
Capabilities: []string{"system-tray"},
Category: "utilities",
Repo: "https://github.com/test/plugin2",
Author: "Another Author",
Description: "Test plugin 2",
Dependencies: []string{"dep1", "dep2"},
Compositors: []string{"hyprland", "niri"},
Distro: []string{"arch"},
Screenshot: "https://example.com/screenshot.png",
}
createTestPlugin(t, fs, tmpDir, "plugin1.json", plugin1)
createTestPlugin(t, fs, tmpDir, "plugin2.json", plugin2)
err := registry.loadPlugins()
assert.NoError(t, err)
assert.Len(t, registry.plugins, 2)
assert.Equal(t, "TestPlugin1", registry.plugins[0].Name)
assert.Equal(t, "TestPlugin2", registry.plugins[1].Name)
assert.Equal(t, []string{"dankbar-widget"}, registry.plugins[0].Capabilities)
assert.Equal(t, []string{"dep1", "dep2"}, registry.plugins[1].Dependencies)
})
t.Run("skips non-json files", func(t *testing.T) {
registry, fs, tmpDir := setupTestRegistry(t)
pluginsDir := filepath.Join(tmpDir, "plugins")
err := fs.MkdirAll(pluginsDir, 0755)
require.NoError(t, err)
err = afero.WriteFile(fs, filepath.Join(pluginsDir, "README.md"), []byte("# Test"), 0644)
require.NoError(t, err)
plugin := Plugin{
Name: "ValidPlugin",
Capabilities: []string{"test"},
Category: "test",
Repo: "https://github.com/test/test",
Author: "Test",
Description: "Test",
Compositors: []string{"niri"},
Distro: []string{"any"},
}
createTestPlugin(t, fs, tmpDir, "valid.json", plugin)
err = registry.loadPlugins()
assert.NoError(t, err)
assert.Len(t, registry.plugins, 1)
assert.Equal(t, "ValidPlugin", registry.plugins[0].Name)
})
t.Run("skips directories", func(t *testing.T) {
registry, fs, tmpDir := setupTestRegistry(t)
pluginsDir := filepath.Join(tmpDir, "plugins")
err := fs.MkdirAll(filepath.Join(pluginsDir, "subdir"), 0755)
require.NoError(t, err)
plugin := Plugin{
Name: "ValidPlugin",
Capabilities: []string{"test"},
Category: "test",
Repo: "https://github.com/test/test",
Author: "Test",
Description: "Test",
Compositors: []string{"niri"},
Distro: []string{"any"},
}
createTestPlugin(t, fs, tmpDir, "valid.json", plugin)
err = registry.loadPlugins()
assert.NoError(t, err)
assert.Len(t, registry.plugins, 1)
})
t.Run("skips invalid json files", func(t *testing.T) {
registry, fs, tmpDir := setupTestRegistry(t)
pluginsDir := filepath.Join(tmpDir, "plugins")
err := fs.MkdirAll(pluginsDir, 0755)
require.NoError(t, err)
err = afero.WriteFile(fs, filepath.Join(pluginsDir, "invalid.json"), []byte("{invalid json}"), 0644)
require.NoError(t, err)
plugin := Plugin{
Name: "ValidPlugin",
Capabilities: []string{"test"},
Category: "test",
Repo: "https://github.com/test/test",
Author: "Test",
Description: "Test",
Compositors: []string{"niri"},
Distro: []string{"any"},
}
createTestPlugin(t, fs, tmpDir, "valid.json", plugin)
err = registry.loadPlugins()
assert.NoError(t, err)
assert.Len(t, registry.plugins, 1)
assert.Equal(t, "ValidPlugin", registry.plugins[0].Name)
})
t.Run("returns error when plugins directory missing", func(t *testing.T) {
registry, _, _ := setupTestRegistry(t)
err := registry.loadPlugins()
assert.Error(t, err)
assert.Contains(t, err.Error(), "failed to read plugins directory")
})
}
func TestList(t *testing.T) {
t.Run("returns cached plugins if available", func(t *testing.T) {
registry, _, _ := setupTestRegistry(t)
plugin := Plugin{
Name: "CachedPlugin",
Capabilities: []string{"test"},
Category: "test",
Repo: "https://github.com/test/test",
Author: "Test",
Description: "Test",
Compositors: []string{"niri"},
Distro: []string{"any"},
}
registry.plugins = []Plugin{plugin}
plugins, err := registry.List()
assert.NoError(t, err)
assert.Len(t, plugins, 1)
assert.Equal(t, "CachedPlugin", plugins[0].Name)
})
t.Run("updates and loads plugins when cache is empty", func(t *testing.T) {
registry, fs, _ := setupTestRegistry(t)
plugin := Plugin{
Name: "NewPlugin",
Capabilities: []string{"test"},
Category: "test",
Repo: "https://github.com/test/test",
Author: "Test",
Description: "Test",
Compositors: []string{"niri"},
Distro: []string{"any"},
}
mockGit := &mockGitClient{
cloneFunc: func(path string, url string) error {
createTestPlugin(t, fs, path, "plugin.json", plugin)
return nil
},
}
registry.git = mockGit
plugins, err := registry.List()
assert.NoError(t, err)
assert.Len(t, plugins, 1)
assert.Equal(t, "NewPlugin", plugins[0].Name)
})
}
func TestUpdate(t *testing.T) {
t.Run("clones repository when cache doesn't exist", func(t *testing.T) {
registry, fs, tmpDir := setupTestRegistry(t)
plugin := Plugin{
Name: "RepoPlugin",
Capabilities: []string{"test"},
Category: "test",
Repo: "https://github.com/test/test",
Author: "Test",
Description: "Test",
Compositors: []string{"niri"},
Distro: []string{"any"},
}
cloneCalled := false
mockGit := &mockGitClient{
cloneFunc: func(path string, url string) error {
cloneCalled = true
assert.Equal(t, registryRepo, url)
assert.Equal(t, tmpDir, path)
createTestPlugin(t, fs, path, "plugin.json", plugin)
return nil
},
}
registry.git = mockGit
err := registry.Update()
assert.NoError(t, err)
assert.True(t, cloneCalled)
assert.Len(t, registry.plugins, 1)
assert.Equal(t, "RepoPlugin", registry.plugins[0].Name)
})
t.Run("pulls updates when cache exists", func(t *testing.T) {
registry, fs, tmpDir := setupTestRegistry(t)
plugin := Plugin{
Name: "UpdatedPlugin",
Capabilities: []string{"test"},
Category: "test",
Repo: "https://github.com/test/test",
Author: "Test",
Description: "Test",
Compositors: []string{"niri"},
Distro: []string{"any"},
}
err := fs.MkdirAll(tmpDir, 0755)
require.NoError(t, err)
pullCalled := false
mockGit := &mockGitClient{
pullFunc: func(path string) error {
pullCalled = true
assert.Equal(t, tmpDir, path)
createTestPlugin(t, fs, path, "plugin.json", plugin)
return nil
},
}
registry.git = mockGit
err = registry.Update()
assert.NoError(t, err)
assert.True(t, pullCalled)
assert.Len(t, registry.plugins, 1)
assert.Equal(t, "UpdatedPlugin", registry.plugins[0].Name)
})
}