MCP v2 - Test Case Design
This page maps the I/O Definition to tests. A target contract clause without a test case is treated as an implementation gap.
Test IDs use MCPV2-<layer>-<NN>.
| Layer | Scope | Tooling |
|---|---|---|
Unit (U) |
schema validation, key parsing, scrypt verification, scope checks, backend request mapping, response mapping | Vitest, no network |
Handler (C) |
MCP tool handlers with mocked PostgreSQL auth and mocked backend internal API | Vitest with vi.mock |
E2E (E) |
deployed dev smoke path through CloudFront/API Gateway, MCP v2, PostgreSQL auth, backend internal API, SQS, guinness-ai-v2, S3 artifact, backend webhook, and DocumentDB design/code reads | manual or CI smoke |
flowchart LR
U["Unit tests<br/>schemas/auth/mappers"] --> C["Handler tests<br/>MCP + mocked backend"]
C --> E["E2E smoke<br/>MCP -> backend -> AI"]
E --> Result["verified project-scoped<br/>design/code/des2code flow"]
Coverage Matrix
| Contract area | Happy path | Failure path | Idempotency |
|---|---|---|---|
| CloudFront token auth | MCPV2-U-01 | MCPV2-U-02 | - |
| PostgreSQL API-key auth | MCPV2-U-03 | MCPV2-U-04, MCPV2-U-05, MCPV2-U-06 | - |
| project/user scope | MCPV2-U-07 | MCPV2-U-08 | - |
| tool input schemas | MCPV2-U-09 | MCPV2-U-10 | - |
| backend internal API delegation | MCPV2-U-11, MCPV2-C-01, MCPV2-C-03, MCPV2-C-05 | MCPV2-C-02, MCPV2-C-04, MCPV2-C-06, MCPV2-C-08 | MCPV2-C-09 |
| backend producer payloads | MCPV2-U-12 | MCPV2-U-13 | - |
| backend downstream SQS / AI-v2 | MCPV2-E-02 | MCPV2-E-04 | MCPV2-E-03 |
| per-request MCP server | MCPV2-C-09 | - | MCPV2-C-09 |
last_used_at update |
MCPV2-C-10 | MCPV2-C-11 | - |
| deployed integration | MCPV2-E-01, MCPV2-E-02 | MCPV2-E-04 | MCPV2-E-03 |
Unit Tests
MCPV2-U-01 - Valid CloudFront token passes
- Given
X-MCP-TokenequalsCLOUDFRONT_SECRET_HEADER. - When edge-token validation runs.
- Then validation passes.
MCPV2-U-02 - Invalid CloudFront token is rejected
- Given
X-MCP-Tokenis missing or mismatched outsideENVIRONMENT=local. - When edge-token validation runs.
- Then the request is rejected with HTTP 401.
MCPV2-U-03 - Valid PostgreSQL API key passes
- Given PostgreSQL
mcp_api_keysreturns an active row with knownkey_hashandsalt. - When
guinness_<prefix>_<secret>is parsed and verified. - Then auth context includes
id,user_id,project_id,permission, andkey_prefix.
MCPV2-U-04 - Unknown key prefix fails
- Given no PostgreSQL row matches the parsed prefix.
- Then authentication fails and hash verification is not attempted.
MCPV2-U-05 - Revoked/expired/deleted keys fail
- Parameterize
revoked_at, pastexpires_at, anddeleted_at. - Then authentication fails before tool execution.
MCPV2-U-06 - MySQL model import is absent
- Given the migrated implementation.
- Then
apps/mcp-v2does not import@guinness-backend/models/mysqlormysql2.
MCPV2-U-07 - Authorized project scope passes
- Given auth context is scoped to
project_id = 42. - When a tool is called with
project_id = 42. - Then scope validation passes.
MCPV2-U-08 - Cross-project scope fails before backend I/O
- Given auth context is scoped to
project_id = 42. - When a tool is called with
project_id = 43. - Then the response is
isError: true. - And no backend internal API call is made.
MCPV2-U-09 - Tool schemas accept valid input
- Cover
trigger-des2code,get-des2code,list-designs,list-code,get-design-detail, andget-code-detail. - Then defaults are applied for
limit = 20andoffset = 0.
MCPV2-U-10 - Tool schemas reject invalid input
- Parameterize empty IDs, IDs over 255 characters, invalid ID characters,
project_id <= 0,organization_id <= 0,limit > 100, andoffset < 0. - Then field-level validation errors are returned.
MCPV2-U-11 - Backend internal request mapping is correct
- Given valid tool arguments and an authenticated project scope.
- Then MCP v2 builds the expected backend internal route, method, query/body,
X-API-Key, andX-MCP-Project-ID. - And MCP v2 does not import or call SQS, DocumentDB, or AI-v2 clients directly.
MCPV2-U-12 - Backend producer payloads share MCP v2 IDs
- Given backend design/code/des2code API request data.
- When producer payloads are built for
design-import,code-import, anddes2code. - Then
design_id,code_id,project_id, andorganization_idmatch the PostgreSQL rows used for access control.
MCPV2-U-13 - Design producer omits figma_url
- Given a design-create request whose Figma URL has already been parsed by the backend.
- Then the
design-importpayload includesorganization_id,project_id,file_id,node_id, anddesign_id. - And the payload does not include
figma_url.
Handler Tests
MCPV2-C-01 - Trigger tool delegates to backend
- Given valid auth and valid trigger input.
- When
trigger-des2codeexecutes. - Then MCP calls
POST /internal/des2codeonBACKEND_INTERNAL_URL. - And MCP response has
structuredContent.success = true.
MCPV2-C-02 - Backend trigger failure returns MCP error
- Given backend internal
POST /internal/des2codereturns 5xx or a validation error. - Then MCP response has
isError: true. - And the error text includes the mapped backend message.
MCPV2-C-03 - Get des2code maps backend success
- Given backend internal API returns a des2code summary.
- Then MCP response contains
matched_code_count,matched_codes,artifact, andprocessed_at.
MCPV2-C-04 - Get des2code maps not found
- Given backend internal API returns a not-found response.
- Then MCP response has
isError: trueand no successful result payload.
MCPV2-C-05 - List designs/code maps pagination
- Given backend internal API returns
total_count,returned_count,limit,offset, and source items. - Then MCP structured content preserves the pagination fields.
MCPV2-C-06 - List limit over 100 fails before backend HTTP
- Given
limit = 101. - Then validation fails and backend internal API is not called.
MCPV2-C-07 - Detail tools return source details without embeddings
- Given backend internal API returns a design or code source detail.
- Then MCP response does not include
visual.vector_embedding,semantics.vector_embedding, orstructural.vector_embedding.
MCPV2-C-08 - Backend internal API unreachable maps to service error
- Given backend internal API times out or returns 5xx.
- Then MCP response has
isError: truewith service-unavailable text.
MCPV2-C-09 - Per-request server isolation
- Given two concurrent JSON-RPC requests.
- When both requests execute.
- Then each creates a fresh MCP server and transport.
- And response IDs/content do not leak between requests.
MCPV2-C-10 - last_used_at update succeeds asynchronously
- Given valid authentication.
- Then
last_used_atupdate is scheduled after successful verification.
MCPV2-C-11 - last_used_at update failure is non-blocking
- Given auth succeeds but the update throws.
- Then tool execution still continues and the failure is logged.
E2E Smoke Tests
MCPV2-E-01 - Deployed tool list
- Given dev CloudFront/API Gateway endpoint and a valid PostgreSQL-backed MCP API key.
- When
tools/listis called. - Then all six MCP v2 tools are returned.
MCPV2-E-02 - Trigger to backend, SQS, des2code, and webhook
- Given imported design and code sources for the same organization/project.
- When
trigger-des2codeis called. - Then MCP v2 calls backend internal
POST /internal/des2code. - And backend sends an SQS message to
guinness-ai-v2/apps/des2code. - And
guinness-ai-v2/apps/des2codewrites a timestamped S3 result artifact. - And
guinness-ai-v2/apps/des2codepostsPOST /v1/webhooks/ai-statuswith artifact metadata. - And backend persists the latest
des2coderesult/status and artifact reference in PostgreSQL.
MCPV2-E-03 - Re-trigger replaces latest result
- Given a design already has a PostgreSQL-backed
des2coderesult and artifact reference. - When the same design is triggered again.
- Then the latest result and artifact reference are replaced for that
design_id. - And the MCP read tool returns the latest result through backend internal API.
MCPV2-E-04 - Cross-project access is blocked
- Given an MCP API key scoped to project A.
- When a tool is called for project B.
- Then the call fails before backend internal API, SQS, or AI-v2 read I/O.