Files
picoclaw/web/backend/utils/onboard_test.go
T
wenjie dea06c391c feat(web): add agent management UI and improve launcher integration (#1358)
* 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
2026-03-11 18:37:00 +08:00

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)
}
}