This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/server/handlers/packages_bundled_test.go
Jeffrey Smith f4e66afc80
All checks were successful
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Successful in 6s
CI/CD / test-sqlite (pull_request) Successful in 2m46s
CI/CD / test-go-pg (pull_request) Successful in 2m47s
CI/CD / build-and-deploy (pull_request) Successful in 1m21s
Fix CI: test manifests need tools/pipes/hooks for extension type
ValidateManifest() now enforces type-specific constraints on bundled
install too. Two tests used type "extension" without any tools/pipes/hooks,
which is correctly rejected. Added hooks field to make them valid.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:36:14 +00:00

228 lines
6.3 KiB
Go

package handlers
import (
"archive/zip"
"context"
"encoding/json"
"os"
"path/filepath"
"testing"
"switchboard-core/database"
"switchboard-core/store"
postgres "switchboard-core/store/postgres"
sqlite "switchboard-core/store/sqlite"
)
// ── Test helpers ──────────────────────────────
func newTestStores(t *testing.T) store.Stores {
t.Helper()
database.RequireTestDB(t)
database.TruncateAll(t)
if database.IsSQLite() {
return sqlite.NewStores(database.TestDB)
}
return postgres.NewStores(database.TestDB)
}
// buildTestPkg creates a minimal .pkg archive in dir with the given manifest.
func buildTestPkg(t *testing.T, dir string, manifest map[string]any) string {
t.Helper()
pkgID, _ := manifest["id"].(string)
if pkgID == "" {
t.Fatal("manifest must have 'id'")
}
data, err := json.Marshal(manifest)
if err != nil {
t.Fatal(err)
}
pkgPath := filepath.Join(dir, pkgID+".pkg")
f, err := os.Create(pkgPath)
if err != nil {
t.Fatal(err)
}
defer f.Close()
zw := zip.NewWriter(f)
w, err := zw.Create("manifest.json")
if err != nil {
t.Fatal(err)
}
if _, err := w.Write(data); err != nil {
t.Fatal(err)
}
if err := zw.Close(); err != nil {
t.Fatal(err)
}
return pkgPath
}
// ═══════════════════════════════════════════════
// Tests
// ═══════════════════════════════════════════════
// TestBundledInstall_FreshDB verifies that bundled packages are installed
// into an empty database on first run.
func TestBundledInstall_FreshDB(t *testing.T) {
stores := newTestStores(t)
ctx := context.Background()
bundledDir := t.TempDir()
packagesDir := t.TempDir()
buildTestPkg(t, bundledDir, map[string]any{
"id": "test-surface-a",
"title": "Test Surface A",
"type": "surface",
})
buildTestPkg(t, bundledDir, map[string]any{
"id": "test-surface-b",
"title": "Test Surface B",
"type": "surface",
"route": "/s/test-b",
})
InstallBundledPackages(bundledDir, packagesDir, "*", stores, nil)
// Both packages should be installed and enabled
for _, id := range []string{"test-surface-a", "test-surface-b"} {
pkg, err := stores.Packages.Get(ctx, id)
if err != nil || pkg == nil {
t.Fatalf("package %s not found after install", id)
}
if !pkg.Enabled {
t.Errorf("package %s should be enabled", id)
}
if pkg.Source != "bundled" {
t.Errorf("package %s source = %q, want %q", id, pkg.Source, "bundled")
}
}
}
// TestBundledInstall_SkipsExisting verifies that already-installed packages
// are not re-installed (preserves admin uninstall/reconfigure).
func TestBundledInstall_SkipsExisting(t *testing.T) {
stores := newTestStores(t)
ctx := context.Background()
bundledDir := t.TempDir()
packagesDir := t.TempDir()
// Pre-seed a package with same ID but different title (simulating existing install)
manifest := map[string]any{"id": "pre-existing", "title": "Original Title", "type": "surface"}
if err := stores.Packages.Seed(ctx, "pre-existing", "Original Title", "extension", manifest); err != nil {
t.Fatal(err)
}
// Bundled package has same ID but different title
buildTestPkg(t, bundledDir, map[string]any{
"id": "pre-existing",
"title": "Bundled Title",
"type": "surface",
})
InstallBundledPackages(bundledDir, packagesDir, "*", stores, nil)
// Package should retain original title (not overwritten)
pkg, err := stores.Packages.Get(ctx, "pre-existing")
if err != nil || pkg == nil {
t.Fatal("pre-existing package not found")
}
if pkg.Title != "Original Title" {
t.Errorf("title = %q, want %q (should not overwrite existing)", pkg.Title, "Original Title")
}
}
// TestBundledInstall_MissingDir verifies graceful handling when bundled
// packages directory doesn't exist.
func TestBundledInstall_MissingDir(t *testing.T) {
stores := newTestStores(t)
// Should not panic or error — just log and return
InstallBundledPackages("/nonexistent/path", "", "", stores, nil)
}
// TestBundledInstall_EmptyDir verifies no-op when directory exists but is empty.
func TestBundledInstall_EmptyDir(t *testing.T) {
stores := newTestStores(t)
bundledDir := t.TempDir()
// Should not panic or error
InstallBundledPackages(bundledDir, "", "", stores, nil)
}
// TestBundledInstall_DormantPackage verifies that bundled packages with
// unmet requires are marked dormant.
func TestBundledInstall_DormantPackage(t *testing.T) {
stores := newTestStores(t)
ctx := context.Background()
bundledDir := t.TempDir()
packagesDir := t.TempDir()
buildTestPkg(t, bundledDir, map[string]any{
"id": "dormant-pkg",
"title": "Dormant Package",
"type": "extension",
"hooks": []string{"on_install"},
"requires": []string{"chat"},
})
InstallBundledPackages(bundledDir, packagesDir, "*", stores, nil)
pkg, err := stores.Packages.Get(ctx, "dormant-pkg")
if err != nil || pkg == nil {
t.Fatal("dormant package not found after install")
}
if pkg.Status != "dormant" {
t.Errorf("status = %q, want %q", pkg.Status, "dormant")
}
if pkg.Enabled {
t.Error("dormant package should not be enabled")
}
}
// TestBundledInstall_Allowlist verifies that BUNDLED_PACKAGES allowlist
// filters which packages are installed.
func TestBundledInstall_Allowlist(t *testing.T) {
stores := newTestStores(t)
ctx := context.Background()
bundledDir := t.TempDir()
packagesDir := t.TempDir()
buildTestPkg(t, bundledDir, map[string]any{
"id": "pkg-alpha", "title": "Alpha", "type": "surface",
})
buildTestPkg(t, bundledDir, map[string]any{
"id": "pkg-beta", "title": "Beta", "type": "surface",
})
buildTestPkg(t, bundledDir, map[string]any{
"id": "pkg-gamma", "title": "Gamma", "type": "surface",
})
// Only allow alpha and gamma
InstallBundledPackages(bundledDir, packagesDir, "pkg-alpha,pkg-gamma", stores, nil)
// Alpha and gamma should be installed
for _, id := range []string{"pkg-alpha", "pkg-gamma"} {
pkg, err := stores.Packages.Get(ctx, id)
if err != nil || pkg == nil {
t.Fatalf("package %s should have been installed (in allowlist)", id)
}
}
// Beta should NOT be installed
pkg, _ := stores.Packages.Get(ctx, "pkg-beta")
if pkg != nil {
t.Fatal("pkg-beta should NOT have been installed (not in allowlist)")
}
}