mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
dea06c391c
* Improve the web launcher and gateway integration across backend and frontend. - add runtime model availability checks for local and OAuth-backed models - support launcher-driven gateway host overrides and websocket URL resolution - add gateway log clearing and keep incremental log sync consistent after resets - migrate session history APIs to JSONL metadata-backed storage with legacy fallback - expose session titles and improve chat history loading and error handling - move shared backend runtime helpers into the web utils package - avoid blocking web startup when automatic onboard initialization fails - add backend tests covering gateway readiness, host resolution, models, logs, and sessions * feat(agent): add skills and tools management APIs and UI - add backend APIs to list, view, import, and delete skills - add tool status and toggle endpoints with dependency-aware config updates - add agent skills/tools pages, routes, sidebar entries, and i18n strings - add backend tests for the new skills and tools flows * chore(frontend): upgrade shadcn to 4.0.5 and refresh lockfile * chore(web): keep backend dist placeholder tracked
102 lines
2.7 KiB
Go
102 lines
2.7 KiB
Go
package utils
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestEnsureOnboardedSkipsWhenConfigExists(t *testing.T) {
|
|
configPath := filepath.Join(t.TempDir(), "config.json")
|
|
if err := os.WriteFile(configPath, []byte(`{}`), 0o644); err != nil {
|
|
t.Fatalf("WriteFile() error = %v", err)
|
|
}
|
|
|
|
origExecCommand := execCommand
|
|
defer func() { execCommand = origExecCommand }()
|
|
|
|
called := false
|
|
execCommand = func(name string, args ...string) *exec.Cmd {
|
|
called = true
|
|
return exec.Command("sh", "-c", "exit 1")
|
|
}
|
|
|
|
if err := EnsureOnboarded(configPath); err != nil {
|
|
t.Fatalf("EnsureOnboarded() error = %v", err)
|
|
}
|
|
if called {
|
|
t.Fatal("expected onboard command not to run when config already exists")
|
|
}
|
|
}
|
|
|
|
func TestEnsureOnboardedRunsOnboardWhenConfigMissing(t *testing.T) {
|
|
configPath := filepath.Join(t.TempDir(), "config.json")
|
|
t.Setenv("EXPECTED_CONFIG_PATH", configPath)
|
|
|
|
origExecCommand := execCommand
|
|
defer func() { execCommand = origExecCommand }()
|
|
|
|
var gotName string
|
|
var gotArgs []string
|
|
execCommand = func(name string, args ...string) *exec.Cmd {
|
|
gotName = name
|
|
gotArgs = append([]string(nil), args...)
|
|
return exec.Command(
|
|
"sh",
|
|
"-c",
|
|
`test "$PICOCLAW_CONFIG" = "$EXPECTED_CONFIG_PATH" &&
|
|
mkdir -p "$(dirname "$PICOCLAW_CONFIG")" &&
|
|
printf '{}' > "$PICOCLAW_CONFIG"`,
|
|
)
|
|
}
|
|
|
|
if err := EnsureOnboarded(configPath); err != nil {
|
|
t.Fatalf("EnsureOnboarded() error = %v", err)
|
|
}
|
|
if gotName == "" {
|
|
t.Fatal("expected onboard command to run")
|
|
}
|
|
if len(gotArgs) != 1 || gotArgs[0] != "onboard" {
|
|
t.Fatalf("command args = %#v, want []string{\"onboard\"}", gotArgs)
|
|
}
|
|
if _, err := os.Stat(configPath); err != nil {
|
|
t.Fatalf("expected config to be created: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestEnsureOnboardedFailsWhenOnboardDoesNotCreateConfig(t *testing.T) {
|
|
configPath := filepath.Join(t.TempDir(), "config.json")
|
|
|
|
origExecCommand := execCommand
|
|
defer func() { execCommand = origExecCommand }()
|
|
|
|
execCommand = func(name string, args ...string) *exec.Cmd {
|
|
return exec.Command("sh", "-c", "exit 0")
|
|
}
|
|
|
|
if err := EnsureOnboarded(configPath); err == nil {
|
|
t.Fatal("EnsureOnboarded() error = nil, want failure when onboard does not create config")
|
|
}
|
|
}
|
|
|
|
func TestEnsureOnboardedIncludesOnboardOutputOnFailure(t *testing.T) {
|
|
configPath := filepath.Join(t.TempDir(), "config.json")
|
|
|
|
origExecCommand := execCommand
|
|
defer func() { execCommand = origExecCommand }()
|
|
|
|
execCommand = func(name string, args ...string) *exec.Cmd {
|
|
return exec.Command("sh", "-c", "echo onboarding failed >&2; exit 2")
|
|
}
|
|
|
|
err := EnsureOnboarded(configPath)
|
|
if err == nil {
|
|
t.Fatal("EnsureOnboarded() error = nil, want failure")
|
|
}
|
|
if !strings.Contains(err.Error(), "onboarding failed") {
|
|
t.Fatalf("error = %q, want onboard output included", err)
|
|
}
|
|
}
|