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") }