Files
agentic-coding-workflow/internal/mcp/tools_orchestrator_test.go
T
2026-06-22 08:55:57 +08:00

109 lines
3.1 KiB
Go

package mcp
import (
"context"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// fakeOrchBridge implements OrchestratorBridge.
type fakeOrchBridge struct {
lastParent uuid.UUID
lastPhase string
lastPrompt string
stepID string
err error
}
func (f *fakeOrchBridge) RequestSubtask(_ context.Context, parentACPSessionID uuid.UUID, phase, prompt string, _ *uuid.UUID) (string, error) {
if f.err != nil {
return "", f.err
}
f.lastParent = parentACPSessionID
f.lastPhase = phase
f.lastPrompt = prompt
if f.stepID == "" {
f.stepID = uuid.NewString()
}
return f.stepID, nil
}
func orchTestDeps() (ServerDeps, *fakeOrchBridge) {
deps := testDeps()
bridge := &fakeOrchBridge{}
deps.Orchestrator = bridge
return deps, bridge
}
// ctxWithSystemToken 构造一个 system token 上下文(绑定 acp session)。
func ctxWithSystemToken(sessionID uuid.UUID) context.Context {
return context.WithValue(context.Background(), AuthContextKey, &AuthSession{
UserID: testUID.String(),
TokenID: uuid.NewString(),
Issuer: IssuerSystem,
ACPSessionID: &sessionID,
})
}
func TestRequestSubtask_SystemTokenHappyPath(t *testing.T) {
deps, bridge := orchTestDeps()
sessionID := uuid.New()
result, err := callTool(ctxWithSystemToken(sessionID), deps, "request_subtask", map[string]any{
"phase": "implementing",
"prompt": "do the subtask",
})
require.NoError(t, err)
require.False(t, result.IsError, "expected success; got %+v", result)
assert.Equal(t, sessionID, bridge.lastParent)
assert.Equal(t, "implementing", bridge.lastPhase)
assert.Equal(t, "do the subtask", bridge.lastPrompt)
}
func TestRequestSubtask_RejectsAdminToken(t *testing.T) {
deps, bridge := orchTestDeps()
// admin token(非 system)→ 拒绝(request_subtask 只允许 in-session agent)。
ctx := context.WithValue(context.Background(), AuthContextKey, &AuthSession{
UserID: testUID.String(),
TokenID: uuid.NewString(),
Issuer: IssuerAdmin,
})
result, err := callTool(ctx, deps, "request_subtask", map[string]any{
"phase": "implementing",
"prompt": "x",
})
require.NoError(t, err)
assert.True(t, result.IsError, "admin token must be rejected")
assert.Empty(t, bridge.lastPrompt)
}
func TestRequestSubtask_RejectsSystemTokenWithoutSession(t *testing.T) {
deps, _ := orchTestDeps()
// system token 但未绑定 acp session → 拒绝。
ctx := context.WithValue(context.Background(), AuthContextKey, &AuthSession{
UserID: testUID.String(),
TokenID: uuid.NewString(),
Issuer: IssuerSystem,
})
result, err := callTool(ctx, deps, "request_subtask", map[string]any{
"phase": "implementing",
"prompt": "x",
})
require.NoError(t, err)
assert.True(t, result.IsError, "system token without acp session must be rejected")
}
func TestRequestSubtask_RequiresPrompt(t *testing.T) {
deps, _ := orchTestDeps()
result, err := callTool(ctxWithSystemToken(uuid.New()), deps, "request_subtask", map[string]any{
"phase": "implementing",
})
require.NoError(t, err)
assert.True(t, result.IsError, "missing prompt must error")
}