Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

205 lines
6.7 KiB
Go

package core
import (
"strings"
"testing"
)
func TestValidateManifestRejectsReservedHandlerPath(t *testing.T) {
err := ValidateManifest(Manifest{
SchemaVersion: ManifestSchemaVersion,
Scope: "automation",
Commands: []ManifestCommand{{
Path: []string{"run"},
Summary: "Run automation",
Output: ManifestCommandOutput{DefaultMode: OutputModeJSON, JSON: true},
Handler: ManifestCommandHandler{Kind: "http", Method: "POST", Path: "/run"},
}},
})
if err == nil {
t.Fatal("ValidateManifest() error = nil, want handler path error")
}
}
func TestValidateManifestRejectsUnknownVisibility(t *testing.T) {
err := ValidateManifest(Manifest{
SchemaVersion: ManifestSchemaVersion,
Scope: "automation",
Commands: []ManifestCommand{{
Path: []string{"run"},
Summary: "Run automation",
Visibility: "private",
Output: ManifestCommandOutput{DefaultMode: OutputModeJSON, JSON: true},
Handler: ManifestCommandHandler{Kind: "http", Method: "POST", Path: "/tutti/cli/run"},
}},
})
if err == nil {
t.Fatal("ValidateManifest() error = nil, want visibility error")
}
}
func TestValidateManifestAcceptsEnumAndDefaultInputAnnotations(t *testing.T) {
err := ValidateManifest(Manifest{
SchemaVersion: ManifestSchemaVersion,
Scope: "automation",
Commands: []ManifestCommand{{
Path: []string{"create"},
Summary: "Create automation",
InputSchema: map[string]any{
"type": "object",
"properties": map[string]any{
"schedule-type": map[string]any{
"type": "string",
"description": "Schedule type.",
"enum": []any{"manual", "interval", "daily", "weekly", "cron"},
"default": "manual",
},
"enabled": map[string]any{
"type": "boolean",
"default": true,
},
"interval-minutes": map[string]any{
"type": "integer",
"default": 60,
},
},
},
Output: ManifestCommandOutput{DefaultMode: OutputModeJSON, JSON: true},
Handler: ManifestCommandHandler{Kind: "http", Method: "POST", Path: "/tutti/cli/create"},
}},
})
if err != nil {
t.Fatalf("ValidateManifest() error = %v", err)
}
}
func TestValidateManifestRejectsEnumValuesWithWrongType(t *testing.T) {
err := ValidateManifest(Manifest{
SchemaVersion: ManifestSchemaVersion,
Scope: "automation",
Commands: []ManifestCommand{{
Path: []string{"create"},
Summary: "Create automation",
InputSchema: map[string]any{
"type": "object",
"properties": map[string]any{
"schedule-type": map[string]any{
"type": "string",
"enum": []any{"manual", 1},
},
},
},
Output: ManifestCommandOutput{DefaultMode: OutputModeJSON, JSON: true},
Handler: ManifestCommandHandler{Kind: "http", Method: "POST", Path: "/tutti/cli/create"},
}},
})
if err == nil {
t.Fatal("ValidateManifest() error = nil, want enum type error")
}
}
func TestBuildCommandsBuildsAppCapability(t *testing.T) {
manifest := Manifest{
SchemaVersion: ManifestSchemaVersion,
Scope: "automation",
Description: "Automation commands",
Commands: []ManifestCommand{{
Path: []string{"run"},
Summary: "Run automation",
Description: "Runs a job",
Visibility: CommandVisibilityIntegration,
InputSchema: map[string]any{"type": "object", "properties": map[string]any{"name": map[string]any{"type": "string"}}},
Output: ManifestCommandOutput{DefaultMode: OutputModeJSON, JSON: true},
Handler: ManifestCommandHandler{Kind: "http", Method: "POST", Path: "/tutti/cli/run"},
}},
}
commands := BuildCommands(manifest, CommandBuildOptions{
AppID: "automation-app",
AppName: "Automation",
IconURL: "data:image/png;base64,abc",
AppDescription: "Test app",
DocumentationFile: "COMMANDS.md",
DocumentationPath: "/tmp/COMMANDS.md",
})
if len(commands) != 1 {
t.Fatalf("commands = %#v", commands)
}
capability := commands[0].Capability
if capability.ID != "app.automation-app.automation.run" || capability.Path[0] != "automation" {
t.Fatalf("capability = %#v", capability)
}
if capability.Source.AppID != "automation-app" || capability.Source.CLIDescription != "Automation commands" {
t.Fatalf("capability source = %#v", capability.Source)
}
if capability.Visibility != CommandVisibilityIntegration {
t.Fatalf("capability visibility = %q", capability.Visibility)
}
}
func TestBuildCommandsDefaultsVisibilityToPublic(t *testing.T) {
commands := BuildCommands(Manifest{
SchemaVersion: ManifestSchemaVersion,
Scope: "automation",
Commands: []ManifestCommand{{
Path: []string{"run"},
Summary: "Run automation",
Output: ManifestCommandOutput{DefaultMode: OutputModeJSON, JSON: true},
Handler: ManifestCommandHandler{Kind: "http", Method: "POST", Path: "/tutti/cli/run"},
}},
}, CommandBuildOptions{AppID: "automation-app"})
if len(commands) != 1 || commands[0].Capability.Visibility != CommandVisibilityPublic {
t.Fatalf("commands = %#v", commands)
}
}
func TestValidateManifestAcceptsWaitExecutionAndBuildsCapabilityMetadata(t *testing.T) {
manifest := Manifest{
SchemaVersion: ManifestSchemaVersion,
Scope: "automation",
Commands: []ManifestCommand{{
Path: []string{"runs", "wait"},
Summary: "Wait for a run",
Execution: &ManifestCommandExecution{Mode: CommandExecutionModeWait},
Output: ManifestCommandOutput{DefaultMode: OutputModeJSON, JSON: true},
Handler: ManifestCommandHandler{
Kind: "http", Method: "POST", Path: "/tutti/cli/runs/wait", TimeoutMs: 45000,
},
}},
}
if err := ValidateManifest(manifest); err != nil {
t.Fatalf("ValidateManifest() error = %v", err)
}
commands := BuildCommands(manifest, CommandBuildOptions{AppID: "automation-app"})
if len(commands) != 1 || commands[0].Capability.Execution == nil ||
commands[0].Capability.Execution.Mode != CommandExecutionModeWait ||
commands[0].Capability.HandlerTimeoutMs != 45000 {
t.Fatalf("commands = %#v", commands)
}
}
func TestValidateManifestRejectsWaitExecutionTimeoutInput(t *testing.T) {
err := ValidateManifest(Manifest{
SchemaVersion: ManifestSchemaVersion,
Scope: "automation",
Commands: []ManifestCommand{{
Path: []string{"runs", "wait"},
Summary: "Wait for a run",
Execution: &ManifestCommandExecution{Mode: CommandExecutionModeWait},
InputSchema: map[string]any{
"type": "object",
"properties": map[string]any{
"timeout-ms": map[string]any{"type": "integer"},
},
},
Output: ManifestCommandOutput{DefaultMode: OutputModeJSON, JSON: true},
Handler: ManifestCommandHandler{Kind: "http", Method: "POST", Path: "/tutti/cli/runs/wait"},
}},
})
if err == nil || !strings.Contains(err.Error(), "reserves --timeout-ms") {
t.Fatalf("ValidateManifest() error = %v", err)
}
}