Feat v0.2.9 builtin retirement (#13)
Some checks failed
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-frontend (push) Successful in 6s
CI/CD / test-go-pg (push) Failing after 2m15s
CI/CD / test-sqlite (push) Successful in 2m36s
CI/CD / build-and-deploy (push) Has been skipped

Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #13.
This commit is contained in:
2026-03-27 16:46:50 +00:00
committed by xcaliber
parent babfe66721
commit 8580e1d93e
21 changed files with 42 additions and 439 deletions

View File

@@ -5,9 +5,7 @@ import (
"database/sql"
"encoding/json"
"net/http"
"os"
"path/filepath"
"testing"
"testing"
"github.com/gin-gonic/gin"
@@ -806,219 +804,3 @@ func TestExtension_StoreDeleteUserSettings(t *testing.T) {
}
}
// ═══════════════════════════════════════════════
// Seed Logic (F26/F27)
// ═══════════════════════════════════════════════
// makeSeedDir creates a temp directory with extension subdirectories.
// Each entry in exts maps a dir name to {manifest, script}.
func makeSeedDir(t *testing.T, exts map[string]struct{ manifest, script string }) string {
t.Helper()
dir := t.TempDir()
for name, files := range exts {
extDir := filepath.Join(dir, name)
if err := os.MkdirAll(extDir, 0755); err != nil {
t.Fatalf("mkdir %s: %v", extDir, err)
}
if files.manifest != "" {
if err := os.WriteFile(filepath.Join(extDir, "manifest.json"), []byte(files.manifest), 0644); err != nil {
t.Fatalf("write manifest: %v", err)
}
}
if files.script != "" {
if err := os.WriteFile(filepath.Join(extDir, "script.js"), []byte(files.script), 0644); err != nil {
t.Fatalf("write script: %v", err)
}
}
}
return dir
}
func TestSeed_NewExtension(t *testing.T) {
h := setupExtensionHarness(t)
ctx := context.Background()
dir := makeSeedDir(t, map[string]struct{ manifest, script string }{
"test-seeded": {
manifest: `{"id":"test-seeded","name":"Seeded Extension","version":"1.0.0","tier":"browser","author":"test"}`,
script: `console.log("seeded");`,
},
})
SeedBuiltinPackages(h.stores, dir)
// Should be created as system extension
pkg, err := h.stores.Packages.Get(ctx, "test-seeded")
if err != nil {
t.Fatalf("seeded extension not found: %v", err)
}
if pkg.Title != "Seeded Extension" {
t.Fatalf("name: got %q", pkg.Title)
}
if pkg.Version != "1.0.0" {
t.Fatalf("version: got %q", pkg.Version)
}
if !pkg.IsSystem {
t.Fatal("should be system extension")
}
if !pkg.Enabled {
t.Fatal("should be enabled")
}
// Verify _script is inlined in manifest
if _, ok := pkg.Manifest["_script"]; !ok {
t.Fatal("manifest should contain _script")
}
}
func TestSeed_SameVersionSkips(t *testing.T) {
h := setupExtensionHarness(t)
ctx := context.Background()
dir := makeSeedDir(t, map[string]struct{ manifest, script string }{
"skip-ext": {
manifest: `{"id":"skip-ext","name":"Skip Test","version":"1.0.0"}`,
script: `console.log("v1");`,
},
})
// Seed twice
SeedBuiltinPackages(h.stores, dir)
SeedBuiltinPackages(h.stores, dir)
// Should still have exactly one
pkgs, err := h.stores.Packages.List(ctx)
if err != nil {
t.Fatalf("list: %v", err)
}
count := 0
for _, p := range pkgs {
if p.ID == "skip-ext" {
count++
}
}
if count != 1 {
t.Fatalf("expected 1 skip-ext, got %d", count)
}
}
func TestSeed_VersionChangeUpdates(t *testing.T) {
h := setupExtensionHarness(t)
ctx := context.Background()
// Seed v1
dir1 := makeSeedDir(t, map[string]struct{ manifest, script string }{
"versioned-ext": {
manifest: `{"id":"versioned-ext","name":"V1 Name","version":"1.0.0","author":"original"}`,
script: `console.log("v1");`,
},
})
SeedBuiltinPackages(h.stores, dir1)
pkg, _ := h.stores.Packages.Get(ctx, "versioned-ext")
if pkg.Version != "1.0.0" {
t.Fatalf("v1 version: got %q", pkg.Version)
}
// Seed v2 (different version triggers update)
dir2 := makeSeedDir(t, map[string]struct{ manifest, script string }{
"versioned-ext": {
manifest: `{"id":"versioned-ext","name":"V2 Name","version":"2.0.0","author":"updated"}`,
script: `console.log("v2");`,
},
})
SeedBuiltinPackages(h.stores, dir2)
pkg, _ = h.stores.Packages.Get(ctx, "versioned-ext")
if pkg.Version != "2.0.0" {
t.Fatalf("v2 version: got %q", pkg.Version)
}
if pkg.Title != "V2 Name" {
t.Fatalf("v2 name: got %q", pkg.Title)
}
}
func TestSeed_MissingManifestSkips(t *testing.T) {
h := setupExtensionHarness(t)
ctx := context.Background()
// Directory with no manifest.json
dir := makeSeedDir(t, map[string]struct{ manifest, script string }{
"no-manifest": {script: `console.log("orphan");`},
})
SeedBuiltinPackages(h.stores, dir)
pkgs, err := h.stores.Packages.List(ctx)
if err != nil {
t.Fatalf("list: %v", err)
}
if len(pkgs) != 0 {
t.Fatalf("should skip dir without manifest, got %d extensions", len(pkgs))
}
}
func TestSeed_InvalidManifestSkips(t *testing.T) {
h := setupExtensionHarness(t)
ctx := context.Background()
dir := makeSeedDir(t, map[string]struct{ manifest, script string }{
"bad-manifest": {manifest: `{not valid json`, script: `console.log("bad");`},
})
SeedBuiltinPackages(h.stores, dir)
pkgs, _ := h.stores.Packages.List(ctx)
if len(pkgs) != 0 {
t.Fatalf("should skip invalid manifest, got %d extensions", len(pkgs))
}
}
func TestSeed_MissingIDSkips(t *testing.T) {
h := setupExtensionHarness(t)
ctx := context.Background()
// Valid JSON but no "id" field
dir := makeSeedDir(t, map[string]struct{ manifest, script string }{
"no-id": {manifest: `{"name":"No ID Extension","version":"1.0.0"}`, script: `console.log("no id");`},
})
SeedBuiltinPackages(h.stores, dir)
pkgs, _ := h.stores.Packages.List(ctx)
if len(pkgs) != 0 {
t.Fatalf("should skip manifest without id, got %d extensions", len(pkgs))
}
}
func TestSeed_NonexistentDirectorySkips(t *testing.T) {
h := setupExtensionHarness(t)
// Should not panic on missing directory
SeedBuiltinPackages(h.stores, "/nonexistent/path/extensions")
pkgs, _ := h.stores.Packages.List(context.Background())
if len(pkgs) != 0 {
t.Fatalf("should seed nothing from missing dir, got %d", len(pkgs))
}
}
func TestSeed_ScriptOptional(t *testing.T) {
h := setupExtensionHarness(t)
ctx := context.Background()
// Manifest-only extension (no script.js)
dir := makeSeedDir(t, map[string]struct{ manifest, script string }{
"manifest-only": {manifest: `{"id":"manifest-only","name":"Manifest Only","version":"1.0.0"}`},
})
SeedBuiltinPackages(h.stores, dir)
pkg, err := h.stores.Packages.Get(ctx, "manifest-only")
if err != nil {
t.Fatalf("should create manifest-only ext: %v", err)
}
// Manifest should NOT contain _script
if _, ok := pkg.Manifest["_script"]; ok {
t.Fatal("manifest should not contain _script when no script.js exists")
}
}