145 lines
4.0 KiB
Go
145 lines
4.0 KiB
Go
package agent
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestInjectDispatchFlags(t *testing.T) {
|
|
schema := json.RawMessage(`{"type":"object","required":["cmd"],"properties":{"cmd":{"type":"string"}}}`)
|
|
|
|
result := injectDispatchFlags(schema)
|
|
|
|
var obj map[string]json.RawMessage
|
|
if err := json.Unmarshal(result, &obj); err != nil {
|
|
t.Fatalf("unmarshal result: %v", err)
|
|
}
|
|
|
|
var props map[string]json.RawMessage
|
|
if err := json.Unmarshal(obj["properties"], &props); err != nil {
|
|
t.Fatalf("unmarshal properties: %v", err)
|
|
}
|
|
|
|
// Original property preserved
|
|
if _, ok := props["cmd"]; !ok {
|
|
t.Error("original property 'cmd' missing")
|
|
}
|
|
|
|
// Dispatch flags injected
|
|
for _, flag := range []string{"bypass", "timeout", "sandbox", "background"} {
|
|
if _, ok := props[flag]; !ok {
|
|
t.Errorf("dispatch flag %q not injected", flag)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestInjectDispatchFlags_NoOverwrite(t *testing.T) {
|
|
// If a tool already declares "timeout", don't overwrite it
|
|
schema := json.RawMessage(`{"type":"object","properties":{"timeout":{"type":"string","description":"custom"}}}`)
|
|
|
|
result := injectDispatchFlags(schema)
|
|
|
|
var obj map[string]json.RawMessage
|
|
json.Unmarshal(result, &obj)
|
|
var props map[string]json.RawMessage
|
|
json.Unmarshal(obj["properties"], &props)
|
|
|
|
// timeout should keep original definition
|
|
var timeoutDef map[string]string
|
|
json.Unmarshal(props["timeout"], &timeoutDef)
|
|
if timeoutDef["description"] != "custom" {
|
|
t.Errorf("timeout was overwritten: got %q", timeoutDef["description"])
|
|
}
|
|
|
|
// Other flags should still be injected
|
|
if _, ok := props["bypass"]; !ok {
|
|
t.Error("bypass not injected")
|
|
}
|
|
}
|
|
|
|
func TestInjectDispatchFlags_EmptySchema(t *testing.T) {
|
|
// Empty or malformed schemas pass through unchanged
|
|
if got := injectDispatchFlags(nil); got != nil {
|
|
t.Errorf("nil schema: got %s", got)
|
|
}
|
|
if got := injectDispatchFlags(json.RawMessage(`{}`)); string(got) != `{}` {
|
|
t.Errorf("no properties: got %s", got)
|
|
}
|
|
}
|
|
|
|
func TestIsBackground(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
args string
|
|
want bool
|
|
}{
|
|
{"true bool", `{"cmd":"ls","background":true}`, true},
|
|
{"false bool", `{"cmd":"ls","background":false}`, false},
|
|
{"string true", `{"cmd":"ls","background":"true"}`, true},
|
|
{"string 1", `{"cmd":"ls","background":"1"}`, true},
|
|
{"absent", `{"cmd":"ls"}`, false},
|
|
{"empty", `{}`, false},
|
|
{"malformed", `not json`, false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := isBackground(json.RawMessage(tt.args))
|
|
if got != tt.want {
|
|
t.Errorf("isBackground(%s) = %v, want %v", tt.args, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStripBackgroundFlag(t *testing.T) {
|
|
args := json.RawMessage(`{"cmd":"make test","background":true,"timeout":60}`)
|
|
got := stripBackgroundFlag(args)
|
|
|
|
var m map[string]json.RawMessage
|
|
if err := json.Unmarshal(got, &m); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
|
|
if _, ok := m["background"]; ok {
|
|
t.Error("background flag not stripped")
|
|
}
|
|
if _, ok := m["cmd"]; !ok {
|
|
t.Error("cmd was removed")
|
|
}
|
|
if _, ok := m["timeout"]; !ok {
|
|
t.Error("timeout was removed")
|
|
}
|
|
}
|
|
|
|
func TestExtractCmdDesc(t *testing.T) {
|
|
// Normal cmd
|
|
got := extractCmdDesc("shell", json.RawMessage(`{"cmd":"go test ./..."}`))
|
|
if got != "go test ./..." {
|
|
t.Errorf("got %q, want %q", got, "go test ./...")
|
|
}
|
|
|
|
// Long cmd gets truncated to 80 chars + "..."
|
|
longCmd := `{"cmd":"echo ` + strings.Repeat("a", 200) + `"}`
|
|
got = extractCmdDesc("shell", json.RawMessage(longCmd))
|
|
if len(got) != 83 { // 80 + "..."
|
|
t.Errorf("long cmd: got len %d, want 83", len(got))
|
|
}
|
|
if !strings.HasSuffix(got, "...") {
|
|
t.Errorf("long cmd should end with ..., got %q", got[len(got)-10:])
|
|
}
|
|
|
|
// No cmd field returns tool name
|
|
got = extractCmdDesc("file_edit", json.RawMessage(`{"path":"/a"}`))
|
|
if got != "file_edit" {
|
|
t.Errorf("got %q, want %q", got, "file_edit")
|
|
}
|
|
|
|
// Malformed JSON returns tool name
|
|
got = extractCmdDesc("shell", json.RawMessage(`bad`))
|
|
if got != "shell" {
|
|
t.Errorf("got %q, want %q", got, "shell")
|
|
}
|
|
}
|