You've already forked agentic-coding-workflow
test(mcp): K5 — prompts + resources integration scenarios
- PromptsList_FromTemplates: system template visible via prompts/list + prompts/get
- ResourceRead_NotFound: non-existent pm://projects/{uuid} returns error
- ResourceList_ScopeFilter: in-scope project resource readable; resources listed
All 14 spec §8.2 integration scenarios now complete.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,7 @@ import (
|
||||
tcpg "github.com/testcontainers/testcontainers-go/modules/postgres"
|
||||
|
||||
"github.com/yan1h/agent-coding-workflow/internal/audit"
|
||||
"github.com/yan1h/agent-coding-workflow/internal/chat"
|
||||
"github.com/yan1h/agent-coding-workflow/internal/infra/db"
|
||||
"github.com/yan1h/agent-coding-workflow/internal/infra/logger"
|
||||
"github.com/yan1h/agent-coding-workflow/internal/mcp"
|
||||
@@ -908,17 +909,128 @@ func (s *mcpIntegrationSuite) seedCrashedSessionWithLiveToken(ctx context.Contex
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// K5 stubs
|
||||
// K5: Prompts + Resources
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func (s *mcpIntegrationSuite) testPromptsListFromTemplates(t *testing.T) {
|
||||
t.Skip("filled in K5")
|
||||
t.Parallel()
|
||||
|
||||
// Seed a system-scope template via chat.TemplateService
|
||||
chatRepo := chat.NewRepository(s.pool)
|
||||
tplSvc := chat.NewTemplateService(chatRepo, s.auditRec, nil)
|
||||
tpl, err := tplSvc.Create(s.ctx, s.adminID, "test-system-prompt", "You are a helpful assistant.", chat.TemplateScopeSystem)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, tpl)
|
||||
|
||||
// Build an in-memory MCP server with Templates registered
|
||||
callerResolver := mcp.NewCallerResolver(s.userSvc)
|
||||
projectRepo := project.NewPostgresRepository(s.pool)
|
||||
deps := mcp.ServerDeps{
|
||||
Caller: callerResolver,
|
||||
Projects: s.projectSvc,
|
||||
Reqs: project.NewRequirementService(projectRepo, mcp.AuditWrap(s.auditRec)),
|
||||
Issues: s.issueSvc,
|
||||
Templates: tplSvc,
|
||||
}
|
||||
srv := mcp.NewMCPServer(deps)
|
||||
require.NoError(t, mcp.RegisterSystemPrompts(srv, deps, s.adminID))
|
||||
|
||||
client := mcpsdk.NewClient(&mcpsdk.Implementation{Name: "k5-prompts", Version: "0.0.1"}, nil)
|
||||
t1, t2 := mcpsdk.NewInMemoryTransports()
|
||||
if _, err := srv.Connect(s.ctx, t1, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sess, err := client.Connect(s.ctx, t2, nil)
|
||||
require.NoError(t, err)
|
||||
defer sess.Close()
|
||||
|
||||
list, err := sess.ListPrompts(s.ctx, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
var found bool
|
||||
for _, p := range list.Prompts {
|
||||
if p.Name == "test-system-prompt" {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.True(t, found, "expected prompt %q in list", "test-system-prompt")
|
||||
|
||||
got, err := sess.GetPrompt(s.ctx, &mcpsdk.GetPromptParams{Name: "test-system-prompt"})
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, got.Messages)
|
||||
}
|
||||
|
||||
func (s *mcpIntegrationSuite) testResourceReadNotFound(t *testing.T) {
|
||||
t.Skip("filled in K5")
|
||||
t.Parallel()
|
||||
|
||||
// Resources are registered by NewMCPServer; use in-memory transport
|
||||
callerResolver := mcp.NewCallerResolver(s.userSvc)
|
||||
projectRepo := project.NewPostgresRepository(s.pool)
|
||||
deps := mcp.ServerDeps{
|
||||
Caller: callerResolver,
|
||||
Projects: s.projectSvc,
|
||||
Reqs: project.NewRequirementService(projectRepo, mcp.AuditWrap(s.auditRec)),
|
||||
Issues: s.issueSvc,
|
||||
}
|
||||
srv := mcp.NewMCPServer(deps)
|
||||
|
||||
client := mcpsdk.NewClient(&mcpsdk.Implementation{Name: "k5-resources", Version: "0.0.1"}, nil)
|
||||
t1, t2 := mcpsdk.NewInMemoryTransports()
|
||||
if _, err := srv.Connect(s.ctx, t1, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sess, err := client.Connect(s.ctx, t2, nil)
|
||||
require.NoError(t, err)
|
||||
defer sess.Close()
|
||||
|
||||
_, err = sess.ReadResource(s.ctx, &mcpsdk.ReadResourceParams{
|
||||
URI: "pm://projects/" + uuid.New().String(),
|
||||
})
|
||||
require.Error(t, err, "reading non-existent resource should error")
|
||||
msg := strings.ToLower(err.Error())
|
||||
assert.True(t,
|
||||
strings.Contains(msg, "not found") || strings.Contains(msg, "no such") || strings.Contains(msg, "404"),
|
||||
"expected not_found, got: %v", err)
|
||||
}
|
||||
|
||||
func (s *mcpIntegrationSuite) testResourceListScopeFilter(t *testing.T) {
|
||||
t.Skip("filled in K5")
|
||||
t.Parallel()
|
||||
|
||||
// Resources are statically registered. Scope filtering applies during READ.
|
||||
// Verify: list returns resources; reading in-scope project works.
|
||||
callerResolver := mcp.NewCallerResolver(s.userSvc)
|
||||
projectRepo := project.NewPostgresRepository(s.pool)
|
||||
deps := mcp.ServerDeps{
|
||||
Caller: callerResolver,
|
||||
Projects: s.projectSvc,
|
||||
Reqs: project.NewRequirementService(projectRepo, mcp.AuditWrap(s.auditRec)),
|
||||
Issues: s.issueSvc,
|
||||
}
|
||||
srv := mcp.NewMCPServer(deps)
|
||||
srv.AddReceivingMiddleware(func(next mcpsdk.MethodHandler) mcpsdk.MethodHandler {
|
||||
return func(ctx context.Context, method string, req mcpsdk.Request) (mcpsdk.Result, error) {
|
||||
ctx = context.WithValue(ctx, mcp.AuthContextKey, s.userSession())
|
||||
return next(ctx, method, req)
|
||||
}
|
||||
})
|
||||
|
||||
client := mcpsdk.NewClient(&mcpsdk.Implementation{Name: "k5-scope", Version: "0.0.1"}, nil)
|
||||
t1, t2 := mcpsdk.NewInMemoryTransports()
|
||||
if _, err := srv.Connect(s.ctx, t1, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sess, err := client.Connect(s.ctx, t2, nil)
|
||||
require.NoError(t, err)
|
||||
defer sess.Close()
|
||||
|
||||
list, err := sess.ListResources(s.ctx, nil)
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, list.Resources, "expected registered resources")
|
||||
|
||||
// Reading the in-scope project resource should work
|
||||
_, err = sess.ReadResource(s.ctx, &mcpsdk.ReadResourceParams{
|
||||
URI: "pm://projects/" + s.projectID.String(),
|
||||
})
|
||||
require.NoError(t, err, "in-scope project should be readable")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user