Files
magpie/internal/gui/backup_test.go
T

92 lines
2.9 KiB
Go

package gui
import (
"encoding/base64"
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"github.com/yetone/magpie/internal/library"
)
// folderOnly is the app's windows as far as an export needs them.
type folderOnly struct{ Windows }
func (folderOnly) OpenFolder(string) error { return nil }
// sandboxHome gives the test a machine of its own: no agents, no magpie files.
func sandboxHome(t *testing.T) string {
t.Helper()
h := t.TempDir()
t.Setenv("HOME", h)
t.Setenv("USERPROFILE", h)
t.Setenv("XDG_CONFIG_HOME", filepath.Join(h, ".config"))
t.Setenv("XDG_CACHE_HOME", filepath.Join(h, ".cache"))
t.Setenv("PATH", "")
for _, v := range []string{"CLAUDE_CONFIG_DIR", "CODEX_HOME", "DSH_HOME", "PI_CODING_AGENT_DIR", "OMO_CODING_AGENT_DIR", "SENPI_CODING_AGENT_DIR", "COPILOT_HOME",
"CLINE_DIR", "GROK_HOME", "HERMES_HOME", "HANA_HOME", "APPDATA", "LOCALAPPDATA"} {
t.Setenv(v, "")
}
return h
}
// The Settings page's Export and Import carry the library, and leave it
// when its box is unticked.
func TestBackupLibraryRoundTrip(t *testing.T) {
h := sandboxHome(t)
text := "Be brief."
if _, err := library.SaveInstructions(library.InstructionsChange{Shared: &text}); err != nil {
t.Fatal(err)
}
mux := http.NewServeMux()
backupRoutes(mux, folderOnly{})
post := func(path string, body any) map[string]any {
t.Helper()
b, _ := json.Marshal(body)
w := httptest.NewRecorder()
mux.ServeHTTP(w, httptest.NewRequest("POST", path, strings.NewReader(string(b))))
if w.Code != 200 {
t.Fatalf("%s: %d %s", path, w.Code, w.Body)
}
var out map[string]any
json.Unmarshal(w.Body.Bytes(), &out)
return out
}
export := func(lib bool) []byte {
t.Helper()
out := post("/api/backup/export", map[string]any{"pass": "pw", "keys": true, "library": lib})
if out["library"] != lib {
t.Fatalf("export: %v", out)
}
p, _ := out["path"].(string)
data, err := os.ReadFile(filepath.Join(h, strings.TrimPrefix(p, "~")))
if err != nil {
t.Fatal(err)
}
return data
}
with, without := export(true), export(false)
sandboxHome(t) // another machine
enc := base64.StdEncoding.EncodeToString
if out := post("/api/backup/import", map[string]any{"data": enc(without), "pass": "pw", "agents": true, "library": true}); out["Library"] != false {
t.Fatalf("a file without it: %v", out)
}
if out := post("/api/backup/import", map[string]any{"data": enc(with), "pass": "pw", "agents": true, "library": false}); out["Library"] != false {
t.Fatalf("unticked: %v", out)
}
if iv, _ := library.ReadInstructions(); iv.Shared != "" {
t.Fatalf("the library came in unticked: %q", iv.Shared)
}
if out := post("/api/backup/import", map[string]any{"data": enc(with), "pass": "pw", "agents": true, "library": true}); out["Library"] != true {
t.Fatalf("import: %v", out)
}
if iv, _ := library.ReadInstructions(); iv.Shared != "Be brief." {
t.Fatalf("instructions: %q", iv.Shared)
}
}