Files
tutti/services/tuttid/api/daemon_workspace_app_agent_test.go
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

252 lines
8.2 KiB
Go

package api
import (
"context"
"net/http"
"reflect"
"testing"
tuttigenerated "github.com/tutti-os/tutti/services/tuttid/api/generated"
agenttargetbiz "github.com/tutti-os/tutti/services/tuttid/biz/agenttarget"
workspacebiz "github.com/tutti-os/tutti/services/tuttid/biz/workspace"
agentservice "github.com/tutti-os/tutti/services/tuttid/service/agent"
agentstatusservice "github.com/tutti-os/tutti/services/tuttid/service/agentstatus"
)
func TestDaemonAPIRoutesWorkspaceAppAgentPreferencesRejectInvalidPath(t *testing.T) {
t.Parallel()
mux := http.NewServeMux()
RegisterRoutes(mux, NewRoutes(DaemonAPI{}))
recorder := performGeneratedRouteRequest(
t,
mux,
http.MethodGet,
"/v1/workspaces/%20/apps/canvas/preferences/agent",
nil,
)
if recorder.Code != http.StatusBadRequest {
t.Fatalf("status = %d, want %d; body: %s", recorder.Code, http.StatusBadRequest, recorder.Body.String())
}
}
func TestDaemonAPIRoutesWorkspaceAppAgentProviderStatusesDefaultToEnabledAgentTargets(t *testing.T) {
t.Parallel()
var capturedProviders []string
mux := http.NewServeMux()
RegisterRoutes(mux, NewRoutes(DaemonAPI{
AgentStatusService: stubAgentStatusService{
listFn: func(_ context.Context, input agentstatusservice.ListInput) (agentstatusservice.Snapshot, error) {
capturedProviders = append([]string(nil), input.Providers...)
return agentstatusservice.Snapshot{
Providers: []agentstatusservice.ProviderStatus{
{Provider: "codex"},
{Provider: "hermes"},
{Provider: "opencode"},
},
}, nil
},
},
AgentTargetService: stubAgentTargetService{
listFn: func(context.Context) ([]agenttargetbiz.Target, error) {
return []agenttargetbiz.Target{
{
ID: agenttargetbiz.IDLocalCodex,
Provider: "codex",
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("codex"),
Name: "Codex",
Enabled: true,
Source: agenttargetbiz.SourceSystem,
},
{
ID: "local:hermes",
Provider: "hermes",
LaunchRefJSON: `{"type":"local_cli","provider":"hermes"}`,
Name: "Hermes",
Enabled: true,
Source: agenttargetbiz.SourceSystem,
},
{
ID: agenttargetbiz.IDLocalCursor,
Provider: "cursor",
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("cursor"),
Name: "Cursor",
Enabled: false,
Source: agenttargetbiz.SourceSystem,
},
{
ID: agenttargetbiz.IDLocalOpenCode,
Provider: "opencode",
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("opencode"),
Name: "OpenCode",
Enabled: true,
Source: agenttargetbiz.SourceSystem,
},
}, nil
},
},
AppCenterService: installedWorkspaceAppCenter("canvas"),
}))
recorder := performGeneratedRouteRequest(
t,
mux,
http.MethodGet,
"/v1/workspaces/ws-1/apps/canvas/agent-providers/status",
nil,
)
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, want %d; body: %s", recorder.Code, http.StatusOK, recorder.Body.String())
}
if !reflect.DeepEqual(capturedProviders, []string{"codex", "hermes", "opencode"}) {
t.Fatalf("providers = %#v, want [codex hermes opencode]", capturedProviders)
}
var response tuttigenerated.AgentProviderStatusListResponse
decodeGeneratedRouteResponse(t, recorder, &response)
gotProviders := make([]string, 0, len(response.Providers))
for _, provider := range response.Providers {
gotProviders = append(gotProviders, string(provider.Provider))
}
if !reflect.DeepEqual(gotProviders, []string{"codex", "hermes", "opencode"}) {
t.Fatalf("response providers = %#v, want [codex hermes opencode]", gotProviders)
}
}
func TestDaemonAPIRoutesWorkspaceAppAgentProviderStatusesNarrowExplicitProvidersToAgentTargets(t *testing.T) {
t.Parallel()
var capturedProviders []string
mux := http.NewServeMux()
RegisterRoutes(mux, NewRoutes(DaemonAPI{
AgentStatusService: stubAgentStatusService{
listFn: func(_ context.Context, input agentstatusservice.ListInput) (agentstatusservice.Snapshot, error) {
capturedProviders = append([]string(nil), input.Providers...)
return agentstatusservice.Snapshot{
Providers: []agentstatusservice.ProviderStatus{{Provider: "codex"}},
}, nil
},
},
AgentTargetService: stubAgentTargetService{
listFn: func(context.Context) ([]agenttargetbiz.Target, error) {
return []agenttargetbiz.Target{
{
ID: agenttargetbiz.IDLocalCodex,
Provider: "codex",
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("codex"),
Name: "Codex",
Enabled: true,
Source: agenttargetbiz.SourceSystem,
},
}, nil
},
},
AppCenterService: installedWorkspaceAppCenter("canvas"),
}))
recorder := performGeneratedRouteRequest(
t,
mux,
http.MethodGet,
"/v1/workspaces/ws-1/apps/canvas/agent-providers/status?providers=codex&providers=hermes",
nil,
)
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, want %d; body: %s", recorder.Code, http.StatusOK, recorder.Body.String())
}
if !reflect.DeepEqual(capturedProviders, []string{"codex"}) {
t.Fatalf("providers = %#v, want [codex]", capturedProviders)
}
}
func TestDaemonAPIRoutesWorkspaceAppComposerOptionsBindPathWorkspace(t *testing.T) {
t.Parallel()
mux := http.NewServeMux()
RegisterRoutes(mux, NewRoutes(DaemonAPI{
AgentSessionService: stubAgentSessionService{
composerOptionsFn: func(_ context.Context, input agentservice.ComposerOptionsInput) (agentservice.ComposerOptions, error) {
if input.WorkspaceID != "ws-1" {
t.Fatalf("workspaceID = %q, want ws-1", input.WorkspaceID)
}
return agentservice.ComposerOptions{Provider: input.Provider}, nil
},
},
AgentTargetService: stubAgentTargetService{
listFn: func(context.Context) ([]agenttargetbiz.Target, error) {
return []agenttargetbiz.Target{{
ID: agenttargetbiz.IDLocalCodex,
Provider: "codex",
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("codex"),
Name: "Codex",
Enabled: true,
Source: agenttargetbiz.SourceSystem,
}}, nil
},
},
AppCenterService: installedWorkspaceAppCenter("canvas"),
}))
recorder := performGeneratedRouteRequest(
t,
mux,
http.MethodPost,
"/v1/workspaces/ws-1/apps/canvas/agent-providers/codex/composer-options",
map[string]any{"workspaceId": "ws-2"},
)
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, want %d; body: %s", recorder.Code, http.StatusOK, recorder.Body.String())
}
}
func TestDaemonAPIRoutesWorkspaceAppComposerOptionsRejectHiddenProvider(t *testing.T) {
t.Parallel()
composerOptionsCalled := false
mux := http.NewServeMux()
RegisterRoutes(mux, NewRoutes(DaemonAPI{
AgentSessionService: stubAgentSessionService{
composerOptionsFn: func(_ context.Context, input agentservice.ComposerOptionsInput) (agentservice.ComposerOptions, error) {
composerOptionsCalled = true
return agentservice.ComposerOptions{Provider: input.Provider}, nil
},
},
AgentTargetService: stubAgentTargetService{
listFn: func(context.Context) ([]agenttargetbiz.Target, error) {
return []agenttargetbiz.Target{{
ID: agenttargetbiz.IDLocalCodex,
Provider: "codex",
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("codex"),
Name: "Codex",
Enabled: true,
Source: agenttargetbiz.SourceSystem,
}}, nil
},
},
AppCenterService: installedWorkspaceAppCenter("canvas"),
}))
recorder := performGeneratedRouteRequest(
t,
mux,
http.MethodPost,
"/v1/workspaces/ws-1/apps/canvas/agent-providers/opencode/composer-options",
nil,
)
if recorder.Code != http.StatusBadRequest {
t.Fatalf("status = %d, want %d; body: %s", recorder.Code, http.StatusBadRequest, recorder.Body.String())
}
if composerOptionsCalled {
t.Fatal("composer options service called for hidden provider")
}
}
func installedWorkspaceAppCenter(appID string) stubWorkspaceAppCenterService {
return stubWorkspaceAppCenterService{
listFn: func(_ context.Context, _ string) ([]workspacebiz.WorkspaceApp, error) {
return []workspacebiz.WorkspaceApp{workspaceAppForRouteTest(appID, workspacebiz.AppRuntimeStatusIdle)}, nil
},
}
}