You've already forked agentic-coding-workflow
bugfix
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
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")
|
||||
}
|
||||
Reference in New Issue
Block a user