Skip to content

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-Token equals CLOUDFRONT_SECRET_HEADER.
  • When edge-token validation runs.
  • Then validation passes.

MCPV2-U-02 - Invalid CloudFront token is rejected

  • Given X-MCP-Token is missing or mismatched outside ENVIRONMENT=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_keys returns an active row with known key_hash and salt.
  • When guinness_<prefix>_<secret> is parsed and verified.
  • Then auth context includes id, user_id, project_id, permission, and key_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, past expires_at, and deleted_at.
  • Then authentication fails before tool execution.

MCPV2-U-06 - MySQL model import is absent

  • Given the migrated implementation.
  • Then apps/mcp-v2 does not import @guinness-backend/models/mysql or mysql2.

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, and get-code-detail.
  • Then defaults are applied for limit = 20 and offset = 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, and offset < 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, and X-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, and des2code.
  • Then design_id, code_id, project_id, and organization_id match 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-import payload includes organization_id, project_id, file_id, node_id, and design_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-des2code executes.
  • Then MCP calls POST /internal/des2code on BACKEND_INTERNAL_URL.
  • And MCP response has structuredContent.success = true.

MCPV2-C-02 - Backend trigger failure returns MCP error

  • Given backend internal POST /internal/des2code returns 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, and processed_at.

MCPV2-C-04 - Get des2code maps not found

  • Given backend internal API returns a not-found response.
  • Then MCP response has isError: true and 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, or structural.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: true with 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_at update 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/list is 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-des2code is 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/des2code writes a timestamped S3 result artifact.
  • And guinness-ai-v2/apps/des2code posts POST /v1/webhooks/ai-status with artifact metadata.
  • And backend persists the latest des2code result/status and artifact reference in PostgreSQL.

MCPV2-E-03 - Re-trigger replaces latest result

  • Given a design already has a PostgreSQL-backed des2code result 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.