mirror of
https://github.com/spotiflacapp/SpotiFLAC-Mobile.git
synced 2026-06-01 03:15:17 +07:00
- Add 16 Go supplement test files covering extension runtime, providers, health checks, lyrics, metadata, HTTP utils, library scan, and more - Add Dart model/utils test suite (test/models_and_utils_test.dart) - Update settings.g.dart with deduplicateDownloads serialization
143 lines
5.6 KiB
Go
143 lines
5.6 KiB
Go
package gobackend
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestExtensionManagerPackageLifecycle(t *testing.T) {
|
|
dir := t.TempDir()
|
|
extensionsDir := filepath.Join(dir, "extensions")
|
|
dataDir := filepath.Join(dir, "data")
|
|
manager := &extensionManager{extensions: map[string]*loadedExtension{}}
|
|
if err := manager.SetDirectories(extensionsDir, dataDir); err != nil {
|
|
t.Fatalf("SetDirectories: %v", err)
|
|
}
|
|
if err := GetExtensionSettingsStore().SetDataDir(dataDir); err != nil {
|
|
t.Fatalf("settings data dir: %v", err)
|
|
}
|
|
|
|
js := `
|
|
var cleaned = false;
|
|
registerExtension({
|
|
initialize: function(settings) { this.settings = settings || {}; },
|
|
cleanup: function() { cleaned = true; },
|
|
doAction: function() { return { message: "done", setting_updates: { quality: "lossless" } }; },
|
|
getHomeFeed: function() { return [{ id: "home", title: "Home" }]; },
|
|
getBrowseCategories: function() { return [{ id: "cat", title: "Category" }]; },
|
|
searchTracks: function() { return { tracks: [], total: 0 }; },
|
|
fetchLyrics: function() { return { syncType: "UNSYNCED", lines: [{ words: "hello" }] }; },
|
|
getDownloadUrl: function() { return { url: "https://example.test/a.flac" }; }
|
|
});
|
|
`
|
|
pkgV1 := filepath.Join(dir, "manager-ext-v1.spotiflac-ext")
|
|
createTestExtensionPackage(t, pkgV1, "manager-ext", "1.0.0", js, map[string]string{"../unsafe.txt": "skip"})
|
|
pkgV2 := filepath.Join(dir, "manager-ext-v2.spotiflac-ext")
|
|
createTestExtensionPackage(t, pkgV2, "manager-ext", "1.1.0", js, nil)
|
|
|
|
if compareVersions("v1.2.0", "1.1.9") <= 0 || compareVersions("1.0.0", "1.0") != 0 || compareVersions("1.0.0", "1.0.1") >= 0 {
|
|
t.Fatal("compareVersions mismatch")
|
|
}
|
|
if _, err := manager.LoadExtensionFromFile(filepath.Join(dir, "bad.txt")); err == nil {
|
|
t.Fatal("expected bad extension suffix error")
|
|
}
|
|
if _, err := manager.LoadExtensionFromFile(filepath.Join(dir, "missing.spotiflac-ext")); err == nil {
|
|
t.Fatal("expected invalid package error")
|
|
}
|
|
|
|
ext, err := manager.LoadExtensionFromFile(pkgV1)
|
|
if err != nil {
|
|
t.Fatalf("LoadExtensionFromFile: %v", err)
|
|
}
|
|
if ext.ID != "manager-ext" || ext.Enabled || ext.SourceDir == "" {
|
|
t.Fatalf("loaded extension = %#v", ext)
|
|
}
|
|
if _, err := os.Stat(filepath.Join(ext.SourceDir, "unsafe.txt")); err == nil {
|
|
t.Fatal("unsafe archive path should not be extracted")
|
|
}
|
|
if _, err := manager.LoadExtensionFromFile(pkgV1); err == nil {
|
|
t.Fatal("expected duplicate version error")
|
|
}
|
|
|
|
installedJSON, err := manager.GetInstalledExtensionsJSON()
|
|
if err != nil || !strings.Contains(installedJSON, "manager-ext") || !strings.Contains(installedJSON, "icon_path") {
|
|
t.Fatalf("GetInstalledExtensionsJSON = %q/%v", installedJSON, err)
|
|
}
|
|
var installed []map[string]interface{}
|
|
if err := json.Unmarshal([]byte(installedJSON), &installed); err != nil || len(installed) != 1 {
|
|
t.Fatalf("decode installed = %#v/%v", installed, err)
|
|
}
|
|
|
|
if err := GetExtensionSettingsStore().Set("manager-ext", "quality", "lossless"); err != nil {
|
|
t.Fatalf("settings Set: %v", err)
|
|
}
|
|
if err := manager.SetExtensionEnabled("manager-ext", true); err != nil {
|
|
t.Fatalf("enable extension: %v", err)
|
|
}
|
|
if !ext.Enabled || ext.VM == nil || !ext.initialized {
|
|
t.Fatalf("enabled extension = %#v", ext)
|
|
}
|
|
if err := manager.InitializeExtension("manager-ext", map[string]interface{}{"quality": "hires"}); err != nil {
|
|
t.Fatalf("InitializeExtension: %v", err)
|
|
}
|
|
action, err := manager.InvokeAction("manager-ext", "doAction")
|
|
if err != nil || action["success"] != true || action["message"] != "done" {
|
|
t.Fatalf("InvokeAction = %#v/%v", action, err)
|
|
}
|
|
if err := manager.CleanupExtension("manager-ext"); err != nil {
|
|
t.Fatalf("CleanupExtension: %v", err)
|
|
}
|
|
if err := manager.SetExtensionEnabled("manager-ext", false); err != nil {
|
|
t.Fatalf("disable extension: %v", err)
|
|
}
|
|
if ext.VM != nil || ext.initialized {
|
|
t.Fatalf("expected VM teardown, got %#v", ext)
|
|
}
|
|
if _, err := manager.InvokeAction("manager-ext", "doAction"); err == nil {
|
|
t.Fatal("expected disabled action error")
|
|
}
|
|
|
|
upgradeJSON, err := manager.CheckExtensionUpgradeJSON(pkgV2)
|
|
if err != nil || !strings.Contains(upgradeJSON, `"can_upgrade":true`) {
|
|
t.Fatalf("CheckExtensionUpgradeJSON = %q/%v", upgradeJSON, err)
|
|
}
|
|
upgraded, err := manager.UpgradeExtension(pkgV2)
|
|
if err != nil {
|
|
t.Fatalf("UpgradeExtension: %v", err)
|
|
}
|
|
if upgraded.Manifest.Version != "1.1.0" {
|
|
t.Fatalf("upgraded = %#v", upgraded.Manifest)
|
|
}
|
|
if _, err := manager.UpgradeExtension(pkgV1); err == nil {
|
|
t.Fatal("expected downgrade error")
|
|
}
|
|
if err := manager.RemoveExtension("manager-ext"); err != nil {
|
|
t.Fatalf("RemoveExtension: %v", err)
|
|
}
|
|
if _, err := manager.GetExtension("manager-ext"); err == nil {
|
|
t.Fatal("expected removed extension missing")
|
|
}
|
|
|
|
dirExt := filepath.Join(extensionsDir, "dir-ext")
|
|
if err := os.MkdirAll(dirExt, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
manifest := `{"name":"dir-ext","displayName":"dir-ext","version":"1.0.0","description":"Directory extension","type":["metadata_provider"],"permissions":{}}`
|
|
if err := os.WriteFile(filepath.Join(dirExt, "manifest.json"), []byte(manifest), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(dirExt, "index.js"), []byte(`registerExtension({searchTracks:function(){return {tracks:[], total:0};}});`), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
loaded, loadErrs := manager.LoadExtensionsFromDirectory(extensionsDir)
|
|
if len(loadErrs) != 0 || len(loaded) != 1 || loaded[0] != "dir-ext" {
|
|
t.Fatalf("LoadExtensionsFromDirectory = %#v/%#v", loaded, loadErrs)
|
|
}
|
|
manager.UnloadAllExtensions()
|
|
if len(manager.GetAllExtensions()) != 0 {
|
|
t.Fatal("expected all extensions unloaded")
|
|
}
|
|
}
|