You've already forked agentic-coding-workflow
109 lines
3.1 KiB
Go
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")
|
|
}
|